⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 subprocessrefexpression.java

📁 一个工作流设计及定义的系统,可以直接与数据库结合进行系统工作流程的定义及应用.
💻 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 + -