
src.openwfe.org.engine.expressions.raw.RawExpression Maven / Gradle / Ivy
/*
* Copyright (c) 2001-2006, 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: RawExpression.java 2947 2006-07-17 08:04:50Z jmettraux $
*/
//
// RawExpression.java
//
// [email protected]
//
// generated with
// jtmpl 1.1.01 2004/05/19 ([email protected])
//
package openwfe.org.engine.expressions.raw;
import openwfe.org.Utils;
import openwfe.org.ReflectionUtils;
import openwfe.org.ApplicationContext;
import openwfe.org.engine.Definitions;
import openwfe.org.engine.expool.PoolException;
import openwfe.org.engine.workitem.InFlowWorkItem;
import openwfe.org.engine.expressions.BuildException;
import openwfe.org.engine.expressions.ApplyException;
import openwfe.org.engine.expressions.ReplyException;
import openwfe.org.engine.expressions.FlowExpression;
import openwfe.org.engine.expressions.FlowExpressionId;
import openwfe.org.engine.expressions.ProcessDefinition;
import openwfe.org.engine.expressions.OneChildExpression;
import openwfe.org.engine.expressions.ZeroChildExpression;
import openwfe.org.engine.expressions.CompositeFlowExpression;
import openwfe.org.engine.expressions.map.ExpressionMap;
/**
* A RawExpression wraps non-parsed XML fragments (branches) of the process
* definition.
*
* CVS Info :
*
$Author: jmettraux $
*
$Id: RawExpression.java 2947 2006-07-17 08:04:50Z jmettraux $
*
* @author [email protected]
*/
public abstract class RawExpression
extends ZeroChildExpression
{
private final static org.apache.log4j.Logger log = org.apache.log4j.Logger
.getLogger(RawExpression.class.getName());
//
// CONSTANTS & co
private static long lastGivenInstanceId = -1;
//
// FIELDS
/*
* This is used when parsing for droflo, when prepareChildren() is
* called, if this is set, then it is used for storing children.
*/
private transient ProcessDefinition processDefinition = null;
/*
* also for prepareChildren() : just keeping tracking of the
* expression being 'resolved'.
*/
private transient FlowExpression generatedExpression = null;
private int subId = 0;
//
// CONSTRUCTORS
//
// BEAN METHODS
public int getSubId () { return this.subId; }
public void setSubId (final int i) { this.subId = i; }
//
// ABSTRACT METHODS
/**
* Inits the new raw expression.
*/
public abstract void init
(ApplicationContext context,
FlowExpressionId environmentId,
FlowExpressionId parentId,
int expressionId,
Object raw)
throws
BuildException;
/**
* Inits the new raw expression.
*/
public abstract void init
(ApplicationContext context,
FlowExpressionId environmentId,
FlowExpressionId parentId,
FlowExpressionId id,
Object raw)
throws
BuildException;
/**
* Returns true if this raw expression is leading to a DefinitionExpression
*/
public abstract boolean isDefinition ();
/**
* Returns true if this raw expression is leading to a workflow defintion.
*/
public abstract boolean isWorkflowDefinition ();
/**
* If this raw expression points to a definition, will return the
* name under which the definition result should be bound.
*/
public abstract String getDefinitionName ();
/**
* Resolves the real expression hiding behind the raw expression.
*/
public abstract FlowExpression resolveExpression
(InFlowWorkItem currentWi)
throws
BuildException;
/**
* Resolves the real expression hiding behind the raw expression ;
* this version of the method is used by Droflo for flow visualization
* and edition.
*/
public abstract FlowExpression resolveExpression (ProcessDefinition def)
throws BuildException;
/**
* This is callback method : FlowExpression 'generatedExpression' calls it
* on its RawExpression 'generatingExpression', because this raw expression
* knows how to turn raw whatever into a bunch of children.
* Regular flow expressions do not care about how they and their children
* are generated, it's the raw expressions' job.
*/
public abstract java.util.List prepareChildren (InFlowWorkItem currentWi)
throws BuildException;
/* *
* Returns the class of the unevaluated expression lying behind this
* RawExpression instance.
* /
public abstract Class getExpressionClass ();
*
* now required at FlowExpression level.
*/
/**
* Returns the unparsed representation of the process expression, or
* a pointer to it as represented.
*/
public abstract Object getRaw ();
//
// METHODS
/**
* Returns a copy of the children list with only children that are
* instances of FlowExpressionId.
* This method is called by classical composite expressions but not
* by 'dirty' ones like PrintExpression that accept XML Text or CDATA
* fragments.
*/
public java.util.List cleanChildren (final java.util.List children)
{
final java.util.ArrayList result =
new java.util.ArrayList(children.size());
final java.util.Iterator it = children.iterator();
while (it.hasNext())
{
final Object o = it.next();
if (o instanceof FlowExpressionId) result.add(o);
}
return result;
}
protected synchronized String nextSubId ()
{
final String result = ""+this.subId;
this.subId++;
return result;
}
/**
* Determines a new expression id from the parent id and the
* given expressionId and expression name.
*/
protected FlowExpressionId determineId
(final FlowExpressionId parentId,
final String expressionName,
final int expressionId)
{
final FlowExpressionId newId = parentId.copy();
newId.setExpressionName(expressionName);
final String parentExpressionId = parentId.getExpressionId();
if (parentExpressionId == null)
newId.setExpressionId(""+expressionId);
else
newId.setExpressionId(parentExpressionId+"."+expressionId);
return newId;
}
/**
* Returns a flow expression id pointing to a clone of this raw expression,
* but the clone has a brand new workflow instance id.
*/
public synchronized RawExpression newInstance
(final FlowExpressionId parentId)
throws
PoolException
{
if (log.isDebugEnabled())
{
log.debug("newInstance()");
log.debug("newInstance() this.id "+this.getId());
log.debug("newInstance() parentId "+parentId);
}
final RawExpression clone = (RawExpression)this.clone();
String oldId = clone.getId().getWorkflowInstanceId();
String newWfid = null;
if (parentId != null)
{
final String oldRoot =
FlowExpressionId.extractParentWorkflowInstanceId(oldId);
final String parentRoot =
parentId.getParentWorkflowInstanceId();
//if (log.isDebugEnabled())
//{
// log.debug
// ("newInstance() oldRoot "+
// oldId);
// log.debug
// ("newInstance() parentRoot "+
// parentId.getWorkflowInstanceId());
//
// log.debug("newInstance() oldRoot "+oldRoot);
// log.debug("newInstance() parentRoot "+parentRoot);
//}
if ( ! oldRoot.equals(parentRoot))
newWfid = oldId;
}
else // parentId == null
{
if (oldId.indexOf(".") < 0 &&
clone.getId().getExpressionId().equals("0"))
{
newWfid = oldId;
}
}
if (newWfid == null)
newWfid = oldId + "." + nextSubId();
clone.getId().setWorkflowInstanceId(newWfid);
if (log.isDebugEnabled())
{
log.debug("newInstance() clone.wfid = "+newWfid);
log.debug("newInstance() clone.id = "+clone.getId());
log.debug("newInstance() clone.parent = "+clone.getParent());
}
getExpressionPool().add(clone);
this.storeItself();
//
// keeping track of the 'nextSubId'
return clone;
}
//
// METHODS from FlowExpression
/**
* You can pre-apply a RawExpression, ie resolving into its real
* expression.
*/
public FlowExpression preApply (final InFlowWorkItem wi)
throws ApplyException
{
try
{
final FlowExpression realExpression = resolveExpression(wi);
Definitions.getExpressionPool(context()).add(realExpression);
//
// overrides old (raw) version
//log.debug
// ("preApply() \n "+this.getId()+
// "\nresolved \n "+realExpression.getId());
//log.debug
// ("preApply() wfid is "+
// realExpression.getId().getWorkflowInstanceId());
return realExpression;
}
catch (final Throwable t)
{
throw new ApplyException("preApply failed", t);
}
}
/**
* Takes the raw XML element, turns it into a FlowExpression and
* applies it.
*/
public void apply (final InFlowWorkItem wi)
throws ApplyException
{
final FlowExpression realExpression = preApply(wi);
realExpression.apply(wi);
}
/**
* Takes the raw XML element, turns it into a FlowExpression and
* launches it.
*/
public void launch (final InFlowWorkItem wi)
throws ApplyException
{
final FlowExpression realExpression = preApply(wi);
realExpression.launch(wi);
}
/**
* This method is never applied, so its implementation is simply empty.
*/
public final void reply (final InFlowWorkItem wi)
throws ReplyException
{
// nada
}
//
// BEAN METHODS
public ProcessDefinition getProcessDefinition ()
{
return this.processDefinition;
}
public void setProcessDefinition (final ProcessDefinition def)
{
this.processDefinition = def;
}
public FlowExpression getGeneratedExpression ()
{
return this.generatedExpression;
}
public void setGeneratedExpression (final FlowExpression fe)
{
this.generatedExpression = fe;
}
//
// STATIC METHODS
/**
* A unique static method for fetching new instance ids
*/
public synchronized static String determineNewWorkflowInstanceId ()
{
long instanceId = System.currentTimeMillis();
while (instanceId <= lastGivenInstanceId) instanceId++;
lastGivenInstanceId = instanceId;
return ""+instanceId;
}
/**
* Returns an empty raw expression, ready for filling with a
* flow expression id and a raw version of a process segment (some XML).
*/
public static RawExpression getEmptyRawExpression
(final ApplicationContext context)
{
final ExpressionMap expMap = Definitions.getExpressionMap(context);
return (RawExpression)ReflectionUtils
.buildNewInstance(expMap.getRawExpressionClass().getName());
}
}