Index: modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/JmsActivity.java
===================================================================
--- modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/JmsActivity.java (revision 6436)
+++ modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/JmsActivity.java (working copy)
@@ -55,7 +55,6 @@
import org.jbpm.internal.log.Log;
import org.jbpm.pvm.internal.el.Expression;
import org.jbpm.pvm.internal.model.ExecutionImpl;
-import org.jbpm.pvm.internal.script.ScriptManager;
import org.jbpm.pvm.internal.wire.Descriptor;
import org.jbpm.pvm.internal.wire.WireContext;
import org.jbpm.pvm.internal.wire.descriptor.MapDescriptor;
Index: modules/jpdl/src/test/java/org/jbpm/jpdl/parsing/TaskParsingTest.java
===================================================================
--- modules/jpdl/src/test/java/org/jbpm/jpdl/parsing/TaskParsingTest.java (revision 6436)
+++ modules/jpdl/src/test/java/org/jbpm/jpdl/parsing/TaskParsingTest.java (working copy)
@@ -5,10 +5,12 @@
import org.jbpm.jpdl.internal.activity.TaskActivity;
import org.jbpm.pvm.internal.client.ClientProcessDefinition;
import org.jbpm.pvm.internal.el.Expression;
-import org.jbpm.pvm.internal.el.StaticTextExpression;
import org.jbpm.pvm.internal.model.ActivityImpl;
import org.jbpm.pvm.internal.task.TaskDefinitionImpl;
+/**
+ * @author Huisheng Xu
+ */
public class TaskParsingTest extends JpdlParseTestCase {
public void testTaskParse() {
@@ -33,8 +35,8 @@
TaskDefinitionImpl taskDefinition = taskActivity.getTaskDefinition();
// check for properties not previously parsed
- StaticTextExpression descriptionExpression = (StaticTextExpression) taskDefinition.getDescription();
- assertEquals("first task", descriptionExpression.getText());
+ Expression descriptionExpression = taskDefinition.getDescription();
+ assertEquals("first task", descriptionExpression.getExpressionString());
assertEquals(3, taskDefinition.getPriority());
assertEquals("aForm", taskDefinition.getFormResourceName());
assertEquals("1 day", taskDefinition.getDueDateDescription());
Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/cal/Duration.java
===================================================================
--- modules/pvm/src/main/java/org/jbpm/pvm/internal/cal/Duration.java (revision 6436)
+++ modules/pvm/src/main/java/org/jbpm/pvm/internal/cal/Duration.java (working copy)
@@ -31,26 +31,28 @@
import java.util.regex.Pattern;
import org.jbpm.api.JbpmException;
+import org.jbpm.pvm.internal.el.Expression;
import org.jbpm.pvm.internal.env.EnvironmentImpl;
-import org.jbpm.pvm.internal.script.ScriptManager;
import org.jbpm.pvm.internal.util.Clock;
/**
* represents a time duration.
- *
- *
With the constructor {link {@link #Duration(String)} you can create a
+ *
+ *
With the constructor {link {@link #Duration(String)} you can create a
* Duration from a text representation. The syntax is as follows
*
- *
+ *
*
* duration = part [',' part | 'and' part]*
* part = number ['business'] unit
* number = (0..9)+
* unit = (y|year|years|month|months|w|week|weeks|d|day|days|h|hour|hours|min|minute|minutes|s|sec|second|seconds|milli|millis|millisecond|milliseconds)
*
- *
+ *
* Duration is immutable.
*
+ *
+ * @author Huisheng Xu
*/
public class Duration implements Serializable {
@@ -65,12 +67,12 @@
protected int weeks;
protected int months;
protected int years;
-
+
private final static String dateFormat = "yyyy-MM-dd HH:mm:ss";
-
+
private static final Pattern dateDurationPattern = Pattern.compile("\\s*(#\\{.+\\})\\s*"
+ "(?:(\\+|-)\\s*(\\d+\\s+(?:business\\s+)?\\w+))?\\s*");
-
+
private static final Pattern durationPattern = Pattern.compile("\\s*(\\d+\\s+(?:business\\s+)?"
+ "\\w+)\\s*");
@@ -78,13 +80,13 @@
protected Duration() {
}
- /** parses the duration from a text
- *
+ /** parses the duration from a text
+ *
* duration = part [',' part | 'and' part]*
* part = number ['business'] unit
* number = (0..9)+
* unit = (y|year|years|month|months|w|week|weeks|d|day|days|h|hour|hours|min|minute|minutes|s|sec|second|seconds|milli|millis|millisecond|milliseconds)
- *
+ *
* @throws JbpmException if the parsing is unsuccessful
*/
public Duration(String text) {
@@ -93,23 +95,22 @@
for (String part: splitInParts(text)) {
parsePart(part);
}
-
+
isBusinessTime = text.indexOf("business")!=-1;
}
-
+
public static boolean isValidExpression(String durationExpression) {
try {
- new Duration(durationExpression);
+ new Duration(durationExpression);
} catch (JbpmException e) {
return false;
}
return true;
}
-
+
public static Date calculateDueDate(String durationExpression) {
Date duedate = null;
if (durationExpression != null) {
- ScriptManager scriptManager = ScriptManager.getScriptManager();
Date baseDate;
String durationString = null;
@@ -118,14 +119,15 @@
if (durationExpression.startsWith("#")) {
String baseDateEL = durationExpression.substring(0, durationExpression.indexOf("}") + 1);
- Object result = scriptManager.evaluateExpression(baseDateEL, null);
+ Object result = Expression.create(baseDateEL, null).evaluate();
if (result instanceof Date) {
baseDate = (Date) result;
} else if (result instanceof Calendar) {
baseDate = ((Calendar) result).getTime();
} else {
- throw new JbpmException("Invalid basedate type: " + baseDateEL + " is of type " + result.getClass().getName()
+ throw new JbpmException("Invalid basedate type: " + baseDateEL + " is of type "
+ + result.getClass().getName()
+ ". Only Date and Calendar are supported");
}
@@ -173,40 +175,40 @@
this.months = months;
this.years = years;
}
-
+
private List splitInParts(String text) {
List parts = new ArrayList(2);
while (text!=null) {
int commaIndex = text.indexOf(',');
int andIndex = text.indexOf(" and ");
- if ( ( (commaIndex==-1)
+ if ( ( (commaIndex==-1)
&& (andIndex!=-1)
- )
- ||
- ( ( (commaIndex!=-1)
+ )
+ ||
+ ( ( (commaIndex!=-1)
&& (andIndex!=-1)
- )
+ )
&& (andIndexcommaIndex)
)
) {
String part = text.substring(0, commaIndex).trim();
parts.add(part);
text = text.substring(commaIndex+1);
-
+
} else {
parts.add(text.trim());
text = null;
@@ -224,7 +226,7 @@
String quantityText = part.substring(0, spaceIndex).trim();
spaceIndex = part.lastIndexOf(' ');
String unitText = part.substring(spaceIndex+1).trim().toLowerCase();
-
+
int quantity;
try {
quantity = Integer.parseInt(quantityText);
@@ -237,7 +239,7 @@
}
fieldSetter.set(this, quantity);
}
-
+
interface FieldSetter {
void set(Duration duration, int quantity);
}
@@ -325,7 +327,7 @@
fieldSetters.put("year", fieldSetter);
fieldSetters.put("years", fieldSetter);
}
-
+
public int getDays() {
return days;
}
@@ -353,7 +355,7 @@
public int getSeconds() {
return seconds;
}
-
+
public int getWeeks() {
return weeks;
}
Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/el/Expression.java
===================================================================
--- modules/pvm/src/main/java/org/jbpm/pvm/internal/el/Expression.java (revision 6436)
+++ modules/pvm/src/main/java/org/jbpm/pvm/internal/el/Expression.java (working copy)
@@ -36,8 +36,9 @@
/** handles all expression resolving
- *
+ *
* @author Tom Baeyens
+ * @author Huisheng Xu
*/
public abstract class Expression implements Serializable {
@@ -55,7 +56,7 @@
if (expressionText==null) {
throw new JbpmException("expressionText is null");
}
-
+
if (language==null || language.startsWith(LANGUAGE_UEL)) {
if (expressionText.indexOf('{')==-1) {
return new StaticTextExpression(expressionText);
@@ -65,26 +66,28 @@
// by default, expr is interpreted as a value expression
if (language==null || LANGUAGE_UEL_VALUE.equals(language)) {
try {
- ValueExpression valueExpression = expressionFactory.createValueExpression(elContext, expressionText, Object.class);
-
+ ValueExpression valueExpression = expressionFactory
+ .createValueExpression(elContext, expressionText, Object.class);
+
return new UelValueExpression(valueExpression);
-
+
// if the expr is not a valid value expr...
} catch (ELException e) {
- // ... and the expr-type was not specified
+ // ... and the expr-type was not specified
if (language==null) {
// then try to parse it as a method expression
language = LANGUAGE_UEL_METHOD;
}
- }
- }
+ }
+ }
if (LANGUAGE_UEL_METHOD.equals(language)) {
- MethodExpression methodExpression = expressionFactory.createMethodExpression(elContext, expressionText, null, new Class>[]{});
+ MethodExpression methodExpression = expressionFactory
+ .createMethodExpression(elContext, expressionText, null, new Class>[]{});
return new UelMethodExpression(methodExpression);
}
- }
+ }
return new ScriptExpression(expressionText, language);
}
@@ -97,7 +100,11 @@
}
// runtime evaluation ///////////////////////////////////////////////////////
-
+
+ public Object evaluate() {
+ return evaluateInScope(null);
+ }
+
public Object evaluate(Execution execution) {
return evaluateInScope((ScopeInstanceImpl)execution);
}
@@ -105,7 +112,7 @@
public Object evaluate(Task task) {
return evaluateInScope((ScopeInstanceImpl)task);
}
-
+
public abstract Object evaluateInScope(ScopeInstanceImpl scopeInstance);
protected ELContext getElContext(ScopeInstanceImpl scopeInstance) {
@@ -120,4 +127,8 @@
}
return elContext;
}
+
+ public abstract String getExpressionString();
+
+ public abstract boolean isLiteralText();
}
Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/el/ScriptExpression.java
===================================================================
--- modules/pvm/src/main/java/org/jbpm/pvm/internal/el/ScriptExpression.java (revision 6436)
+++ modules/pvm/src/main/java/org/jbpm/pvm/internal/el/ScriptExpression.java (working copy)
@@ -26,15 +26,18 @@
/**
+ * This is script expression, it will use ScriptManager to evaluate the expr by specified language.
+ *
* @author Tom Baeyens
+ * @author Huisheng Xu
*/
public class ScriptExpression extends Expression {
private static final long serialVersionUID = 1L;
-
+
protected String expressionText;
protected String language;
-
+
public ScriptExpression(String expressionText, String language) {
this.expressionText = expressionText;
this.language = language;
@@ -44,4 +47,12 @@
ScriptManager scriptManager = ScriptManager.getScriptManager();
return scriptManager.evaluateExpression(expressionText, language);
}
+
+ public String getExpressionString() {
+ return expressionText;
+ }
+
+ public boolean isLiteralText() {
+ return false;
+ }
}
Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/el/StaticTextExpression.java
===================================================================
--- modules/pvm/src/main/java/org/jbpm/pvm/internal/el/StaticTextExpression.java (revision 6436)
+++ modules/pvm/src/main/java/org/jbpm/pvm/internal/el/StaticTextExpression.java (working copy)
@@ -25,14 +25,17 @@
/**
+ * This is a static text expression, didn't contains any script expression.
+ *
* @author Tom Baeyens
+ * @author Huiheng Xu
*/
public class StaticTextExpression extends Expression {
private static final long serialVersionUID = 1L;
String text;
-
+
public StaticTextExpression(String text) {
this.text = text;
}
@@ -41,7 +44,11 @@
return text;
}
- public String getText() {
+ public String getExpressionString() {
return text;
}
+
+ public boolean isLiteralText() {
+ return true;
+ }
}
Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/el/UelMethodExpression.java
===================================================================
--- modules/pvm/src/main/java/org/jbpm/pvm/internal/el/UelMethodExpression.java (revision 6436)
+++ modules/pvm/src/main/java/org/jbpm/pvm/internal/el/UelMethodExpression.java (working copy)
@@ -29,11 +29,12 @@
/**
* @author Tom Baeyens
+ * @author Huisheng Xu
*/
public class UelMethodExpression extends Expression {
private static final long serialVersionUID = 1L;
-
+
protected MethodExpression methodExpression;
public UelMethodExpression(MethodExpression methodExpression) {
@@ -44,4 +45,12 @@
ELContext elContext = getElContext(scopeInstance);
return methodExpression.invoke(elContext, null);
}
+
+ public String getExpressionString() {
+ return methodExpression.getExpressionString();
+ }
+
+ public boolean isLiteralText() {
+ return false;
+ }
}
Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/el/UelValueExpression.java
===================================================================
--- modules/pvm/src/main/java/org/jbpm/pvm/internal/el/UelValueExpression.java (revision 6436)
+++ modules/pvm/src/main/java/org/jbpm/pvm/internal/el/UelValueExpression.java (working copy)
@@ -32,11 +32,12 @@
/**
* @author Tom Baeyens
+ * @author Huisheng Xu
*/
public class UelValueExpression extends Expression {
private static final long serialVersionUID = 1L;
-
+
protected ValueExpression valueExpression;
public UelValueExpression(ValueExpression valueExpression) {
@@ -54,14 +55,22 @@
public void setValue(Task task, Object value) {
setValue((ScopeInstanceImpl)task, value);
}
-
+
public void setValue(Execution execution, Object value) {
setValue((ScopeInstanceImpl)execution, value);
}
-
+
public void setValue(ScopeInstanceImpl scopeInstance, Object value) {
ELContext elContext = getElContext(scopeInstance);
valueExpression.setValue(elContext, value);
}
+ public String getExpressionString() {
+ return valueExpression.getExpressionString();
+ }
+
+ public boolean isLiteralText() {
+ return false;
+ }
+
}
Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/email/impl/MailProducerImpl.java
===================================================================
--- modules/pvm/src/main/java/org/jbpm/pvm/internal/email/impl/MailProducerImpl.java (revision 6436)
+++ modules/pvm/src/main/java/org/jbpm/pvm/internal/email/impl/MailProducerImpl.java (working copy)
@@ -49,16 +49,17 @@
import org.jbpm.api.JbpmException;
import org.jbpm.api.identity.Group;
import org.jbpm.api.identity.User;
+import org.jbpm.pvm.internal.el.Expression;
import org.jbpm.pvm.internal.email.spi.AddressResolver;
import org.jbpm.pvm.internal.email.spi.MailProducer;
import org.jbpm.pvm.internal.env.EnvironmentImpl;
import org.jbpm.pvm.internal.identity.spi.IdentitySession;
-import org.jbpm.pvm.internal.script.ScriptManager;
/**
* Default mail producer.
- *
+ *
* @author Alejandro Guizar
+ * @author Huisheng Xu
*/
public class MailProducerImpl implements MailProducer, Serializable {
@@ -96,7 +97,7 @@
* Fills the from
attribute of the given email. The sender addresses are an
* optional element in the mail template. If absent, each mail server supplies the current
* user's email address.
- *
+ *
* @see {@link InternetAddress#getLocalAddress(Session)}
*/
protected void fillFrom(Execution execution, Message email) throws MessagingException {
@@ -138,8 +139,7 @@
}
private T evaluateExpression(String expression, Class type) {
- ScriptManager scriptManager = ScriptManager.getScriptManager();
- Object value = scriptManager.evaluateExpression(expression, template.getLanguage());
+ Object value = Expression.create(expression, template.getLanguage()).evaluate();
return type.cast(value);
}
@@ -265,7 +265,7 @@
// obtain interface to data
DataHandler dataHandler = createDataHandler(attachmentTemplate);
attachmentPart.setDataHandler(dataHandler);
-
+
// resolve file name
String name = attachmentTemplate.getName();
if (name != null) {
Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java
===================================================================
--- modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java (revision 6436)
+++ modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java (working copy)
@@ -66,7 +66,6 @@
import org.jbpm.pvm.internal.model.op.AtomicOperation;
import org.jbpm.pvm.internal.model.op.MoveToChildActivity;
import org.jbpm.pvm.internal.model.op.Signal;
-import org.jbpm.pvm.internal.script.ScriptManager;
import org.jbpm.pvm.internal.session.DbSession;
import org.jbpm.pvm.internal.session.MessageSession;
import org.jbpm.pvm.internal.session.RepositorySession;
@@ -82,6 +81,7 @@
/**
* @author Tom Baeyens
+ * @author Huisheng Xu
*/
public class ExecutionImpl extends ScopeInstanceImpl implements ClientProcessInstance,
ActivityExecution, EventListenerExecution {
@@ -89,13 +89,13 @@
private static final long serialVersionUID = 1L;
private static final Log log = Log.getLog(ExecutionImpl.class.getName());
-
- /** an optional name for this execution. can be used to
- * differentiate concurrent paths of execution like e.g.
+
+ /** an optional name for this execution. can be used to
+ * differentiate concurrent paths of execution like e.g.
* the 'shipping' and 'billing' paths. */
protected String name;
- /** a key for this execution. typically this is an externally provided reference
+ /** a key for this execution. typically this is an externally provided reference
* that is unique within the scope of the process definition. */
protected String key;
@@ -109,10 +109,10 @@
* concurrency. */
protected ExecutionImpl parent;
protected ExecutionImpl processInstance;
-
- /** the super process link in case this is a sub process execution */
+
+ /** the super process link in case this is a sub process execution */
protected ExecutionImpl superProcessExecution;
-
+
/** the sub process link in case of sub process execution */
protected ExecutionImpl subProcessInstance;
@@ -121,7 +121,7 @@
/** reference to the current activity instance history record */
protected Long historyActivityInstanceDbid;
-
+
/** start time of the activity for history purposes (not persisted) */
protected Date historyActivityStart;
@@ -130,10 +130,10 @@
protected Map systemVariables = new HashMap();
// persistent indicators of the current position ////////////////////////////
-
+
/** persistent process definition reference */
protected String processDefinitionId;
-
+
/** persistent activity reference */
protected String activityName;
@@ -141,7 +141,7 @@
/** transient cached process definition. persistence is managed in {@link #processDefinitionId} */
protected ProcessDefinitionImpl processDefinition;
-
+
/** transient cached current activity pointer. persistence is managed in {@link #activityName} */
private ActivityImpl activity;
@@ -157,7 +157,7 @@
protected ObservableElementImpl eventSource;
// cached named executions //////////////////////////////////////////////////
-
+
/** caches the child executions by execution name. This member might be
* null and is only created from the executions in case its needed. Note
* that not all executions are forced to have a name and duplicates are allowed.
@@ -175,7 +175,7 @@
protected Propagation propagation;
// construction /////////////////////////////////////////////////////////////
-
+
public void initializeProcessInstance(ProcessDefinitionImpl processDefinition, String key) {
setProcessDefinition(processDefinition);
setActivity(processDefinition.getInitial());
@@ -184,7 +184,7 @@
this.key = key;
save();
-
+
HistoryEvent.fire(new ProcessInstanceCreate(), this);
}
@@ -211,7 +211,7 @@
}
this.state = STATE_ACTIVE_ROOT;
ExecutionImpl scopedExecution = initializeScopes();
-
+
fire(Event.START, getProcessDefinition());
if (getActivity()!=null) {
scopedExecution.performAtomicOperation(AtomicOperation.EXECUTE_ACTIVITY);
@@ -223,7 +223,7 @@
ActivityImpl initial = getProcessDefinition().getInitial();
ExecutionImpl scopedExecution = null;
-
+
if (initial!=null) {
enteredActivities.add(initial);
ActivityImpl parentActivity = initial.getParentActivity();
@@ -231,19 +231,19 @@
enteredActivities.addFirst(parentActivity);
parentActivity = parentActivity.getParentActivity();
}
-
+
scopedExecution = this;
initializeVariables(getProcessDefinition(), this);
initializeTimers(getProcessDefinition());
-
+
for (ActivityImpl enteredActivity: enteredActivities) {
if (enteredActivity.isLocalScope()) {
scopedExecution.setActivity(enteredActivity);
scopedExecution = scopedExecution.createScope(enteredActivity);
}
}
-
+
scopedExecution.setActivity(initial);
}
return scopedExecution;
@@ -251,29 +251,29 @@
public ExecutionImpl createScope(ScopeElementImpl scope) {
ExecutionImpl child = createExecution(scope.getName());
-
+
setState(STATE_INACTIVE_SCOPE);
child.setState(STATE_ACTIVE_ROOT);
-
+
// copy the current state from the child execution to the parent execution
child.setActivity(getActivity());
child.setTransition(getTransition());
child.setPropagation(getPropagation());
-
+
child.initializeVariables(scope, this);
child.initializeTimers(scope);
-
+
return child;
}
-
+
public ExecutionImpl destroyScope(CompositeElementImpl scope) {
destroyTimers(scope);
-
+
// copy the current state from the child execution to the parent execution
parent.setActivity(getActivity());
parent.setTransition(getTransition());
parent.setPropagation(getPropagation());
-
+
ExecutionImpl parentsParent = parent.getParent();
if (parentsParent!=null
&& STATE_INACTIVE_CONCURRENT_ROOT.equals(parentsParent.getState())) {
@@ -282,16 +282,16 @@
else {
parent.setState(STATE_ACTIVE_ROOT);
}
-
- // capture the parent execution cause the
+
+ // capture the parent execution cause the
// subsequent invocation of end() will set the parent to null
ExecutionImpl parent = this.parent;
-
+
end();
return parent;
}
-
+
@Override
protected void destroyTimers(CompositeElementImpl scope) {
TimerSession timerSession = EnvironmentImpl.getFromCurrent(TimerSession.class, false);
@@ -319,7 +319,7 @@
}
return "execution";
}
-
+
// execution method : end ///////////////////////////////////////////////////
public void end() {
@@ -341,7 +341,7 @@
|| state.equals(STATE_ASYNC)) {
throw new JbpmException("invalid end state: "+state);
}
-
+
if (log.isDebugEnabled()) {
if (state==STATE_ENDED) {
log.debug(toString()+" ends");
@@ -350,32 +350,32 @@
log.debug(toString()+" ends with state "+state);
}
}
-
+
// end all child executions
// making a copy of the executions to prevent ConcurrentMoidificationException
List executionsToEnd = new ArrayList(executions);
for (ExecutionImpl child: executionsToEnd) {
child.end(state);
}
-
+
setState(state);
this.propagation = Propagation.EXPLICIT;
-
+
DbSession dbSession = EnvironmentImpl.getFromCurrent(DbSession.class, false);
-
-
+
+
if (parent!=null) {
-
+
if (dbSession!=null) {
-
+
// make sure task attached to this execution are completed or skipped
TaskImpl task = dbSession.findTaskByExecution(this);
if (task != null && !task.isCompleted()) {
task.skip(null);
}
-
+
dbSession.delete(this);
}
parent.removeExecution(this);
@@ -397,7 +397,7 @@
}
}
}
-
+
public void end(OpenExecution executionToEnd) {
((ExecutionImpl)executionToEnd).end();
}
@@ -415,7 +415,7 @@
public void signal(String signal) {
signal(signal, (Map)null);
}
-
+
public void signal(Map parameters) {
signal(null, parameters);
}
@@ -436,7 +436,7 @@
throw new JbpmException("execution is not in a activity or in a transition");
}
}
-
+
public void signal(Execution execution) {
((ExecutionImpl)execution).signal(null, (Map)null);
}
@@ -454,7 +454,7 @@
}
// execution method : take ////////////////////////////////////////////////
-
+
/** @see Execution#takeDefaultTransition() */
public void takeDefaultTransition() {
TransitionImpl defaultTransition = getActivity().getDefaultOutgoingTransition();
@@ -483,7 +483,7 @@
setPropagation(Propagation.EXPLICIT);
setTransition((TransitionImpl) transition);
-
+
fire(Event.END, getActivity(), AtomicOperation.TRANSITION_END_ACTIVITY);
}
@@ -504,24 +504,24 @@
}
execute(nestedActivity);
}
-
+
/** @see Execution#execute(Activity) */
public void execute(Activity activity) {
if (activity==null) {
throw new JbpmException("activity is null");
}
checkActive();
-
+
this.propagation = Propagation.EXPLICIT;
performAtomicOperation(new MoveToChildActivity((ActivityImpl) activity));
}
-
+
// execution method : waitForSignal /////////////////////////////////////////
-
+
public void waitForSignal() {
propagation = Propagation.WAIT;
}
-
+
// execution method : proceed ///////////////////////////////////////////////
public void proceed() {
@@ -533,8 +533,8 @@
if (defaultTransition!=null) {
take(defaultTransition);
}
- // in block structured processDefinition languages we assume that
- // there is no default transition and that there is a
+ // in block structured processDefinition languages we assume that
+ // there is no default transition and that there is a
// parent activity of the current activity
else {
ActivityImpl parentActivity = getActivity().getParentActivity();
@@ -545,9 +545,9 @@
performAtomicOperation(AtomicOperation.PROPAGATE_TO_PARENT);
}
else {
- // When we don't know how to proceed, i don't know if it's best to
+ // When we don't know how to proceed, i don't know if it's best to
// throw new PvmException("don't know how to proceed");
- // or to end the execution. Because of convenience for testing,
+ // or to end the execution. Because of convenience for testing,
// I opted to end the execution.
end();
}
@@ -563,7 +563,7 @@
}
// events ///////////////////////////////////////////////////////////////////
-
+
public void fire(String eventName, ObservableElement eventSource) {
fire(eventName, (ObservableElementImpl) eventSource, null);
}
@@ -582,17 +582,17 @@
performAtomicOperationSync(eventCompletedOperation);
}
}
-
+
public static EventImpl findEvent(ObservableElementImpl observableElement, String eventName) {
if (observableElement==null) {
return null;
}
-
+
EventImpl event = observableElement.getEvent(eventName);
if (event!=null) {
return event;
}
-
+
return findEvent(observableElement.getParent(), eventName);
}
@@ -622,7 +622,7 @@
return propagatingExecution;
}
- // asynchronous continuations ////////////////////////////////////////////////
+ // asynchronous continuations ////////////////////////////////////////////////
public synchronized void performAtomicOperation(AtomicOperation operation) {
if (operation.isAsync(this)) {
@@ -632,7 +632,7 @@
performAtomicOperationSync(operation);
}
}
-
+
public void sendContinuationMessage(AtomicOperation operation) {
EnvironmentImpl environment = EnvironmentImpl.getCurrent();
MessageSession messageSession = environment.get(MessageSession.class);
@@ -649,8 +649,8 @@
// initialise the fifo queue of atomic operations
atomicOperations = new LinkedList();
atomicOperations.offer(operation);
-
- ExecutionContext originalExecutionContext = null;
+
+ ExecutionContext originalExecutionContext = null;
ExecutionContext executionContext = null;
EnvironmentImpl environment = EnvironmentImpl.getCurrent();
if (environment!=null) {
@@ -665,7 +665,7 @@
environment.setContext(executionContext);
}
}
-
+
try {
while (! atomicOperations.isEmpty()) {
AtomicOperation atomicOperation = atomicOperations.poll();
@@ -674,7 +674,7 @@
}
finally {
atomicOperations = null;
-
+
if (executionContext!=null) {
environment.removeContext(executionContext);
}
@@ -688,13 +688,13 @@
}
}
- /**
+ /**
* Important: Only use this if resolving an expression on another execution then the current execution
- *
+ *
* TODO: remove this operation once the environment/executionContext is refactored
*/
public Object resolveExpression(String expression, String language) {
- ExecutionContext originalExecutionContext = null;
+ ExecutionContext originalExecutionContext = null;
ExecutionContext executionContext = null;
EnvironmentImpl environment = EnvironmentImpl.getCurrent();
if (environment!=null) {
@@ -709,10 +709,9 @@
environment.setContext(executionContext);
}
}
-
+
try {
- ScriptManager scriptManager = ScriptManager.getScriptManager();
- return scriptManager.evaluateScript(expression, language);
+ return Expression.create(expression, language).evaluate();
}
catch (RuntimeException e) {
log.error("Error while evaluation script " + expression, e);
@@ -730,7 +729,7 @@
public void handleException(ObservableElementImpl observableElement, EventImpl event,
EventListenerReference eventListenerReference, Exception exception, String rethrowMessage) {
-
+
List processElements = new ArrayList();
if (eventListenerReference!=null) {
processElements.add(eventListenerReference);
@@ -742,7 +741,7 @@
processElements.add(observableElement);
observableElement = observableElement.getParent();
}
-
+
for (ProcessElementImpl processElement: processElements) {
List exceptionHandlers = processElement.getExceptionHandlers();
if (exceptionHandlers!=null) {
@@ -766,7 +765,7 @@
log.trace("rethrowing exception cause no exception handler for "+exception);
ExceptionHandlerImpl.rethrow(exception, rethrowMessage+": "+exception.getMessage());
}
-
+
// tasks ////////////////////////////////////////////////////////////////////
/** tasks and swimlane assignment.
@@ -778,10 +777,10 @@
if (assigneeExpression!=null) {
String assignee = (String) assigneeExpression.evaluate(this);
assignable.setAssignee(assignee);
-
+
if (log.isTraceEnabled()) log.trace("task "+name+" assigned to "+assignee+" using expression "+assigneeExpression);
}
-
+
Expression candidateUsersExpression = assignableDefinition.getCandidateUsersExpression();
if (candidateUsersExpression!=null) {
String candidateUsers = (String) candidateUsersExpression.evaluate(this);
@@ -792,7 +791,7 @@
assignable.addCandidateUser(candidateUser);
}
}
-
+
Expression candidateGroupsExpression = assignableDefinition.getCandidateGroupsExpression();
if (candidateGroupsExpression!=null) {
String candidateGroups = (String) candidateGroupsExpression.evaluate(this);
@@ -802,11 +801,11 @@
assignable.addCandidateGroup(candidateGroup);
}
}
-
+
UserCodeReference assignmentHandlerReference = assignableDefinition
.getAssignmentHandlerReference();
if (assignmentHandlerReference!=null) {
- // JBPM-2758
+ // JBPM-2758
// TODO Find out why processdefinition is null in at this time....
if (processDefinition == null) {
processDefinition = getProcessDefinition();
@@ -825,25 +824,25 @@
}
protected String resolveAssignmentExpression(String expression, String expressionLanguage) {
- ScriptManager scriptManager = EnvironmentImpl.getFromCurrent(ScriptManager.class);
- Object result = scriptManager.evaluateExpression(expression, expressionLanguage);
+ Object result = Expression.create(expression, expressionLanguage).evaluate();
if (result == null || result instanceof String) {
return (String) result;
}
- throw new JbpmException("result of assignment expression "+expression+" is "+result+" ("+result.getClass().getName()+") instead of String");
+ throw new JbpmException("result of assignment expression " + expression
+ + " is " + result + " (" + result.getClass().getName() + ") instead of String");
}
-
+
// swimlanes ////////////////////////////////////////////////////////////////
-
+
public void addSwimlane(SwimlaneImpl swimlane) {
swimlanes.put(swimlane.getName(), swimlane);
swimlane.setExecution(this);
}
-
+
public SwimlaneImpl getSwimlane(String swimlaneName) {
return swimlanes.get(swimlaneName);
}
-
+
public void removeSwimlane(SwimlaneImpl swimlane) {
swimlanes.remove(swimlane.getName());
swimlane.setExecution(null);
@@ -875,7 +874,7 @@
swimlanes.put(swimlaneName, swimlane);
return swimlane;
}
-
+
// child executions /////////////////////////////////////////////////////////
public ExecutionImpl createExecution() {
@@ -884,22 +883,22 @@
public ExecutionImpl createExecution(String name) {
// when an activity calls createExecution, propagation is explicit.
- // this means that the default propagation (proceed()) will not be called
+ // this means that the default propagation (proceed()) will not be called
propagation = Propagation.EXPLICIT;
// create new execution
ExecutionImpl childExecution = newChildExecution();
- // initialize child execution
+ // initialize child execution
childExecution.setProcessDefinition(getProcessDefinition());
childExecution.processInstance = this.processInstance;
childExecution.name = name;
-
+
// composeIds uses the parent so the childExecution has to be added before the ids are composed
- childExecution.setParent(this);
+ childExecution.setParent(this);
childExecution.save();
// make sure that child execution are saved before added to a persistent collection
- // cause of the 'assigned' id strategy, adding the childExecution to the persistent collection
+ // cause of the 'assigned' id strategy, adding the childExecution to the persistent collection
// before the dbid is assigned will result in identifier of an instance of ExecutionImpl altered from 0 to x
addExecution(childExecution);
@@ -953,7 +952,7 @@
}
return executionsMap;
}
-
+
public boolean hasExecution(String name) {
return getExecutionsMap() != null && executionsMap.containsKey(name);
}
@@ -971,11 +970,11 @@
&& activityName != null) {
activityNames.add(activityName);
}
-
+
for (ExecutionImpl childExecution: executions) {
childExecution.addActiveActivityNames(activityNames);
}
-
+
return activityNames;
}
@@ -993,9 +992,9 @@
return null;
}
-
+
// system variables /////////////////////////////////////////////////////////
-
+
public void createSystemVariable(String key, Object value) {
createSystemVariable(key, value, null);
}
@@ -1016,7 +1015,7 @@
createSystemVariable(key, value, null);
}
}
-
+
public Object getSystemVariable(String key) {
Variable variable = systemVariables.get(key);
if (variable!=null) {
@@ -1024,7 +1023,7 @@
}
return null;
}
-
+
public boolean removeSystemVariable(String key) {
if (systemVariables.containsKey(key)) {
return systemVariables.remove(key) != null;
@@ -1037,7 +1036,7 @@
public ClientProcessInstance createSubProcessInstance(ClientProcessDefinition processDefinition) {
return createSubProcessInstance(processDefinition, null);
}
-
+
public ClientProcessInstance createSubProcessInstance(ClientProcessDefinition processDefinition, String key) {
if (subProcessInstance!=null) {
throw new JbpmException(toString()+" already has a sub process instance: "+subProcessInstance);
@@ -1046,11 +1045,11 @@
subProcessInstance.setSuperProcessExecution(this);
return subProcessInstance;
}
-
+
public ClientProcessInstance startSubProcessInstance(ClientProcessDefinition processDefinition) {
return startSubProcessInstance(processDefinition, null);
}
-
+
public ClientProcessInstance startSubProcessInstance(ClientProcessDefinition processDefinition, String key) {
createSubProcessInstance(processDefinition, key);
subProcessInstance.start();
@@ -1084,11 +1083,11 @@
if (!isActive()) {
throw new JbpmException(toString()+" is not active: "+state);
} else if (this.subProcessInstance != null && !Execution.STATE_ENDED.equals(this.subProcessInstance.getState())) {
- throw new JbpmException(toString() + " has running subprocess: "
+ throw new JbpmException(toString() + " has running subprocess: "
+ this.subProcessInstance.toString() + " in state " + this.subProcessInstance.getState());
}
}
-
+
public boolean isEnded() {
if (Execution.STATE_ENDED.equals(state)) {
return true;
@@ -1120,7 +1119,7 @@
////////////////////////////////////////////////////////////////////////////////
// overriding the ScopeInstanceImpl methods /////////////////////////////////
-
+
public ScopeInstanceImpl getParentVariableScope() {
return parent;
}
@@ -1130,10 +1129,10 @@
}
// overridable by process languages /////////////////////////////////////////
-
- /** by default this will use {@link ActivityImpl#findOutgoingTransition(String)} to
- * search for the outgoing transition, which includes a search over the parent chain
- * of the current activity. This method allows process languages to overwrite this default
+
+ /** by default this will use {@link ActivityImpl#findOutgoingTransition(String)} to
+ * search for the outgoing transition, which includes a search over the parent chain
+ * of the current activity. This method allows process languages to overwrite this default
* implementation of the transition lookup by transitionName.*/
protected TransitionImpl findTransition(String transitionName) {
return getActivity().findOutgoingTransition(transitionName);
@@ -1142,7 +1141,7 @@
protected TransitionImpl findDefaultTransition() {
return getActivity().findDefaultTransition();
}
-
+
// history //////////////////////////////////////////////////////////////////
public void historyAutomatic() {
@@ -1152,7 +1151,7 @@
public void historyDecision(String transitionName) {
HistoryEvent.fire(new DecisionEnd(transitionName), this);
}
-
+
public void historyActivityStart() {
HistoryEvent.fire(new ActivityStart(), this);
}
@@ -1172,12 +1171,12 @@
public boolean equals(Object o) {
return EqualsUtil.equals(this, o);
}
-
+
// process definition getter and setter /////////////////////////////////////
- // this getter and setter is special because persistence is based on the //
+ // this getter and setter is special because persistence is based on the //
// process definition id. //
/////////////////////////////////////////////////////////////////////////////
-
+
public ProcessDefinitionImpl getProcessDefinition() {
if (processDefinition == null && processDefinitionId != null) {
RepositorySession repositorySession = EnvironmentImpl
@@ -1193,19 +1192,19 @@
this.processDefinition = processDefinition;
this.processDefinitionId = processDefinition.getId();
}
-
+
// activity getter and setter ///////////////////////////////////////////////
- // this getter and setter is special because persistence is based on the //
+ // this getter and setter is special because persistence is based on the //
// activity name. //
/////////////////////////////////////////////////////////////////////////////
-
+
public ActivityImpl getActivity() {
if (activity == null && activityName != null) {
activity = getProcessDefinition().findActivity(activityName);
}
return activity;
}
-
+
public void setActivity(ActivityImpl activity) {
this.activity = activity;
if (activity!=null) {
@@ -1237,14 +1236,14 @@
}
// getters and setters for scope instance //////////////////////////////////////
-
+
@Override
public ExecutionImpl getExecution() {
return this;
}
// getters and setters /////////////////////////////////////////////////////////
-
+
public TransitionImpl getTransition() {
return transition;
}
Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExpressionCondition.java
===================================================================
--- modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExpressionCondition.java (revision 6436)
+++ modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExpressionCondition.java (working copy)
@@ -23,34 +23,34 @@
import org.jbpm.api.JbpmException;
import org.jbpm.api.model.OpenExecution;
-import org.jbpm.pvm.internal.script.ScriptManager;
+import org.jbpm.pvm.internal.el.Expression;
/**
* @author Tom Baeyens
+ * @author Huisheng Xu
*/
public class ExpressionCondition implements Condition {
private static final long serialVersionUID = 1L;
-
+
protected String expression;
protected String language;
-
+
public boolean evaluate(OpenExecution execution) {
- ScriptManager scriptManager = ScriptManager.getScriptManager();
- Object result = scriptManager.evaluateExpression(expression, language);
+ Object result = Expression.create(expression, language).evaluate();
if (result instanceof Boolean) {
return ((Boolean) result).booleanValue();
}
- throw new JbpmException("expression condition '"+expression+"' did not return a boolean: "+result);
+ throw new JbpmException("expression condition '" + expression + "' did not return a boolean: "+result);
}
public void setExpression(String expression) {
this.expression = expression;
}
-
+
public void setLanguage(String language) {
this.language = language;
}
-
+
}
Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/model/VariableOutDefinitionSet.java
===================================================================
--- modules/pvm/src/main/java/org/jbpm/pvm/internal/model/VariableOutDefinitionSet.java (revision 6436)
+++ modules/pvm/src/main/java/org/jbpm/pvm/internal/model/VariableOutDefinitionSet.java (working copy)
@@ -26,16 +26,17 @@
import java.util.Collections;
import java.util.List;
+import org.jbpm.pvm.internal.el.Expression;
import org.jbpm.pvm.internal.env.EnvironmentImpl;
-import org.jbpm.pvm.internal.script.ScriptManager;
/**
* @author Tom Baeyens
+ * @author Huisheng Xu
*/
public class VariableOutDefinitionSet implements Serializable {
-
+
private static final long serialVersionUID = 1L;
-
+
protected List variableOutDefinitions;
public void processOutVariables(ExecutionImpl outerExecution, ScopeInstanceImpl innerScopeInstance) {
@@ -44,13 +45,11 @@
for (VariableOutDefinitionImpl variableOutDefinition: variableOutDefinitions) {
String variableName = variableOutDefinition.getName();
if (variableName!=null) {
- ScriptManager scriptManager = EnvironmentImpl.getFromCurrent(ScriptManager.class);
-
// TODO update evaluateExpression so that scopeInstance can be passed in directly
String expression = variableOutDefinition.getExpression();
String language = variableOutDefinition.getLanguage();
- Object value = scriptManager.evaluateExpression(expression, language);
+ Object value = Expression.create(expression, language).evaluateInScope(innerScopeInstance);
outerExecution.setVariable(variableName, value);
}
}
@@ -62,7 +61,7 @@
&& (!variableOutDefinitions.isEmpty())
);
}
-
+
public List getVariableOutDefinitions() {
if (variableOutDefinitions==null) {
return Collections.emptyList();
Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/descriptor/ExpressionDescriptor.java
===================================================================
--- modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/descriptor/ExpressionDescriptor.java (revision 6436)
+++ modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/descriptor/ExpressionDescriptor.java (working copy)
@@ -21,23 +21,23 @@
*/
package org.jbpm.pvm.internal.wire.descriptor;
-import org.jbpm.pvm.internal.script.ScriptManager;
+import org.jbpm.pvm.internal.el.Expression;
import org.jbpm.pvm.internal.wire.WireContext;
/**
* @author Tom Baeyens
+ * @author Huisheng Xu
*/
public class ExpressionDescriptor extends AbstractDescriptor {
private static final long serialVersionUID = 1L;
-
+
protected String expression;
protected String language;
-
+
public Object construct(WireContext wireContext) {
- ScriptManager scriptManager = ScriptManager.getScriptManager();
- Object result = scriptManager.evaluateExpression(expression, language);
+ Object result = Expression.create(expression, language).evaluate();
return result;
}
Index: modules/pvm/src/test/java/org/jbpm/pvm/internal/el/ExpressionTest.java
===================================================================
--- modules/pvm/src/test/java/org/jbpm/pvm/internal/el/ExpressionTest.java (revision 0)
+++ modules/pvm/src/test/java/org/jbpm/pvm/internal/el/ExpressionTest.java (revision 0)
@@ -0,0 +1,43 @@
+
+package org.jbpm.pvm.internal.el;
+
+import junit.framework.*;
+import org.jbpm.api.*;
+import org.jbpm.pvm.internal.model.*;
+
+/**
+ * @author Huisheng Xu
+ */
+public class ExpressionTest extends TestCase {
+ public void testStaticEl() {
+ Expression expr = Expression.create("Lingo", null);
+ assertEquals("Lingo", expr.evaluate((Execution) null));
+ }
+
+ public void testValueEl() {
+ Expression expr = Expression.create("#{name}", null);
+ ExecutionImpl execution = new ExecutionImpl();
+ execution.setVariable("name", "Lingo");
+ assertEquals("Lingo", expr.evaluate(execution));
+ }
+
+ public void testFunctionEl() {
+ Expression expr = Expression.create("#{length(array)}", null);
+ ExecutionImpl execution = new ExecutionImpl();
+ execution.setVariable("array", new String[] {"1", "2", "3"});
+ assertEquals(3, expr.evaluate(execution));
+ }
+
+ public void testMethodEl() {
+ Expression expr = Expression.create("#{action.login()}", null);
+ ExecutionImpl execution = new ExecutionImpl();
+ execution.setVariable("action", new Demo());
+ assertEquals("Lingo", expr.evaluate(execution));
+ }
+
+ public static class Demo {
+ public String login() {
+ return "Lingo";
+ }
+ }
+}
Index: modules/test-db/src/test/java/org/jbpm/test/variables/VariableExpressionTest.java
===================================================================
--- modules/test-db/src/test/java/org/jbpm/test/variables/VariableExpressionTest.java (revision 6436)
+++ modules/test-db/src/test/java/org/jbpm/test/variables/VariableExpressionTest.java (working copy)
@@ -20,7 +20,7 @@
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
/**
- *
+ *
*/
package org.jbpm.test.variables;
@@ -39,7 +39,7 @@
* @author Maciej Swiderski
*/
public class VariableExpressionTest extends JbpmTestCase {
-
+
public void testExpression() {
deployJpdlXmlString(
"" +
@@ -51,7 +51,7 @@
" " +
" " +
" " +
- " " +
+ " " +
" " +
" " +
" " +
@@ -63,17 +63,17 @@
" " +
""
);
-
+
Map vars = new HashMap();
vars.put("counter", 0);
-
+
ProcessInstance processInstance = executionService.startProcessInstanceByKey("theProcess", vars);
assertActivityActive(processInstance.getId(), "waitHere");
-
+
Integer counter = (Integer) executionService.getVariable(processInstance.getId(), "counter");
assertEquals(new Integer(10), counter);
}
-
+
public void testNullValueExpression() {
deployJpdlXmlString(
"" +
@@ -85,7 +85,7 @@
" " +
" " +
" " +
- " " +
+ " " +
" " +
" " +
" " +
@@ -97,17 +97,17 @@
" " +
""
);
-
+
Map vars = new HashMap();
vars.put("counter", null);
-
+
ProcessInstance processInstance = executionService.startProcessInstanceByKey("theProcess", vars);
assertActivityActive(processInstance.getId(), "waitHere");
-
+
Object value = executionService.getVariable(processInstance.getId(), "counter");
assertEquals(null, value);
}
-
+
public void testMissingVariableExpression() {
deployJpdlXmlString(
"" +
@@ -119,7 +119,7 @@
" " +
" " +
" " +
- " " +
+ " " +
" " +
" " +
" " +
@@ -131,20 +131,21 @@
" " +
""
);
-
+
Map vars = new HashMap();
try {
ProcessInstance processInstance = executionService.startProcessInstanceByKey("theProcess", vars);
fail("Variable counter is not set, should fail");
- } catch (JbpmException e) {
+ } catch (Exception e) {
- assertTrue(e.getMessage().indexOf("Cannot find property counter") != -1);
+ assertEquals("Cannot resolve identifier 'counter'",
+ e.getMessage());
}
}
-
-
+
+
public static class MyJavaActivity implements ActivityBehaviour {
private static final long serialVersionUID = 1L;
@@ -154,7 +155,7 @@
counter++;
execution.setVariable("counter", counter);
}
-
+
}
}