src.openwfe.org.engine.expressions.raw.XmlRawExpression 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: XmlRawExpression.java 2575 2006-05-08 11:52:39Z jmettraux $
*/
//
// XmlRawExpression.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.ApplicationContext;
import openwfe.org.xml.XmlUtils;
import openwfe.org.engine.Definitions;
import openwfe.org.engine.impl.launch.SimpleXmlLauncher;
import openwfe.org.engine.expool.PoolException;
import openwfe.org.engine.workitem.InFlowWorkItem;
import openwfe.org.engine.expressions.BuildException;
import openwfe.org.engine.expressions.FlowExpression;
import openwfe.org.engine.expressions.FlowExpressionId;
import openwfe.org.engine.expressions.DefineExpression;
import openwfe.org.engine.expressions.OneChildExpression;
import openwfe.org.engine.expressions.DefinitionExpression;
import openwfe.org.engine.expressions.ProcessDefinition;
import openwfe.org.engine.expressions.SubProcessRefExpression;
import openwfe.org.engine.expressions.CompositeFlowExpression;
/**
* A RawExpression wraps non-parsed XML fragments (branches) of the process
* definition.
*
* CVS Info :
*
$Author: jmettraux $
*
$Id: XmlRawExpression.java 2575 2006-05-08 11:52:39Z jmettraux $
*
* @author [email protected]
*/
public class XmlRawExpression
extends RawExpression
{
private final static org.apache.log4j.Logger log = org.apache.log4j.Logger
.getLogger(XmlRawExpression.class.getName());
//
// CONSTANTS & co
private final static String A_NAME = "name";
private final static String A_REVISION = "revision";
private final static String E_DESCRIPTION = "description";
private final static String E_INCLUDE = "include";
private final static String A_URL = "url";
//
// FIELDS
private org.jdom.Element xmlBranch = null;
//
// CONSTRUCTORS
/**
* Inits the new raw expression.
*/
public void init
(final ApplicationContext context,
final FlowExpressionId environmentId,
final FlowExpressionId parentId,
final int expressionId,
final Object raw)
throws
BuildException
{
this.setApplicationContext(context);
if (parentId.getExpressionName() != null)
this.setParent(parentId);
this.xmlBranch = (org.jdom.Element)raw;
this.xmlBranch.detach();
//log.debug("init() xmlBranch is <"+this.xmlBranch.getName()+">");
this.setId
(determineId
(parentId, this.xmlBranch.getName(), expressionId));
this.setEnvironmentId(environmentId);
log.debug("init() 0 set id to "+this.getId());
log.debug("init() 0 set parent to "+this.getParent());
log.debug("init() 0 set env id to "+this.getEnvironmentId());
}
/**
* Inits the new raw expression.
*/
public void init
(final ApplicationContext context,
final FlowExpressionId environmentId,
final FlowExpressionId parentId,
final FlowExpressionId id,
final Object raw)
throws
BuildException
{
this.setApplicationContext(context);
this.setEnvironmentId(environmentId);
this.setParent(parentId);
this.setId(id);
this.xmlBranch = (org.jdom.Element)raw;
this.xmlBranch.detach();
log.debug("init() 1 set id to "+this.getId());
log.debug("init() 1 set parent to "+this.getParent());
log.debug("init() 1 set env id to "+this.getEnvironmentId());
//openwfe.org.Utils.logStackTrace(log, "init() 1");
}
/*
* debug stuff
*
public void setParent (final FlowExpressionId fei)
{
log.debug("setParent() "+this+" to "+fei+" for "+this.getId());
//openwfe.org.Utils.logStackTrace(log, "setParent()");
super.setParent(fei);
}
*/
//
// METHODS from RawExpression
/**
* Returns true if this raw expression points to an expression that is
* an implementation of DefinitionExpression (and thus deserves a special
* treatment).
*/
public boolean isDefinition ()
{
final Class c = getExpressionClass();
//log.debug("isDefinition() branch is <"+this.xmlBranch.getName()+">");
if (c == null)
{
log.warn
("isDefinition() did not found expression named '"+
this.xmlBranch.getName());
return false;
}
return DefinitionExpression.class.isAssignableFrom(c);
}
/**
* Returns true if this raw expression is leading to a workflow defintion.
*/
public boolean isWorkflowDefinition ()
{
return
((this.getDefinitionName() != null) &&
(this.xmlBranch.getAttributeValue(A_REVISION) != null));
}
/**
* Well, returns the value of the 'name' attribute of the underlying
* xmlBranch field.
*/
public String getDefinitionName ()
{
return this.xmlBranch.getAttributeValue(A_NAME);
}
/**
* Returns the class of the unevaluated expression lying behind this
* RawExpression instance.
*/
public Class getExpressionClass ()
{
//log.debug("getExpressionClass()");
final String expressionName = this.xmlBranch.getName();
//log.debug("getExpressionClass() expName is '"+expressionName+"'");
return getExpressionMap().getClass(expressionName);
}
//
// BEAN METHODS
public org.jdom.Element getXmlBranch ()
{
return this.xmlBranch;
}
public void setXmlBranch (final org.jdom.Element e)
{
this.xmlBranch = e;
}
//
// METHODS from FlowExpression
/**
* The classical clone method.
*/
public Object clone ()
{
final XmlRawExpression clone = (XmlRawExpression)super.clone();
clone.setXmlBranch((org.jdom.Element)this.getXmlBranch().clone());
return clone;
}
//
// METHODS
/**
* Resolves the real expression hiding behind the raw expression.
*/
public FlowExpression resolveExpression
(final InFlowWorkItem currentWi)
throws
BuildException
{
return resolveExpression(currentWi, null);
}
/**
* Resolves the real expression hiding behind the raw expression.
*/
public FlowExpression resolveExpression (final ProcessDefinition def)
throws BuildException
{
return resolveExpression(null, def);
}
/* *
* Resolves the real expression hiding behind the raw expression.
* If the processDefinition param is null, expressions are stored
* in the expression pool instead.
*/
private FlowExpression resolveExpression
(final InFlowWorkItem currentWi,
final ProcessDefinition def)
throws
BuildException
{
//log.debug("resolveExpression() "+this.getId());
setProcessDefinition(def);
//
// preparation
final String expressionName = this.xmlBranch.getName();
log.debug("resolveExpression() expressionName >"+expressionName+"<");
// maybe this should be disabled somehow in certain
// distributed engines cases
//
Object oValue = null;
if (def == null) oValue = lookupVariable(expressionName);
Class expressionClass =
getExpressionMap().getClass(expressionName);
FlowExpression fe = null;
log.debug("resolveExpression() this.parent is "+getParent());
log.debug("resolveExpression() oValue is "+oValue);
//
// initting the stuff
if ((oValue != null && oValue instanceof FlowExpressionId) ||
(oValue != null && oValue instanceof RawExpression) ||
(def != null && expressionClass == null))
//
// pointing to a [subprocess] definition
{
log.debug("resolveExpression() 'subprocess' expression");
final java.util.Map feParams = new java.util.HashMap(1);
feParams.put(SubProcessRefExpression.A_REF, expressionName);
feParams.putAll(XmlUtils.fetchAttributes(this.xmlBranch));
// forget="true" and the like are being passed here...
fe = new SubProcessRefExpression();
final java.util.Map atParams =
getLauncher().fetchAttributes(fe, this.xmlBranch);
feParams.putAll(atParams);
setGeneratedExpression(fe);
//log.debug
// ("resolveExpression() initting sub"+
// "\n fe.id is "+getId()+
// "\n fe.parent is "+getParent());
fe.init
(context(),
getEnvironmentId(),
getParent(),
getId(),
this,
feParams,
currentWi);
}
else
{
if (oValue != null && oValue instanceof Class)
{
log.debug("resolveExpression() built-in expression");
expressionClass = (Class)oValue;
try
{
fe = (FlowExpression)expressionClass.newInstance();
}
catch (final Exception e)
{
throw new BuildException
("Failed to prepare built-in expression '"+
expressionName+"'",
e);
}
}
else
//
// regular case...
{
log.debug
("resolveExpression() built-in expression "+
"(not found through var lookup)");
fe = getExpressionMap().instantiateExpression(expressionName);
}
setGeneratedExpression(fe);
fe.init
(context(),
getEnvironmentId(),
getParent(),
getId(),
this,
this.xmlBranch,
currentWi);
log.debug
("resolveExpression() set parent\n"+
" for "+fe.getId()+"\n to "+getParent());
}
//
// build expression
//this.debugVariables("XmlRawExpression.resolveExpression()");
if (this.getAttributes().keySet()
.contains(DefineExpression.A_MAP_CHILDREN))
{
log.debug
("resolveExpression() map-children >"+
this.getAttributes().get(DefineExpression.A_MAP_CHILDREN)+"<");
fe.getAttributes().put
(DefineExpression.A_MAP_CHILDREN,
this.getAttributes().get(DefineExpression.A_MAP_CHILDREN));
}
log.debug("resolveExpression() init for fe "+fe.getId());
if (def == null)
{
try
{
getExpressionPool().add(fe);
}
catch (final PoolException pe)
{
log.debug
("Failed to add resolved expression to pool "+fe.getId(),
pe);
throw new BuildException
("Failed to add resolved expression to pool "+fe.getId());
}
}
else
{
log.debug
("resolveExpression() fe class is "+fe.getClass().getName());
def.add(fe);
}
//
// that's all folks !
return fe;
}
/*
* pc = prepare children
*/
private void pcInclude
(final org.jdom.Element elt,
final InFlowWorkItem currentWi,
final java.util.List preChildren)
{
String url = elt.getAttributeValue(A_URL);
if (url == null) return;
log.debug("pcInclude() url is >"+url+"<");
this.getAttributes().put(A_URL, url);
url = lookupAttribute(A_URL, currentWi);
log.debug("pcInclude() url' is >"+url+"<");
try
{
final org.jdom.Element iElt =
XmlUtils.extractXml(url, SimpleXmlLauncher.shouldValidate());
pcFirstPass(iElt, currentWi, preChildren);
}
catch (final Exception e)
{
log.warn
("Failed to include '"+url+"'. Skipped.", e);
}
}
/*
* pc = prepare children
*/
private void pcFirstPass
(final org.jdom.Element elt,
final InFlowWorkItem currentWi,
final java.util.List preChildren)
{
//
// grab and insert includes in this first pass
java.util.Iterator it = elt.getContent().iterator();
while (it.hasNext())
{
final org.jdom.Content cContent = (org.jdom.Content)it.next();
if (cContent instanceof org.jdom.Text)
{
preChildren.add(cContent);
continue;
}
if ( ! (cContent instanceof org.jdom.Element)) continue;
final org.jdom.Element cElt = (org.jdom.Element)cContent;
//log.debug
// ("resolveExpression() considering <"+elt.getName()+">");
if (cElt.getName().equals(E_DESCRIPTION))
{
continue;
}
if (cElt.getName().equals(E_INCLUDE))
{
pcInclude(cElt, currentWi, preChildren);
continue;
}
preChildren.add(cElt);
}
}
public java.util.List prepareChildren (final InFlowWorkItem currentWi)
throws BuildException
{
//
// build children
final java.util.List children =
new java.util.ArrayList(this.xmlBranch.getChildren().size());
final java.util.List preChildren =
new java.util.ArrayList(this.xmlBranch.getChildren().size());
//
// 1st pass
pcFirstPass(this.xmlBranch, currentWi, preChildren);
//
// 2nd pass
int i = 0;
final java.util.Iterator it = preChildren.iterator();
while (it.hasNext())
{
final org.jdom.Content content = (org.jdom.Content)it.next();
content.detach();
if (content instanceof org.jdom.Text)
{
children.add(((org.jdom.Text)content).getText());
continue;
}
final org.jdom.Element elt = (org.jdom.Element)content;
final XmlRawExpression child = new XmlRawExpression();
child.init(context(), getEnvironmentId(), getId(), i, elt);
i++;
if (getProcessDefinition() == null)
//
// not in droflo, store in pool
{
log.debug("prepareChildren() adding to pool : "+child.getId());
try
{
getExpressionPool().add(child);
}
catch (final PoolException pe)
{
throw new BuildException
("Failed to add child to pool "+child.getId(), pe);
}
}
else
//
// in droflo, store into ProcessDefinition instance
{
final FlowExpression resolvedChild =
child.resolveExpression(getProcessDefinition());
if (resolvedChild instanceof DefinitionExpression)
{
final String name =
(String)resolvedChild.getAttributes().get("name");
log.debug
("prepareChildren() DefinitionExpression named '"+
name+"'");
getGeneratedExpression().bindVariable
(name,
resolvedChild);
}
getProcessDefinition().add(resolvedChild);
}
children.add(child.getId());
}
//log.debug
// ("resolveExpression() children count : "+children.size());
return children;
}
/**
* This method is used by ExpressionPool.dump().
*/
public org.jdom.Element dump ()
{
final org.jdom.Element elt = super.dump();
final org.jdom.Element eRaw = new org.jdom.Element("raw");
final org.jdom.Element eBranch =
(org.jdom.Element)this.xmlBranch.clone();
eBranch.detach();
eRaw.addContent(eBranch);
elt.addContent(eRaw);
return elt;
}
//
// STATIC METHODS
/* *
* Returns, in order, the variable names under which the children
* have to be evaluated and bound.
* Returns null if there are no children to map.
* /
public static String[] parseChildrenToMap (final RawExpression re)
{
final XmlRawExpression xre = (XmlRawExpression)re;
final String s = xre.getXmlBranch().getAttributeValue(A_MAP_CHILDREN);
log.debug("parseChildrenToMap() s is >"+s+"< for "+xre.getId());
if (s == null) return null;
return s.split(",\\s*");
}
*/
}