📄 subprocessrefexpression.java
字号:
/* * Copyright (c) 2005, John Mettraux, OpenWFE.org * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * . Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * . Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * . Neither the name of the "OpenWFE" nor the names of its contributors may be * used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * $Id: SubProcessRefExpression.java,v 1.26 2005/05/17 16:40:23 jmettraux Exp $ *///// SubProcessRefExpression.java//// jmettraux@openwfe.org//// generated with // jtmpl 1.0.04 20.11.2001 John Mettraux (jmettraux@openwfe.org)//package openwfe.org.engine.expressions;import openwfe.org.Utils;import openwfe.org.OpenWfeException;import openwfe.org.ApplicationContext;import openwfe.org.time.Time;import openwfe.org.engine.Definitions;import openwfe.org.engine.expool.ExpressionPool;import openwfe.org.engine.launch.LaunchException;import openwfe.org.engine.listen.reply.OkReply;import openwfe.org.engine.history.History;import openwfe.org.engine.workitem.Attribute;import openwfe.org.engine.workitem.LaunchItem;import openwfe.org.engine.workitem.InFlowWorkItem;import openwfe.org.engine.workitem.StringAttribute;import openwfe.org.engine.workitem.StringMapAttribute;/** * A leaf (terminal) expression : a reference to a subProcess * * <p><font size=2>CVS Info : * <br>$Author: jmettraux $ * <br>$Date: 2005/05/17 16:40:23 $ * <br>$Id: SubProcessRefExpression.java,v 1.26 2005/05/17 16:40:23 jmettraux Exp $ </font> * * @author jmettraux@openwfe.org */public class SubProcessRefExpression extends ZeroChildExpression{ private final static org.apache.log4j.Logger log = org.apache.log4j.Logger .getLogger(SubProcessRefExpression.class.getName()); // // CONSTANTS /** * Instructs the expression to look for the subprocess name in the given * variable. */ public final static String A_VARIABLE_REF = "variable-ref"; /** * Instructs the expression to look for the subprocess name in the given * field of the applied workitem. */ public final static String A_FIELD_REF = "field-ref"; /** * The name of the subprocess to launch is given directly as a ref. * It may also be possible that this ref contains a dollar notation * syntax referencing a variable or a field like in "${target}" or * "${field:target}" or even "${field:target_prefix}_${index}".<br> * See the 'dollar notation' in the documentation. */ public final static String A_REF = "ref"; /** * When the attribute 'forget' of this expression is set to 'true' (or * 'yes'), then the flow initiating the subprocess won't block until * it finishes, it won't wait on it. */ public final static String A_FORGET = "forget"; /** * When the attribute 'fields' is present, the workitem in use in the * new subprocess instance will be empty except for the fields named as * value of this attribute. * If this attribute has an empty value, the workitem will have no fields * at all. * If this attribute is not present, the workitem will be a copy of the * workitem in use in the parent flow. */ public final static String A_FIELDS = "fields"; private final static String ENGINE_SEPARATOR = "::"; // // FIELDS // // CONSTRUCTORS // // BEAN METHODS // // METHODS private void addFieldsFromRegex (final String regex, final InFlowWorkItem parentWi, final InFlowWorkItem newWi) { final java.util.Iterator it = parentWi.getAttributes().keyNamesMatching(regex).iterator(); while (it.hasNext()) { final String fieldName = ((String)it.next()).trim(); log.debug("prepareFields() adding field '"+fieldName+"'"); final Attribute a = parentWi.getAttribute(fieldName); newWi.getAttributes().put(new StringAttribute(fieldName), a); } } private void addFieldWithValue (final String assignation, //final InFlowWorkItem parentWi, final InFlowWorkItem newWi) { final String[] ss = assignation.split(" *= *"); final String fieldName = ss[0].trim(); final String value = ss[1].trim(); log.debug("addFieldWithValue() newWi['"+fieldName+"'] = '"+value+"'"); newWi.getAttributes().put (new StringAttribute(fieldName), new StringAttribute(value)); } private void addFieldAlias (final String aliasing, final InFlowWorkItem parentWi, final InFlowWorkItem newWi) { final String[] ss = aliasing.split(" *as *"); final String newFieldName = ss[0].trim(); final String parentFieldName = ss[1].trim(); final Attribute parentValue = parentWi.getAttribute(parentFieldName); if (parentValue != null) { newWi.getAttributes() .put(new StringAttribute(newFieldName), parentValue); } } private InFlowWorkItem prepareSubWorkitem (final InFlowWorkItem parentWi) { final String sFields = lookupAttribute(A_FIELDS, parentWi); final InFlowWorkItem newWi = (InFlowWorkItem)parentWi.clone(); if (sFields == null) return newWi; newWi.setAttributes(new StringMapAttribute()); String[] fields = sFields.split(", *"); for (int i=0; i<fields.length; i++) { log.debug("prepareFields() considering '"+fields[i]+"'..."); if (fields[i].indexOf("=") > -1) addFieldWithValue(fields[i], newWi); else if (fields[i].indexOf(" as ") > -1) addFieldAlias(fields[i], parentWi, newWi); else addFieldsFromRegex(fields[i], parentWi, newWi); } return newWi; } /* * wi.field > var > wfd */ private boolean shouldForget (final InFlowWorkItem wi) { // may be dangerous ??!! if (Utils.toBoolean(wi.getAttribute(A_FORGET))) return true; if (Utils.toBoolean(lookupVariable(A_FORGET))) return true; if (Utils.toBoolean(lookupAttribute(A_FORGET, wi))) return true; return false; } /** * either launches a subProcess, either launches an external process */ public void apply (final InFlowWorkItem wi) throws ApplyException { tag(wi); // it takes a hell lot of importance if the flow is continued // directly. log.debug("apply() tagged wi to "+wi.getLastExpressionId()); final boolean shouldForget = shouldForget(wi); // // preparation FlowExpressionId parentId = this.getId(); if (shouldForget) parentId = null; String ref = determineReference(wi); ref = checkIfLocalEngine(ref); final InFlowWorkItem launchWi = prepareSubWorkitem(wi); // // history logging historyLog (wi, History.EVT_FLOW_START, null, "launching ref=\""+ref+"\""); // // launching if (isUrl(ref)) // // launch subProcess { try { getLauncher().launch(launchWi, parentId, ref); } catch (final LaunchException le) { throw new ApplyException ("Subflow launch failure "+ref, le); } } else // // launch inner subProcess { final Object oValue = lookupVariable(ref); if ( ! (oValue instanceof FlowExpressionId)) { throw new ApplyException ("Ref '"+ref+"' doesn't point to a subprocess."); } final FlowExpressionId expId = (FlowExpressionId)oValue; log.debug("apply() inner subprocess at "+expId); try { //final FlowExpressionId subRootId = getLauncher().launchSub ((InFlowWorkItem)wi.clone(), parentId, expId); //log.debug("apply() subRoot is "+subRootId); } catch (final LaunchException le) { throw new ApplyException ("Failed to launch inner subprocess '"+ref+"'", le); } } if (shouldForget) // // don't wait for a reply of the subprocess // continueCurrentFlowDirectly(wi); } /* * Checks whether a ref is a URL or not (it may also comprise * a 'engineId::' prefix). */ private boolean isUrl (final String ref) throws ApplyException { if (ref == null || ref.length() < 1) { throw new ApplyException ("Cannot launch null or \"\" flow url"); } if (Utils.isUrl(ref)) return true; final int i = ref.indexOf("::"); if (i > -1) { if (i+2 == ref.length()) return false; // avoiding 'out of index'... return Utils.isUrl(ref.substring(i+2)); } return false; } // // METHODS overridden from FlowExpression /** * this method is overriden to allow later resolution of the referenced * subProcess (ie linking of the expression to the references subProcess). */ public void setAttributes (java.util.Map m) { super.setAttributes(m); } // // METHODS /* * This method will remove any 'engine::' prefix if engine is * the id of the local engine * (thus the launch will be internal) * * (should help fix bug #928820) */ private String checkIfLocalEngine (final String reference) { if (reference.indexOf(ENGINE_SEPARATOR) < 0) return reference; final String localEngineId = context().getApplicationName(); if (localEngineId == null) { log.warn ("application param '"+Definitions.ENGINE_ID+ "' is missing, cannot determine engineId"); return reference; } String[] ss = reference.split("::"); if (ss[0].equals(localEngineId)) return ss[1]; return reference; } /** * Given expression attributes, workitem fields and this expression * variables, determines the ref, ie the subprocess name or url that * is supposed to be launched. */ protected String determineReference (final InFlowWorkItem wi) throws ApplyException { final String varName = lookupAttribute(A_VARIABLE_REF, wi); if (varName != null) { String ref = (String)lookupVariable(varName); if (ref == null) { throw new ApplyException ("no variable set under name '"+varName+"'"); } return ref; } final String fieldName = lookupAttribute(A_FIELD_REF, wi); if (fieldName != null) { Attribute aRef = wi.getAttributes().get(fieldName); String ref = null; if (aRef != null) ref = aRef.toString(); if (ref == null) { throw new ApplyException ("workitem holds no field named '"+fieldName+"'"); } return ref; } final String ref = lookupAttribute(A_REF, wi); if (ref == null) { throw new ApplyException ("No 'variable-ref', 'field-ref' or 'ref' attribute in "+ "'subprocess' expression"); } return ref; } /** * When 'forget' is set to true, * this method allows to directly continue the current flow */ protected void continueCurrentFlowDirectly (final InFlowWorkItem wi) throws ApplyException { log.debug ("continueCurrentFlowDirectly() for "+wi.getLastExpressionId()); try { getExpressionPool().reply(wi.getLastExpressionId(), wi); } catch (final ReplyException re) { throw new ApplyException ("continueCurrentFlowDirectly() failed", re); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -