src.openwfe.org.engine.expressions.DefineExpression 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: DefineExpression.java 2575 2006-05-08 11:52:39Z jmettraux $
*/
//
// DefineExpression.java
//
// [email protected]
//
// generated with
// jtmpl 1.1.01 2004/05/19 ([email protected])
//
package openwfe.org.engine.expressions;
import openwfe.org.ApplicationContext;
import openwfe.org.engine.Definitions;
import openwfe.org.engine.expool.ExpressionPool;
import openwfe.org.engine.history.History;
import openwfe.org.engine.workitem.InFlowWorkItem;
import openwfe.org.engine.expressions.map.ExpressionMap;
import openwfe.org.engine.expressions.raw.RawExpression;
/**
* This expression may interpret 'workflow-definition', 'subprocess-definition'
* and above all 'define'
*
* CVS Info :
*
$Author: jmettraux $
*
$Id: DefineExpression.java 2575 2006-05-08 11:52:39Z jmettraux $
*
* @author [email protected]
*/
public class DefineExpression
extends CleanCompositeFlowExpression
implements DefinitionExpression
{
private final static org.apache.log4j.Logger log = org.apache.log4j.Logger
.getLogger(DefineExpression.class.getName());
//
// CONSTANTS & co
/**
* This attribute name 'map-children' is used to map the result
* of the evaluation of nested children to variable names.
*/
public final static String A_MAP_CHILDREN = "map-children";
//
// FIELDS
//
// CONSTRUCTORS
//
// METHODS
//
// BEAN METHODS
//
// METHODS from DefinitionExpression
/**
* This expression's implementation of eval() will yield a
* FlowExpressionId pointing to the body of the definition
*/
public Object eval (final InFlowWorkItem wi)
throws ApplyException
{
//
// find children to map
final String sChildrenToMap =
(String)this.getAttributes().get(A_MAP_CHILDREN);
//
// just get, not a lookup, variables substitution is done at
// subprocess call time (in SubProcessRefExpression).
log.debug("eval() sChildrenToMap >"+sChildrenToMap+"<");
//
// interpret all the definitions
RawExpression body = null;
final java.util.Iterator it = getChildren().iterator();
while (it.hasNext())
{
final FlowExpressionId fei = (FlowExpressionId)it.next();
final RawExpression exp =
(RawExpression)getExpressionPool().fetch(fei);
log.debug("eval() child is "+fei);
if ( ! exp.isDefinition())
{
if (body == null)
{
body = exp;
body.getAttributes().put(A_MAP_CHILDREN, sChildrenToMap);
}
continue;
}
//
// then it's a definition
try
{
define(exp, wi);
}
catch (final BuildException be)
{
throw new ApplyException
("Failed to bind definition", be);
}
}
//
// then apply the root (the body of the definition)
if (body == null)
throw new ApplyException("No body for definition "+getId());
//
// that's all folks
log.debug("eval() body is "+body.getId());
return body.getId();
}
private void define
(final RawExpression re, final InFlowWorkItem wi)
throws
BuildException, ApplyException
{
//
// determine name
final String name = re.getDefinitionName();
log.debug("define() name >"+name+"<");
Object oTemplate = null;
if (name != null &&
name.startsWith("//") &&
(DefineExpression.class.isAssignableFrom(re.getExpressionClass())))
//
// bind at engine level
{
oTemplate = re.clone();
}
else
//
// postulate : re points to a DefinitionExpression
{
final DefinitionExpression de =
(DefinitionExpression)re.resolveExpression(wi);
oTemplate = de.eval(wi);
}
if (name != null && oTemplate != null)
{
bindVariable(name, oTemplate);
}
else
{
log.warn
("define() "+
"missing name or ref for definition at "+this.getId());
}
getExpressionPool().removeExpression(re.getId());
//
// remove the DefineExpression instance,
// the template is the body expression instance.
}
//
// METHODS from FlowExpression
/**
* Interprets all definitions, THEN applies the body...
*/
public void apply (final InFlowWorkItem wi)
throws ApplyException
{
final FlowExpressionId fei = (FlowExpressionId)this.eval(wi);
this.setChildren(new java.util.ArrayList(1));
this.getChildren().add(fei);
//
// history logging
String message = "launching";
if (getParent() != null) message = "launching sub";
historyLog(wi, History.EVT_FLOW_START, null, message);
//
// history item
wi.addHistoryItem(getId(), this.getClass().getName(), message);
//
// launching
getExpressionPool().apply(fei, wi);
}
/**
* When the workflow is instantied, all expressions from root expression to
* all leaf expressions see their 'apply' method get called.
* When then leaf expressions (ParticipantExpressions) get answers from
* their participant, they communicate the modified workitem to their
* father expression with its 'reply' method.
*/
public void reply (final InFlowWorkItem wi)
throws ReplyException
{
//
// [history] log the end of the [sub]flow
historyLog(wi, History.EVT_FLOW_END, null, "replying");
//
// if there is a parent, reply to it
// environment removal is done in expool
if (getParent() != null)
replyToParent(wi);
else
getExpressionPool().removeExpression(this);
}
/**
* Inits the expression.
*/
public void init
(final ApplicationContext context,
final FlowExpressionId environmentId,
final FlowExpressionId parentId,
final FlowExpressionId id,
final RawExpression generatingExpression,
final Object raw,
final InFlowWorkItem currentWi)
throws
BuildException
{
super.init
(context,
environmentId,
parentId,
id,
generatingExpression,
raw,
currentWi);
if (getChildren() == null) return;
int bodyCount = 0;
final java.util.Iterator it = getChildren().iterator();
while (it.hasNext())
{
//final FlowExpressionId fei = (FlowExpressionId)it.next();
final Object child = it.next();
if ( ! (child instanceof FlowExpressionId)) continue;
final FlowExpressionId fei = (FlowExpressionId)child;
final Class childClass =
getExpressionMap().getClass(fei.getExpressionName());
if (childClass == null)
{
log.warn
("init() "+id.getExpressionName()+
" unknown expression '"+fei.getExpressionName()+"'");
continue;
}
if ( ! DefineExpression.class.isAssignableFrom(childClass))
bodyCount++;
if (bodyCount > 1)
{
log.warn
("init() "+id.getExpressionName()+
" with more than one body");
break;
}
}
}
//
// STATIC METHODS
}