src.openwfe.org.engine.expressions.ProcessDefinition Maven / Gradle / Ivy
/*
* 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: ProcessDefinition.java 2500 2006-04-16 17:45:17Z jmettraux $
*/
//
// ProcessDefinition.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.xml.XmlUtils;
import openwfe.org.engine.Definitions;
import openwfe.org.engine.workitem.InFlowWorkItem;
import openwfe.org.engine.expressions.raw.RawExpression;
/**
* This class is only used by droflo for flow edition.
*
* CVS Info :
*
$Author: jmettraux $
*
$Id: ProcessDefinition.java 2500 2006-04-16 17:45:17Z jmettraux $
*
* @author [email protected]
*/
public class ProcessDefinition
extends CleanCompositeFlowExpression
{
private final static org.apache.log4j.Logger log = org.apache.log4j.Logger
.getLogger(ProcessDefinition.class.getName());
//
// CONSTANTS & co
//
// FIELDS
private java.util.Map expressions = new java.util.HashMap(10);
private DefineExpression self = null;
//
// CONSTRUCTORS
public ProcessDefinition
(final ApplicationContext context,
final DefineExpression definition)
throws
BuildException
{
super();
log.debug("ProcessDefinition(1)");
setApplicationContext(context);
log.debug
("ProcessDefinition() definition : "+
definition.getClass().getName()+" "+
definition.getId());
this.setSelf(definition);
this.setId(definition.getId());
log.debug("ProcessDefinition() set ProcessDefinition id to "+getId());
}
public ProcessDefinition
(final ApplicationContext context,
final String wfdUrl,
final String wfdName,
final String wfdRevision)
throws
BuildException
{
super();
log.debug("ProcessDefinition(2)");
setApplicationContext(context);
final FlowExpressionId id = new FlowExpressionId();
id.setOwfeVersion(Definitions.OPENWFE_VERSION);
id.setWorkflowDefinitionUrl(wfdUrl);
id.setWorkflowDefinitionName(wfdName);
id.setWorkflowDefinitionRevision(wfdRevision);
setId(id);
//
// creating 'self'
final DefineExpression de = new DefineExpression();
final java.util.Map deParams = new java.util.HashMap();
deParams.put("name", wfdName);
deParams.put("revision", wfdRevision);
de.init(context(), null, null, getId(), null, deParams, null);
this.setSelf(de);
this.setId(de.getId());
log.debug("ProcessDefinition() set ProcessDefinition id to "+getId());
}
//
// BEAN METHODS
public java.util.Map getExpressions ()
{
return this.expressions;
}
/**
* 'self' is the DefineExpression at the root of the ProcessDefinition
* (usually a workflow-definition).
*/
public DefineExpression getSelf ()
{
return this.self;
}
public void setExpressions (final java.util.Map m)
{
this.expressions = m;
}
public void setSelf (final DefineExpression self)
{
this.self = self;
}
//
// METHODS from CompositeFlowExpression
/**
* Overrides the method as found in removeChild()
*/
public void removeChild (final FlowExpressionId fei)
{
log.debug("removeChild() from "+this.getId());
log.debug("removeChild() before : "+getExpressions().size());
log.debug("removeChild() before\n"+this.toString());
getChildren().remove(fei);
// is it really necessary ?
getExpressions().remove(fei);
log.debug("removeChild() after : "+getExpressions().size());
final java.util.Iterator it = getExpressions().values().iterator();
while (it.hasNext())
removeChildFromExpression(fei, (FlowExpression)it.next());
removeChildFromExpression(fei, this.self);
log.debug("removeChild() after \n"+this.toString());
}
private void removeChildFromExpression
(final FlowExpressionId childId, final FlowExpression fe)
{
if (fe == null)
{
log.debug("removeChildFromExpression() fe is null.");
return;
}
//
// not very happy with this 'if'...
if (fe instanceof CompositeFlowExpression)
{
log.debug("removeChildFromExpression() composite is "+fe.getId());
final CompositeFlowExpression cfe = (CompositeFlowExpression)fe;
log.debug
("removeChild() 0 composite.children : "+
cfe.getChildren().size());
cfe.getChildren().remove(childId);
log.debug
("removeChild() 1 composite.children : "+
cfe.getChildren().size());
}
else if (fe instanceof OneChildExpression)
{
final OneChildExpression oce = (OneChildExpression)fe;
if (oce.getChildExpressionId() != null &&
oce.getChildExpressionId().equals(childId))
{
oce.setChildExpressionId(null);
}
}
}
//
// METHODS
public FlowExpression get (final FlowExpressionId fei)
{
//log.debug("get() trying to get "+fei);
return (FlowExpression)getExpressions().get(fei);
}
public void add (final FlowExpression fe)
{
addChild(fe.getId());
getExpressions().put(fe.getId(), fe);
log.debug("add(1) put child "+fe.getId());
log.debug("add(1) after\n"+this.toString());
}
/**
* Adds a new expression as a child of the given 'parent', this method is
* a droflo edition method.
*/
public void add
(final String expressionName,
final FlowExpressionId parentId,
final int position)
throws
BuildException
{
//log.debug("add(2) adding '"+expressionName+"' to "+parentId);
FlowExpression parent = null;
if (parentId != null)
parent = (FlowExpression)getExpressions().get(parentId);
else
parent = getSelf();
log.debug("add(2) adding '"+expressionName+"' to "+parent.getId());
final FlowExpression fe = getExpressionMap()
.instantiateExpression(expressionName);
final FlowExpressionId id = parent.getId().copy();
final int c = newChildId(parent);
if (c < 0)
{
throw new BuildException
("Cannot add child to an expression of class "+
parent.getClass());
}
id.setExpressionName(expressionName);
id.setExpressionId(parent.getId().getExpressionId()+"."+c);
fe.setId(id);
fe.setParent(parentId);
// add child in this definition
getExpressions().put(fe.getId(), fe);
log.debug("add(2) put child "+fe.getId());
// add child to parent
addChild(parent, fe.getId(), position);
log.debug("add(2) after\n"+this.toString());
}
/*
* Adds a child to a parent expression
*/
private void addChild
(final FlowExpression parent,
final FlowExpressionId childId,
final int position)
{
if (parent instanceof CompositeFlowExpression)
{
((CompositeFlowExpression)parent).addChild(childId, position);
}
else if (parent instanceof OneChildExpression)
{
((OneChildExpression)parent).setChildExpressionId(childId);
}
}
/*
* Returns the last int id in the expression id, ie for "0.4.5" will
* return "5".
*/
private int getChildId (final FlowExpressionId fei)
{
int i = fei.getExpressionId().lastIndexOf(".");
if (i < 0) return Integer.parseInt(fei.getExpressionId());
return Integer.parseInt(fei.getExpressionId().substring(i+1));
}
/*
* Returns a new child id.
* Returns -1 if the expression cannot have children.
*/
private int newChildId (final FlowExpression fe)
{
if (fe instanceof CompositeFlowExpression)
{
final java.util.List children =
((CompositeFlowExpression)fe).getChildren();
if (children == null || children.size() < 1) return 0;
int result = 0;
final java.util.Iterator it = children.iterator();
while (it.hasNext())
{
int c = getChildId((FlowExpressionId)it.next());
if (c > result) result = c;
}
result++;
//log.debug("newChildId() returning "+result);
return result;
}
if (fe instanceof OneChildExpression)
{
final OneChildExpression oce = (OneChildExpression)fe;
if (oce.getChildExpressionId() == null) return 0;
return 1;
}
return -1;
}
public FlowExpression getRootExpression ()
{
final java.util.Iterator it = getExpressions().values().iterator();
while (it.hasNext())
{
final FlowExpression fe = (FlowExpression)it.next();
if ( ! (fe instanceof DefineExpression)) return fe;
}
return null;
}
public FlowExpression getExpression (final String expId)
{
log.debug("getExpression() expId >"+expId+"<");
final java.util.Iterator it = getExpressions().values().iterator();
while (it.hasNext())
{
final FlowExpression fe = (FlowExpression)it.next();
//log.debug
// ("getExpression() considering '"+
// fe.getId().getExpressionId()+"'");
if (expId.equals(fe.getId().getExpressionId()))
return fe;
}
return null;
}
public FlowExpressionId getFlowExpressionId (final String expId)
{
final FlowExpression fe = getExpression(expId);
if (fe == null) return null;
return fe.getId();
}
public void changeSubProcessDefinitionName
(final String defineExpId, final String newName)
{
final DefineExpression def =
(DefineExpression)getExpression(defineExpId);
def.getAttributes().put("name", newName);
}
public void createSubDefinition
(final String parentExpId,
final String subDefName)
{
DefineExpression def =
(DefineExpression)getExpression(parentExpId);
if (def == null) def = this.self;
final DefineExpression subDef = new DefineExpression();
final FlowExpressionId subId = def.getId().copy();
subId.setExpressionName
("subprocess-definition");
subId.setExpressionId
(subId.getExpressionId()+"."+def.getChildren().size());
subDef.setParent(def.getId());
subDef.setId(subId);
def.getChildren().add(subId);
this.add(subDef);
}
public void removeSubDefinition (final String defineExpId)
{
final DefineExpression def =
(DefineExpression)getExpression(defineExpId);
if (def == null)
{
log.warn
("removeSubDefinition() "+
"couldn't remove inexistent "+defineExpId);
return;
}
this.removeChild(def.getId());
}
/**
* Returns this process definition as an XML string
*/
public String outputAsXmlString ()
throws BuildException
{
return XmlUtils.toString(toXml(getSelf(), null, null));
}
/**
* Outputs as XML a subexpression child of this ProcessDefinition.
*/
public String toXmlString (final FlowExpression fe)
throws BuildException
{
return XmlUtils.toString(toXml(fe, null, null));
}
/**
* Replaces the branch corresponding to the given fei with some
* new XML branch.
* (This is used by Droflo's DefaultExpressionRenderer).
*/
public String doReplaceXml
(final FlowExpressionId fei, final String newXml)
throws
BuildException
{
return XmlUtils.toString(toXml(getSelf(), fei, newXml));
}
private org.jdom.Element toXml
(final FlowExpression fe,
final FlowExpressionId repId,
final String repXml)
throws
BuildException
{
if (fe == null)
log.debug("toXml() fe is null");
else
log.debug("toXml() fe.id is "+fe.getId());
if (fe == null) return null;
if (fe.getId().equals(repId))
{
log.debug("toXml() found branch to replace");
try
{
return XmlUtils.extractXmlElement(repXml);
}
catch (final Exception e)
{
log.debug
("toXml() failed to extract XML out of \n"+repXml, e);
throw new BuildException
("failed to extract XML out of \n"+repXml, e);
}
}
final String expName = getExpressionMap().getName(fe.getClass());
log.debug("toXml() expressionName >"+expName+"<");
final org.jdom.Element elt = new org.jdom.Element(expName);
XmlUtils.setAttributes(elt, fe.getAttributes());
if (fe instanceof CompositeFlowExpression)
{
final CompositeFlowExpression cfe = (CompositeFlowExpression)fe;
final java.util.Iterator it = cfe.getChildren().iterator();
while (it.hasNext())
{
final Object o = it.next();
//if (o == null) continue;
if ( ! (o instanceof FlowExpressionId))
{
elt.addContent(new org.jdom.Text(o.toString()));
}
else
{
final FlowExpressionId fei = (FlowExpressionId)o;
final org.jdom.Element eResult =
toXml(get(fei), repId, repXml);
if (eResult != null)
elt.addContent(eResult);
}
}
}
else if (fe instanceof OneChildExpression)
{
final OneChildExpression oce = (OneChildExpression)fe;
if (oce.getChildExpressionId() != null)
{
elt.addContent
(toXml(get(oce.getChildExpressionId()), repId, repXml));
}
}
return elt;
}
//
// METHODS from FlowExpression
/* *
* No implementation needed as a process definition is solely
* used for droflo purposes.
* /
public void release ()
{
// nothing to do, a process definition is never stored in an
// expression pool as it's just used by droflo for edtion and
// display
}
*/
/* *
* Nothing to do.
* /
public InFlowWorkItem cancel ()
throws ApplyException
{
return super.cancel();
}
*/
/**
* No implementation needed as a process definition is solely
* used for droflo purposes.
*/
public void apply (final InFlowWorkItem wi)
throws ApplyException
{
// nada
}
/**
* No implementation needed as a process definition is solely
* used for droflo purposes.
*/
public void reply (InFlowWorkItem wi)
throws ReplyException
{
// nada
}
/**
* Outputs the process definition and its content in a human
* readable format.
*/
public String toString ()
{
final StringBuffer sb = new StringBuffer();
sb.append(getClass().getName());
sb.append(" :\n");
sb.append(" - id : ");
sb.append(this.getId());
sb.append("\n");
sb.append(" children [\n");
java.util.Iterator it = getChildren().iterator();
while (it.hasNext())
{
final FlowExpressionId k = (FlowExpressionId)it.next();
sb.append(" - ");
sb.append(k);
sb.append("\n");
}
sb.append(" ]");
sb.append(" expression ids [\n");
it = getExpressions().keySet().iterator();
while (it.hasNext())
{
final FlowExpressionId k = (FlowExpressionId)it.next();
sb.append(" - ");
sb.append(k);
sb.append("\n");
}
sb.append(" ]");
return sb.toString();
}
/**
* This method awaits a ProcessDefinition or a DefineExpression as
* input, it then returns a list of the direct subDefinitions held
* by the input (or the input's root in the case of a ProcessDefinition).
*/
public java.util.List getSubDefinitions (final FlowExpression fe)
{
DefineExpression def = null;
if (fe instanceof DefineExpression)
{
def = (DefineExpression)fe;
}
else if (fe instanceof ProcessDefinition)
{
def = ((ProcessDefinition)fe).getSelf();
}
else
{
throw new IllegalArgumentException
("Illegal input : class "+fe.getClass().getName());
}
final java.util.List result =
new java.util.ArrayList(def.getChildren().size());
final java.util.Iterator it = def.getChildren().iterator();
while (it.hasNext())
{
final FlowExpressionId fei = (FlowExpressionId)it.next();
final FlowExpression fee = this.get(fei);
log.debug("getSubDefinitions() considering "+fee+" "+fei);
if (fee instanceof DefineExpression) result.add(fee);
}
return result;
}
public FlowExpression getBody (DefineExpression de)
{
log.debug("getBody() of "+de.getId());
final java.util.Iterator it = de.getChildren().iterator();
while (it.hasNext())
{
final FlowExpressionId fei = (FlowExpressionId)it.next();
final FlowExpression fe = this.get(fei);
log.debug("getBody() considering "+fei);
log.debug("getBody() is fe null ? "+(fe == null));
if (fe == null) continue;
if (fe instanceof DefinitionExpression) continue;
return fe;
}
log.debug("getBody() did not find anything, returning null.");
return null;
}
//
// STATIC METHODS
}