JBoss JBPM SVN: r6141 - in jbpm4/trunk: modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity and 10 other directories.
by do-not-reply@jboss.org
Author: tom.baeyens(a)jboss.com
Date: 2010-01-27 10:37:12 -0500 (Wed, 27 Jan 2010)
New Revision: 6141
Added:
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElFactory.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElFactoryImpl.java
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/assign/
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/assign/Address.java
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/assign/AssignTest.java
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/assign/Person.java
Removed:
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElContextFactory.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElContextFactoryImpl.java
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/el/
Modified:
jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/AssignActivity.java
jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/AssignBinding.java
jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/xml/JpdlParser.java
jbpm4/trunk/modules/pvm/pom.xml
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/AbstractTransaction.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/type/converter/SerializableToBytesConverter.java
jbpm4/trunk/modules/pvm/src/main/resources/jbpm.default.cfg.xml
jbpm4/trunk/pom.xml
Log:
JBPM-2653 completed expressions resolving updates for CDI/seam integration for assign activity (didn't yet refactor the existing activities)
Modified: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/AssignActivity.java
===================================================================
--- jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/AssignActivity.java 2010-01-27 13:52:27 UTC (rev 6140)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/AssignActivity.java 2010-01-27 15:37:12 UTC (rev 6141)
@@ -21,8 +21,11 @@
*/
package org.jbpm.jpdl.internal.activity;
+import javax.el.MethodExpression;
+import javax.el.ValueExpression;
+
import org.jbpm.api.model.OpenExecution;
-import org.jbpm.pvm.internal.script.ScriptManager;
+import org.jbpm.pvm.internal.model.ExecutionImpl;
import org.jbpm.pvm.internal.wire.Descriptor;
import org.jbpm.pvm.internal.wire.WireContext;
@@ -34,35 +37,49 @@
private static final long serialVersionUID = 1L;
- protected String expression;
- protected String language;
- protected String variableName;
- protected Descriptor valueDescriptor;
+ protected ValueExpression fromValueExpression;
+ protected MethodExpression fromMethodExpression;
+ protected Descriptor fromValueDescriptor;
+ protected String toVariableName;
+ protected ValueExpression toValueExpression;
+
void perform(OpenExecution execution) throws Exception {
Object value = null;
- if (expression!=null) {
- ScriptManager scriptManager = ScriptManager.getScriptManager();
- value = scriptManager.evaluateExpression(expression, language);
+ if (fromValueExpression!=null) {
+ ExecutionImpl executionImpl = (ExecutionImpl) execution;
+ value = executionImpl.resolveElValueExpressionGet(fromValueExpression);
- } else if (valueDescriptor!=null) {
- value = WireContext.create(valueDescriptor);
+ } else if (fromMethodExpression!=null) {
+ ExecutionImpl executionImpl = (ExecutionImpl) execution;
+ value = executionImpl.resolveElMethodExpressionInvoke(fromMethodExpression);
+
+ } else if (fromValueDescriptor!=null) {
+ value = WireContext.create(fromValueDescriptor);
}
- execution.setVariable(variableName, value);
+ if (toVariableName!=null) {
+ execution.setVariable(toVariableName, value);
+ } else {
+ ExecutionImpl executionImpl = (ExecutionImpl) execution;
+ executionImpl.resolveElValueExpressionSet(toValueExpression, value);
+ }
}
- public void setExpression(String expression) {
- this.expression = expression;
+ public void setFromValueExpression(ValueExpression fromValueExpression) {
+ this.fromValueExpression = fromValueExpression;
}
- public void setLanguage(String language) {
- this.language = language;
+ public void setFromMethodExpression(MethodExpression methodExpression) {
+ this.fromMethodExpression = methodExpression;
}
- public void setVariableName(String variableName) {
- this.variableName = variableName;
+ public void setToVariableName(String variableName) {
+ this.toVariableName = variableName;
}
- public void setValueDescriptor(Descriptor valueDescriptor) {
- this.valueDescriptor = valueDescriptor;
+ public void setToValueExpression(ValueExpression toValueExpression) {
+ this.toValueExpression = toValueExpression;
}
+ public void setFromValueDescriptor(Descriptor valueDescriptor) {
+ this.fromValueDescriptor = valueDescriptor;
+ }
}
Modified: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/AssignBinding.java
===================================================================
--- jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/AssignBinding.java 2010-01-27 13:52:27 UTC (rev 6140)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/AssignBinding.java 2010-01-27 15:37:12 UTC (rev 6141)
@@ -24,6 +24,10 @@
import java.util.List;
import java.util.Set;
+import javax.el.ELException;
+import javax.el.MethodExpression;
+import javax.el.ValueExpression;
+
import org.jbpm.jpdl.internal.xml.JpdlParser;
import org.jbpm.pvm.internal.util.XmlUtil;
import org.jbpm.pvm.internal.wire.Descriptor;
@@ -36,7 +40,7 @@
* @author Tom Baeyens
*/
public class AssignBinding extends JpdlBinding {
-
+
public AssignBinding() {
super("assign");
}
@@ -44,16 +48,42 @@
public Object parseJpdl(Element element, Parse parse, JpdlParser parser) {
AssignActivity assignActivity = new AssignActivity();
- String variableName = XmlUtil.attribute(element, "var", true, parse);
- assignActivity.setVariableName(variableName);
+ String toVar = XmlUtil.attribute(element, "to-var");
+ String toExpr = XmlUtil.attribute(element, "to-expr");
+ if (toVar!=null) {
+ assignActivity.setToVariableName(toVar);
+ } else if (toExpr!=null) {
+ ValueExpression valueExpression = parser.createValueExpression(toExpr);
+ assignActivity.setToValueExpression(valueExpression);
+ }
- String expression = XmlUtil.attribute(element, "expr");
- if (expression!=null) {
- assignActivity.setExpression(expression);
- assignActivity.setLanguage(XmlUtil.attribute(element, "lang"));
+ String exprText = XmlUtil.attribute(element, "expr");
+ String exprType = XmlUtil.attribute(element, "expr-type");
- } else {
-
+ // if there is an expr specified
+ if (exprText!=null) {
+ // by default, expr is interpreted as a value expression
+ if (exprType==null || "value".equals(exprType)) {
+ try {
+ ValueExpression valueExpression = parser.createValueExpression(exprText);
+ assignActivity.setFromValueExpression(valueExpression);
+
+ // if the expr is not a valid value expr...
+ } catch (ELException e) {
+ // ... and the expr-type was not specified
+ if (exprType==null) {
+ // then try to parse it as a method expression
+ exprType = "method";
+ }
+ }
+ }
+
+ if ("method".equals(exprType)) {
+ MethodExpression methodExpression = parser.createMethodExpression(exprText);
+ assignActivity.setFromMethodExpression(methodExpression);
+ }
+
+ } else { // there is no expr specified
Set<String> descriptorTagNames = JpdlParser.wireParser.getBindings().getTagNames(WireParser.CATEGORY_DESCRIPTOR);
Descriptor valueDescriptor = null;
List<Element> assignContentElements = XmlUtil.elements(element);
@@ -62,11 +92,15 @@
Element assignContentElement = assignContentElements.get(i);
String assignContentElementTagName = XmlUtil.getTagLocalName(assignContentElement);
if (descriptorTagNames.contains(assignContentElementTagName)) {
- valueDescriptor = parser.parseDescriptor(element, parse);
+ valueDescriptor = parser.parseDescriptor(assignContentElement, parse);
}
}
-
- assignActivity.setValueDescriptor(valueDescriptor);
+
+ if (valueDescriptor!=null) {
+ assignActivity.setFromValueDescriptor(valueDescriptor);
+ } else {
+ parse.addProblem("no value for assignment specified. 'assign' must have attribute 'expr' or a wire object element.", element);
+ }
}
return assignActivity;
Modified: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/xml/JpdlParser.java
===================================================================
--- jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/xml/JpdlParser.java 2010-01-27 13:52:27 UTC (rev 6140)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/xml/JpdlParser.java 2010-01-27 15:37:12 UTC (rev 6141)
@@ -31,6 +31,11 @@
import java.util.Set;
import java.util.StringTokenizer;
+import javax.el.ELContext;
+import javax.el.ExpressionFactory;
+import javax.el.MethodExpression;
+import javax.el.ValueExpression;
+
import org.jbpm.api.JbpmException;
import org.jbpm.api.activity.ActivityBehaviour;
import org.jbpm.api.listener.EventListener;
@@ -39,6 +44,7 @@
import org.jbpm.jpdl.internal.activity.JpdlBinding;
import org.jbpm.jpdl.internal.activity.MailListener;
import org.jbpm.jpdl.internal.model.JpdlProcessDefinition;
+import org.jbpm.pvm.internal.el.JbpmElFactory;
import org.jbpm.pvm.internal.email.impl.MailProducerImpl;
import org.jbpm.pvm.internal.email.impl.MailTemplate;
import org.jbpm.pvm.internal.email.impl.MailTemplateRegistry;
@@ -113,6 +119,9 @@
public static final String CATEGORY_ACTIVITY = "activity";
public static final String CATEGORY_EVENT_LISTENER = "eventlistener";
+ protected ExpressionFactory expressionFactory;
+ protected ELContext elContext;
+
public JpdlParser() {
initialize();
parseBindings();
@@ -732,4 +741,22 @@
public Set<String> getActivityTagNames() {
return getBindings().getTagNames(CATEGORY_ACTIVITY);
}
+
+ public ValueExpression createValueExpression(String expressionText) {
+ initializeExpressionLanguageParsing();
+ return expressionFactory.createValueExpression(elContext, expressionText, Object.class);
+ }
+
+ public MethodExpression createMethodExpression(String expressionText) {
+ initializeExpressionLanguageParsing();
+ return expressionFactory.createMethodExpression(elContext, expressionText, null, new Class<?>[]{});
+ }
+
+ protected void initializeExpressionLanguageParsing() {
+ if (elContext==null) {
+ JbpmElFactory jbpmElFactory = JbpmElFactory.getJbpmElFactory();
+ expressionFactory = jbpmElFactory.createExpressionFactory();
+ elContext = jbpmElFactory.createElContext();
+ }
+ }
}
Modified: jbpm4/trunk/modules/pvm/pom.xml
===================================================================
--- jbpm4/trunk/modules/pvm/pom.xml 2010-01-27 13:52:27 UTC (rev 6140)
+++ jbpm4/trunk/modules/pvm/pom.xml 2010-01-27 15:37:12 UTC (rev 6141)
@@ -65,10 +65,6 @@
</dependency>
<dependency>
<groupId>juel</groupId>
- <artifactId>juel-impl</artifactId>
- </dependency>
- <dependency>
- <groupId>juel</groupId>
<artifactId>juel-engine</artifactId>
</dependency>
<dependency>
Deleted: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElContextFactory.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElContextFactory.java 2010-01-27 13:52:27 UTC (rev 6140)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElContextFactory.java 2010-01-27 15:37:12 UTC (rev 6141)
@@ -1,35 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jbpm.pvm.internal.el;
-
-import javax.el.ELContext;
-
-import org.jbpm.pvm.internal.model.ScopeInstanceImpl;
-
-/**
- * @author Tom Baeyens
- */
-public interface JbpmElContextFactory {
-
- ELContext createElContext();
- ELContext createElContext(ScopeInstanceImpl scopeInstance);
-}
\ No newline at end of file
Deleted: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElContextFactoryImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElContextFactoryImpl.java 2010-01-27 13:52:27 UTC (rev 6140)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElContextFactoryImpl.java 2010-01-27 15:37:12 UTC (rev 6141)
@@ -1,113 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jbpm.pvm.internal.el;
-
-import javax.el.ArrayELResolver;
-import javax.el.BeanELResolver;
-import javax.el.CompositeELResolver;
-import javax.el.ELContext;
-import javax.el.ELResolver;
-import javax.el.FunctionMapper;
-import javax.el.ListELResolver;
-import javax.el.MapELResolver;
-import javax.enterprise.inject.spi.BeanManager;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-
-import org.jbpm.internal.log.Log;
-import org.jbpm.pvm.internal.env.EnvironmentImpl;
-import org.jbpm.pvm.internal.model.ScopeInstanceImpl;
-
-
-/**
- * @author Tom Baeyens
- */
-public class JbpmElContextFactoryImpl implements JbpmElContextFactory {
-
- private static Log log = Log.getLog(JbpmElContextFactoryImpl.class.getName());
-
- Class<?> functionClass = JstlFunction.class;
-
- /** create ElContext used during parsing time */
- public ELContext createElContext() {
- return createCompositeResolver(null);
- }
-
- /** create ElContext used during evaluation time related to an execution */
- public ELContext createElContext(ScopeInstanceImpl scopeInstance) {
- return createCompositeResolver(scopeInstance);
- }
-
- protected ELContext createCompositeResolver(ScopeInstanceImpl scopeInstance) {
- CompositeELResolver compositeELResolver = new CompositeELResolver();
-
- if (scopeInstance!=null) {
- compositeELResolver.add(new JbpmConstantsElResolver(scopeInstance));
- compositeELResolver.add(new JbpmVariableElResolver(scopeInstance));
- }
-
- EnvironmentImpl environment = EnvironmentImpl.getCurrent();
- if (environment!=null) {
- compositeELResolver.add(new JbpmEnvironmentElResolver(environment));
- }
-
- addCdiResolver(compositeELResolver);
-
- addBasicResolvers(compositeELResolver);
-
- FunctionMapper functionMapper = createFunctionMapper();
-
- return createElContext(compositeELResolver, functionMapper);
- }
-
- protected void addCdiResolver(CompositeELResolver compositeELResolver) {
- try {
- InitialContext initialContext = new InitialContext();
- Object object = initialContext.lookup("java:comp/BeanManager");
- if (object!=null) {
- BeanManager beanManager = (BeanManager) object;
- ELResolver cdiResolver = beanManager.getELResolver();
- if (cdiResolver!=null) {
- compositeELResolver.add(cdiResolver);
- log.debug("added cdi el resolver");
- }
- }
- } catch (NamingException e) {
- log.debug("no cdi bean manager available in jndi");
- }
- }
-
- protected void addBasicResolvers(CompositeELResolver compositeELResolver) {
- compositeELResolver.add(new BeanELResolver());
- compositeELResolver.add(new MapELResolver());
- compositeELResolver.add(new ListELResolver());
- compositeELResolver.add(new ArrayELResolver());
- }
-
- protected FunctionMapper createFunctionMapper() {
- return new JbpmFunctionMapper(functionClass);
- }
-
- protected JbpmElContext createElContext(CompositeELResolver compositeELResolver, FunctionMapper functionMapper) {
- return new JbpmElContext(compositeELResolver, functionMapper);
- }
-}
Copied: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElFactory.java (from rev 6133, jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElContextFactory.java)
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElFactory.java (rev 0)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElFactory.java 2010-01-27 15:37:12 UTC (rev 6141)
@@ -0,0 +1,46 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.pvm.internal.el;
+
+import javax.el.ELContext;
+import javax.el.ExpressionFactory;
+
+import org.jbpm.pvm.internal.env.EnvironmentImpl;
+import org.jbpm.pvm.internal.model.ScopeInstanceImpl;
+
+/**
+ * @author Tom Baeyens
+ */
+public abstract class JbpmElFactory {
+
+ public static JbpmElFactory getJbpmElFactory() {
+ JbpmElFactory contextFactory = EnvironmentImpl.getFromCurrent(JbpmElFactory.class, false);
+ if (contextFactory==null) {
+ contextFactory = new JbpmElFactoryImpl();
+ }
+ return contextFactory;
+ }
+
+ public abstract ELContext createElContext();
+ public abstract ELContext createElContext(ScopeInstanceImpl scopeInstance);
+ public abstract ExpressionFactory createExpressionFactory();
+}
\ No newline at end of file
Property changes on: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElFactory.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Copied: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElFactoryImpl.java (from rev 6133, jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElContextFactoryImpl.java)
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElFactoryImpl.java (rev 0)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElFactoryImpl.java 2010-01-27 15:37:12 UTC (rev 6141)
@@ -0,0 +1,135 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.pvm.internal.el;
+
+import java.util.Properties;
+
+import javax.el.ArrayELResolver;
+import javax.el.BeanELResolver;
+import javax.el.CompositeELResolver;
+import javax.el.ELContext;
+import javax.el.ELResolver;
+import javax.el.ExpressionFactory;
+import javax.el.FunctionMapper;
+import javax.el.ListELResolver;
+import javax.el.MapELResolver;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.jbpm.internal.log.Log;
+import org.jbpm.pvm.internal.env.EnvironmentImpl;
+import org.jbpm.pvm.internal.model.ScopeInstanceImpl;
+
+
+/**
+ * @author Tom Baeyens
+ */
+public class JbpmElFactoryImpl extends JbpmElFactory {
+
+ private static Log log = Log.getLog(JbpmElFactoryImpl.class.getName());
+
+ Class<?> functionClass = JstlFunction.class;
+
+ /** create ElContext used during parsing time */
+ public ELContext createElContext() {
+ return createCompositeResolver(null);
+ }
+
+ /** create ElContext used during evaluation time related to an execution */
+ public ELContext createElContext(ScopeInstanceImpl scopeInstance) {
+ return createCompositeResolver(scopeInstance);
+ }
+
+ protected ELContext createCompositeResolver(ScopeInstanceImpl scopeInstance) {
+ CompositeELResolver compositeELResolver = new CompositeELResolver();
+
+ if (scopeInstance!=null) {
+ compositeELResolver.add(new JbpmConstantsElResolver(scopeInstance));
+ compositeELResolver.add(new JbpmVariableElResolver(scopeInstance));
+ }
+
+ EnvironmentImpl environment = EnvironmentImpl.getCurrent();
+ if (environment!=null) {
+ compositeELResolver.add(new JbpmEnvironmentElResolver(environment));
+ }
+
+ addCdiResolver(compositeELResolver);
+
+ addBasicResolvers(compositeELResolver);
+
+ FunctionMapper functionMapper = createFunctionMapper();
+
+ return createElContext(compositeELResolver, functionMapper);
+ }
+
+ protected void addCdiResolver(CompositeELResolver compositeELResolver) {
+ BeanManager beanManager = getBeanManager();
+ if (beanManager!=null) {
+ ELResolver cdiResolver = beanManager.getELResolver();
+ if (cdiResolver!=null) {
+ compositeELResolver.add(cdiResolver);
+ log.debug("added cdi el resolver");
+ }
+ } else {
+ log.debug("no cdi bean manager available in jndi");
+ }
+ }
+
+ protected BeanManager getBeanManager() {
+ try {
+ InitialContext initialContext = new InitialContext();
+ return (BeanManager) initialContext.lookup("java:comp/BeanManager");
+ } catch (NamingException e) {
+ return null;
+ }
+ }
+
+ public ExpressionFactory createExpressionFactory() {
+ // TODO these ExpressionFactory properties could be integrated in the configuration
+ Properties properties = new Properties();
+ properties.setProperty("javax.el.methodInvocations", "true");
+ ExpressionFactory expressionFactory = ExpressionFactory.newInstance(properties);
+
+ BeanManager beanManager = getBeanManager();
+ if (beanManager!=null) {
+ expressionFactory = beanManager.wrapExpressionFactory(expressionFactory);
+ }
+
+ return expressionFactory;
+ }
+
+ protected void addBasicResolvers(CompositeELResolver compositeELResolver) {
+ compositeELResolver.add(new BeanELResolver());
+ compositeELResolver.add(new MapELResolver());
+ compositeELResolver.add(new ListELResolver());
+ compositeELResolver.add(new ArrayELResolver());
+ }
+
+ protected FunctionMapper createFunctionMapper() {
+ return new JbpmFunctionMapper(functionClass);
+ }
+
+ protected JbpmElContext createElContext(CompositeELResolver compositeELResolver, FunctionMapper functionMapper) {
+ return new JbpmElContext(compositeELResolver, functionMapper);
+ }
+}
Property changes on: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElFactoryImpl.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java 2010-01-27 13:52:27 UTC (rev 6140)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java 2010-01-27 15:37:12 UTC (rev 6141)
@@ -21,6 +21,7 @@
*/
package org.jbpm.pvm.internal.model;
+import java.io.PrintWriter;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
@@ -54,8 +55,8 @@
import org.jbpm.internal.log.Log;
import org.jbpm.pvm.internal.client.ClientProcessDefinition;
import org.jbpm.pvm.internal.client.ClientProcessInstance;
-import org.jbpm.pvm.internal.el.JbpmElContextFactory;
-import org.jbpm.pvm.internal.el.JbpmElContextFactoryImpl;
+import org.jbpm.pvm.internal.el.JbpmElFactory;
+import org.jbpm.pvm.internal.el.JbpmElFactoryImpl;
import org.jbpm.pvm.internal.env.Context;
import org.jbpm.pvm.internal.env.EnvironmentImpl;
import org.jbpm.pvm.internal.env.ExecutionContext;
@@ -86,6 +87,8 @@
import org.jbpm.pvm.internal.util.Priority;
import org.jbpm.pvm.internal.wire.usercode.UserCodeReference;
+import de.odysseus.el.TreeValueExpression;
+
/**
* @author Tom Baeyens
*/
@@ -689,22 +692,20 @@
public void resolveElValueExpressionSet(ValueExpression valueExpression, Object value) {
initCachedElContext();
+
+ log.debug("expression: "+valueExpression);
+
valueExpression.setValue((ELContext) cachedElContext, value);
}
- public void resolveElMethodExpressionInvoke(MethodExpression methodExpression) {
+ public Object resolveElMethodExpressionInvoke(MethodExpression methodExpression) {
initCachedElContext();
- Object[] params = new Object[]{};
- // TODO figure out how to resolve the params
- methodExpression.invoke((ELContext) cachedElContext, params);
+ return methodExpression.invoke((ELContext) cachedElContext, null);
}
protected void initCachedElContext() {
if (cachedElContext==null) {
- JbpmElContextFactory contextFactory = EnvironmentImpl.getFromCurrent(JbpmElContextFactory.class, false);
- if (contextFactory==null) {
- contextFactory = new JbpmElContextFactoryImpl();
- }
+ JbpmElFactory contextFactory = JbpmElFactory.getJbpmElFactory();
cachedElContext = contextFactory.createElContext(this);
}
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/AbstractTransaction.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/AbstractTransaction.java 2010-01-27 13:52:27 UTC (rev 6140)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/AbstractTransaction.java 2010-01-27 15:37:12 UTC (rev 6141)
@@ -36,9 +36,18 @@
if (deserializedObjects==null) {
deserializedObjects = new ArrayList<DeserializedObject>();
}
+
+ // if this object was registered before...
+ for (DeserializedObject registeredObject: deserializedObjects) {
+ if (registeredObject.deserializedObject==deserializedObject.deserializedObject) {
+ // ...don't add it to deserializedObjects collection
+ return;
+ }
+ }
+
deserializedObjects.add(deserializedObject);
}
-
+
public void flushDeserializedObjects() {
if (deserializedObjects!=null) {
for (DeserializedObject deserializedObject: deserializedObjects) {
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/type/converter/SerializableToBytesConverter.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/type/converter/SerializableToBytesConverter.java 2010-01-27 13:52:27 UTC (rev 6140)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/type/converter/SerializableToBytesConverter.java 2010-01-27 15:37:12 UTC (rev 6141)
@@ -54,6 +54,12 @@
oos.writeObject(o);
oos.flush();
bytes = baos.toByteArray();
+
+ Transaction transaction = EnvironmentImpl.getFromCurrent(Transaction.class, false);
+ if (transaction!=null) {
+ transaction.registerDeserializedObject(new DeserializedObject(o, scopeInstance, (BlobVariable) variable));
+ }
+
} catch (IOException e) {
throw new JbpmException("couldn't serialize '"+o+"'", e);
}
Modified: jbpm4/trunk/modules/pvm/src/main/resources/jbpm.default.cfg.xml
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/resources/jbpm.default.cfg.xml 2010-01-27 13:52:27 UTC (rev 6140)
+++ jbpm4/trunk/modules/pvm/src/main/resources/jbpm.default.cfg.xml 2010-01-27 15:37:12 UTC (rev 6141)
@@ -19,6 +19,8 @@
</object>
<object class="org.jbpm.pvm.internal.id.DatabaseIdComposer" init="eager" />
+
+ <object class="org.jbpm.pvm.internal.el.JbpmElFactoryImpl" />
<types resource="jbpm.variable.types.xml" />
Added: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/assign/Address.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/assign/Address.java (rev 0)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/assign/Address.java 2010-01-27 15:37:12 UTC (rev 6141)
@@ -0,0 +1,61 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.test.activity.assign;
+
+import java.io.Serializable;
+
+
+/**
+ * @author Tom Baeyens
+ */
+public class Address implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ String street;
+ String city;
+ String country;
+
+ public String getStreet() {
+ return street;
+ }
+
+ public void setStreet(String street) {
+ this.street = street;
+ }
+
+ public String getCity() {
+ return city;
+ }
+
+ public void setCity(String city) {
+ this.city = city;
+ }
+
+ public String getCountry() {
+ return country;
+ }
+
+ public void setCountry(String country) {
+ this.country = country;
+ }
+}
Property changes on: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/assign/Address.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/assign/AssignTest.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/assign/AssignTest.java (rev 0)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/assign/AssignTest.java 2010-01-27 15:37:12 UTC (rev 6141)
@@ -0,0 +1,133 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.test.activity.assign;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jbpm.api.ProcessInstance;
+import org.jbpm.test.JbpmTestCase;
+
+
+/**
+ * @author Tom Baeyens
+ */
+public class AssignTest extends JbpmTestCase {
+
+ public void testValueExpressionToVar() {
+ deployJpdlXmlString(
+ "<process name='AssignTest'>" +
+ " <start>" +
+ " <transition to='resolve' />" +
+ " </start>" +
+ " <assign name='resolve' expr='#{person.name}' to-var='result'>" +
+ " <transition to='wait' />" +
+ " </assign>" +
+ " <state name='wait' />" +
+ "</process>"
+ );
+
+ Person person = new Person();
+ person.setName("johndoe");
+
+ Map<String, Object> variables = new HashMap<String, Object>();
+ variables.put("person", person);
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("AssignTest", variables);
+ executionService.signalExecutionById(processInstance.getId());
+
+ assertEquals("johndoe", executionService.getVariable(processInstance.getId(), "result"));
+ }
+
+ public void testMethodExpressionToVar() {
+ deployJpdlXmlString(
+ "<process name='AssignTest'>" +
+ " <start>" +
+ " <transition to='resolve' />" +
+ " </start>" +
+ " <assign name='resolve' expr='#{person.hello()}' to-var='result'>" +
+ " <transition to='wait' />" +
+ " </assign>" +
+ " <state name='wait' />" +
+ "</process>"
+ );
+
+ Person person = new Person();
+ person.setName("johndoe");
+
+ Map<String, Object> variables = new HashMap<String, Object>();
+ variables.put("person", person);
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("AssignTest", variables);
+ executionService.signalExecutionById(processInstance.getId());
+
+ assertEquals("goodby", executionService.getVariable(processInstance.getId(), "result"));
+ }
+
+ public void testMethodWithParameterExpressionToVar() {
+ deployJpdlXmlString(
+ "<process name='AssignTest'>" +
+ " <start>" +
+ " <transition to='resolve' />" +
+ " </start>" +
+ " <assign name='resolve' expr=\"#{person.hello('Joe')}\" to-var='result'>" +
+ " <transition to='wait' />" +
+ " </assign>" +
+ " <state name='wait' />" +
+ "</process>"
+ );
+
+ Person person = new Person();
+ person.setName("johndoe");
+
+ Map<String, Object> variables = new HashMap<String, Object>();
+ variables.put("person", person);
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("AssignTest", variables);
+ executionService.signalExecutionById(processInstance.getId());
+
+ assertEquals("Hi, Joe", executionService.getVariable(processInstance.getId(), "result"));
+ }
+
+ public void testWireObjectToExpression() {
+ deployJpdlXmlString(
+ "<process name='AssignTest'>" +
+ " <start>" +
+ " <transition to='resolve' />" +
+ " </start>" +
+ " <assign name='resolve' to-expr='#{person.address.street}'>" +
+ " <string value='gasthuisstraat' />" +
+ " <transition to='wait' />" +
+ " </assign>" +
+ " <state name='wait' />" +
+ "</process>"
+ );
+
+ Person person = new Person();
+ person.setName("johndoe");
+
+ Map<String, Object> variables = new HashMap<String, Object>();
+ variables.put("person", person);
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("AssignTest", variables);
+ executionService.signalExecutionById(processInstance.getId());
+
+ person = (Person) executionService.getVariable(processInstance.getId(), "person");
+ assertEquals("gasthuisstraat", person.getAddress().getStreet());
+ }
+}
Property changes on: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/assign/AssignTest.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/assign/Person.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/assign/Person.java (rev 0)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/assign/Person.java 2010-01-27 15:37:12 UTC (rev 6141)
@@ -0,0 +1,69 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.test.activity.assign;
+
+import java.io.Serializable;
+
+
+/**
+ * @author Tom Baeyens
+ */
+public class Person implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ String name;
+ Address address = new Address();
+ String[] emails;
+
+ public String hello() {
+ return "goodby";
+ }
+
+ public String hello(String name) {
+ return "Hi, "+name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Address getAddress() {
+ return address;
+ }
+
+ public void setAddress(Address address) {
+ this.address = address;
+ }
+
+ public String[] getEmails() {
+ return emails;
+ }
+
+ public void setEmails(String[] emails) {
+ this.emails = emails;
+ }
+}
Property changes on: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/assign/Person.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: jbpm4/trunk/pom.xml
===================================================================
--- jbpm4/trunk/pom.xml 2010-01-27 13:52:27 UTC (rev 6140)
+++ jbpm4/trunk/pom.xml 2010-01-27 15:37:12 UTC (rev 6141)
@@ -62,7 +62,8 @@
<jboss.j2ee.version>4.2.2.GA</jboss.j2ee.version>
<jboss.client.version>5.0.1.GA</jboss.client.version>
<jsr233.version>2.0.5</jsr233.version>
- <juel.version>2.1.0</juel.version>
+ <juel.version>2.2.1</juel.version>
+ <juel.engine.version>2.1.0</juel.engine.version>
<junit.version>3.8.2</junit.version>
<log4j.version>1.2.14</log4j.version>
<mail.version>1.4.1</mail.version>
@@ -238,14 +239,13 @@
<version>${juel.version}</version>
</dependency>
<dependency>
+ <!-- The juel engine is the library from scripting.java.sun.com that exposes juel as a jsr233 scripting engine.
+ It's not part of the juel distribution. For some reason i don't recall, we uploaded it as
+ an juel-engine artifact in the group juel. And more problematic, used the juel version (2.1.0) for it.
+ That is not intuitive. -->
<groupId>juel</groupId>
- <artifactId>juel-impl</artifactId>
- <version>${juel.version}</version>
- </dependency>
- <dependency>
- <groupId>juel</groupId>
<artifactId>juel-engine</artifactId>
- <version>${juel.version}</version>
+ <version>${juel.engine.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
14 years, 3 months
JBoss JBPM SVN: r6139 - in jbpm4/trunk/modules/examples/src/test: java/org/jbpm/examples/bpmn/sequenceflow and 2 other directories.
by do-not-reply@jboss.org
Author: jbarrez
Date: 2010-01-27 07:50:20 -0500 (Wed, 27 Jan 2010)
New Revision: 6139
Added:
jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/bpmn/sequenceflow/
jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/bpmn/sequenceflow/ConditionalSequenceflowTest.java
jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/bpmn/sequenceflow/
jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/bpmn/sequenceflow/conditional_sequence_flow.bpmn.xml
Log:
Examples conditional sequence flow
Added: jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/bpmn/sequenceflow/ConditionalSequenceflowTest.java
===================================================================
--- jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/bpmn/sequenceflow/ConditionalSequenceflowTest.java (rev 0)
+++ jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/bpmn/sequenceflow/ConditionalSequenceflowTest.java 2010-01-27 12:50:20 UTC (rev 6139)
@@ -0,0 +1,97 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.examples.bpmn.sequenceflow;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.jbpm.api.NewDeployment;
+import org.jbpm.api.ProcessInstance;
+import org.jbpm.api.TaskQuery;
+import org.jbpm.api.task.Task;
+import org.jbpm.test.JbpmTestCase;
+
+/**
+ * @author Joram Barrez
+ */
+public class ConditionalSequenceflowTest extends JbpmTestCase {
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ NewDeployment deployment = repositoryService.createDeployment();
+ deployment.addResourceFromClasspath("org/jbpm/examples/bpmn/sequenceflow/conditional_sequence_flow.bpmn.xml");
+ registerDeployment(deployment.deploy());
+ }
+
+ public void testBothSequenceflowTaken() {
+ Map<String, Object> vars = new HashMap<String, Object>();
+ vars.put("var", 250);
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("conditionalSequenceFlow", vars);
+
+ TaskQuery taskQuery = taskService.createTaskQuery()
+ .processInstanceId(processInstance.getId())
+ .orderAsc(TaskQuery.PROPERTY_NAME);
+ Task task = taskQuery.uniqueResult();
+ assertEquals("First task", task.getName());
+ taskService.completeTask(task.getId());
+
+ List<Task> tasks = taskQuery.list();
+ assertEquals(2, tasks.size());
+ assertEquals("Second task", tasks.get(0).getName());
+ assertEquals("Third task", tasks.get(1).getName());
+ }
+
+ public void testOnlyOneSequenceFlow() {
+ Map<String, Object> vars = new HashMap<String, Object>();
+ vars.put("var", 25);
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("conditionalSequenceFlow", vars);
+
+ TaskQuery taskQuery = taskService.createTaskQuery()
+ .processInstanceId(processInstance.getId());
+ Task task = taskQuery.uniqueResult();
+ assertEquals("First task", task.getName());
+ taskService.completeTask(task.getId());
+
+ task = taskQuery.uniqueResult();
+ assertEquals("Second task", task.getName());
+ }
+
+ public void testDefaultSequenceFlow() {
+ Map<String, Object> vars = new HashMap<String, Object>();
+ vars.put("var", 2);
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("conditionalSequenceFlow", vars);
+
+ TaskQuery taskQuery = taskService.createTaskQuery()
+ .processInstanceId(processInstance.getId());
+ Task task = taskQuery.uniqueResult();
+ assertEquals("First task", task.getName());
+ taskService.completeTask(task.getId());
+
+ task = taskQuery.uniqueResult();
+ assertNotNull(task);
+ assertEquals("Fourth task", task.getName());
+ }
+
+
+}
Added: jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/bpmn/sequenceflow/conditional_sequence_flow.bpmn.xml
===================================================================
--- jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/bpmn/sequenceflow/conditional_sequence_flow.bpmn.xml (rev 0)
+++ jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/bpmn/sequenceflow/conditional_sequence_flow.bpmn.xml 2010-01-27 12:50:20 UTC (rev 6139)
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definitions id="vacationRequest"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://schema.omg.org/spec/BPMN/2.0 ../../../../../../../../../../bpmn/src/main/resources/BPMN20.xsd"
+ xmlns="http://schema.omg.org/spec/BPMN/2.0" typeLanguage="http://www.w3.org/2001/XMLSchema"
+ expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://jbpm.org/example/bpmn2/conditional_sequence_flow"
+ xmlns:jbpm="http://jbpm.org/bpmn2">
+
+ <process id="conditionalSequenceFlow">
+
+ <startEvent id="start" />
+
+ <sequenceFlow id="flow1" sourceRef="start" targetRef="task1" />
+
+ <userTask id="task1" default="flow4" name="First task" />
+
+ <sequenceFlow id='flow2' sourceRef='task1' targetRef='task2' >" +
+ <conditionExpression xsi:type='tFormalExpression'>${var > 10}</conditionExpression>
+ </sequenceFlow>
+
+ <sequenceFlow id='flow3' sourceRef='task1' targetRef='task3' >" +
+ <conditionExpression xsi:type='tFormalExpression'>${var > 100}</conditionExpression>
+ </sequenceFlow>
+
+ <sequenceFlow id="flow4" sourceRef="task1" targetRef="task4" />
+
+ <userTask id="task2" name="Second task" />
+
+ <sequenceFlow id="flow5" sourceRef="task2" targetRef="theEnd" />
+
+ <userTask id="task3" name="Third task" />
+
+ <sequenceFlow id="flow5" sourceRef="task2" targetRef="theEnd" />
+
+ <userTask id="task4" name="Fourth task" />
+
+ <sequenceFlow id="flow5" sourceRef="task2" targetRef="theEnd" />
+
+ <endEvent id="theEnd" name="End" />
+
+
+ </process>
+</definitions>
14 years, 3 months
JBoss JBPM SVN: r6138 - in jbpm4/trunk/modules: devguide/src/main/docbook/en/images and 12 other directories.
by do-not-reply@jboss.org
Author: jbarrez
Date: 2010-01-27 07:03:08 -0500 (Wed, 27 Jan 2010)
New Revision: 6138
Added:
jbpm4/trunk/modules/devguide/src/main/docbook/en/images/bpmn2.timer.start.event.png
jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/bpmn/event/timerstart/
jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/bpmn/event/timerstart/TimerStartTest.java
jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/bpmn/event/timerstart/
jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/bpmn/event/timerstart/timer_start_event.bpmn.xml
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/StartProcessTimer.java
Removed:
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/PeriodicStartProcessTimer.java
Modified:
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/StartEventBinding.java
jbpm4/trunk/modules/devguide/src/main/docbook/en/modules/ch03-Bpmn2.xml
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cal/Duration.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/hibernate/DbSessionImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/repository/RepositorySessionImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/session/DbSession.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/session/RepositorySession.java
jbpm4/trunk/modules/pvm/src/main/resources/jbpm.execution.hbm.xml
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/startevent/TimerStartEventTest.java
Log:
JBPM-2722: completed implementation of timer start event
Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/StartEventBinding.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/StartEventBinding.java 2010-01-27 07:59:50 UTC (rev 6137)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/StartEventBinding.java 2010-01-27 12:03:08 UTC (rev 6138)
@@ -21,11 +21,16 @@
*/
package org.jbpm.bpmn.flownodes;
+import java.util.List;
+
import org.jbpm.bpmn.model.BpmnProcessDefinition;
import org.jbpm.bpmn.parser.BpmnParser;
-import org.jbpm.pvm.internal.job.PeriodicStartProcessTimer;
+import org.jbpm.internal.log.Log;
+import org.jbpm.pvm.internal.env.EnvironmentImpl;
+import org.jbpm.pvm.internal.job.StartProcessTimer;
import org.jbpm.pvm.internal.model.ActivityImpl;
import org.jbpm.pvm.internal.model.TimerDefinitionImpl;
+import org.jbpm.pvm.internal.session.DbSession;
import org.jbpm.pvm.internal.util.XmlUtil;
import org.jbpm.pvm.internal.xml.Parse;
import org.jbpm.pvm.internal.xml.Parser;
@@ -34,6 +39,8 @@
public class StartEventBinding extends BpmnBinding {
+
+ private static final Log LOG = Log.getLog(StartEventBinding.class.getName());
public StartEventBinding() {
super("startEvent");
@@ -61,6 +68,9 @@
return new NoneStartEventActivity(); // default
}
+ /**
+ * Timer start event
+ */
protected TimerStartEventActivity createTimerStartEvent(BpmnProcessDefinition processDefinition,
Element timerEventDefinition, String eventId, BpmnParser parser, Parse parse) {
@@ -71,7 +81,7 @@
return null;
}
- PeriodicStartProcessTimer startProcessTimer = new PeriodicStartProcessTimer();
+ StartProcessTimer startProcessTimer = new StartProcessTimer();
startProcessTimer.setProcessDefinitionName(processDefinition.getName());
if (timerDefinition.getDueDate() != null) {
@@ -82,8 +92,31 @@
startProcessTimer.setIntervalExpression(timerDefinition.getCronExpression());
}
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Scheduling a new start process timer for process definition "
+ + processDefinition.getName());
+ }
+
+ deleteStartProcessTimers(processDefinition.getName()); // Only the latest procDef should have a timer start
startProcessTimer.schedule();
return timerStartEvent;
}
+ /**
+ * Deletes all existing timer start events for a given process definition.
+ *
+ * This is required when a new version of a process definition with a timer start is deployed:
+ * only the latest may version may be started by the timer start event.
+ */
+ protected void deleteStartProcessTimers(String processDefinitionName) {
+ DbSession dbSession = EnvironmentImpl.getCurrent().get(DbSession.class);
+ List<StartProcessTimer> existingTimers = dbSession.findStartProcessTimers(processDefinitionName);
+ for (StartProcessTimer spt : existingTimers) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Removing existing start process timer: " + spt);
+ }
+ dbSession.delete(spt);
+ }
+ }
+
}
Added: jbpm4/trunk/modules/devguide/src/main/docbook/en/images/bpmn2.timer.start.event.png
===================================================================
(Binary files differ)
Property changes on: jbpm4/trunk/modules/devguide/src/main/docbook/en/images/bpmn2.timer.start.event.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Modified: jbpm4/trunk/modules/devguide/src/main/docbook/en/modules/ch03-Bpmn2.xml
===================================================================
--- jbpm4/trunk/modules/devguide/src/main/docbook/en/modules/ch03-Bpmn2.xml 2010-01-27 07:59:50 UTC (rev 6137)
+++ jbpm4/trunk/modules/devguide/src/main/docbook/en/modules/ch03-Bpmn2.xml 2010-01-27 12:03:08 UTC (rev 6138)
@@ -1219,6 +1219,124 @@
<title>Advanced constructs</title>
+ <section id="Timer start event">
+
+ <title>Timer start event</title>
+
+ <para>
+ A timer start event is used to indicate that a process should be started when a given
+ time condition is met. This could be a specific point in time (eg. October 10th, 2010 at
+ 5am), but also and more typically a recurring time (eg. every Friday at midnight).
+ </para>
+
+ <para>
+ A timer start event is visualized as a circle with the clock icon inside.
+ <mediaobject><imageobject><imagedata align="center" fileref="images/bpmn2.timer.start.event.png"/></imageobject></mediaobject>
+ </para>
+
+ <para>
+ Using a Timer Start event is done by adding a <emphasis role="bold">timerEventDefinition</emphasis>
+ element below the startEvent element:
+ <programlisting>
+<startEvent name="Every Monday morning" id="myStart">
+ <emphasis role="bold"><timerEventDefinition/></emphasis>
+</startEvent>
+ </programlisting>
+ Following time definitions are possible:
+ <itemizedlist>
+ <listitem>
+ <emphasis role="bold">timeDate: </emphasis>specifies a fixed date when a process instance
+ must be created. The default format of the date specification is
+ "dd/MM/yyyy hh:mm:ss". This can engine-wide be changed by setting the
+ <emphasis role="bold">jbpm.duedatetime.format</emphasis> property in the configuration.
+ <programlisting>
+<startEvent id="myStartEvent" >
+ <timerEventDefinition>
+ <emphasis role="bold"><timeDate>10/10/2099 00:00:00</timeDate></emphasis>
+ </timerEventDefinition>
+</startEvent>
+ </programlisting>
+ Note that using a fixed duedate makes the process only useable for a single time.
+ After the process instance is created, the timer start event will never fire again.
+ </listitem>
+ <listitem>
+ <emphasis role="bold">timeCycle: </emphasis>specifies the recurring time when a new
+ process instance will be created. Two types are possible
+
+ <para>
+ <emphasis role="bold">Duration expression: </emphasis>
+ <programlisting>
+quantity [business] {second | seconds | minute | minutes |
+ hour | hours | day | days | week |
+ weeks | month | months | year | years}
+ </programlisting>
+ This is completely similar to a timer duration definition in JPDL. Note that the
+ BPMN2 start timer event also understands "business time". This
+ allows for example to define a "business day" as an interval from
+ 9am to 5pm. This way, the time from 5pm to 9am will not be taken in account when
+ the time on which the event will fire is calculated.
+ Please refer to the JPDL userguide for more details on how this business calendar can be customized.
+ The following example shows a timer start event that will start a new process
+ instance every five hours.
+ <programlisting>
+<startEvent id="myStartEvent" >
+ <timerEventDefinition>
+ <emphasis role="bold"><timeCycle>5 hours</timeCycle></emphasis>
+ </timerEventDefinition>
+</startEvent>
+ </programlisting>
+ </para>
+ <para>
+ <emphasis role="bold"><ulink url="http://en.wikipedia.org/wiki/CRON_expression">Cron expression:</ulink></emphasis>
+ altough duration expressions cover already a great deal of recurring time definitions,
+ sometimes they are not easy to use.
+ When for example a process instance should be started every Friday night 23pm,
+ cron expressions allow a more natural way of defining such repeating occurrences.
+ </para>
+ <para>
+ The following example shows a timer start event that will start a new process
+ instance every Friday at 23pm.
+ <programlisting>
+<startEvent id="myStartEvent" >
+ <timerEventDefinition>
+ <emphasis role="bold"><timeCycle>0 0 23 ? * FRI</timeCycle></emphasis>
+</timerEventDefinition>
+</startEvent>
+ </programlisting>
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ The timer start event implementation in jBPM also has following features:
+ <itemizedlist>
+ <listitem>
+ Process definitions that have a timer start event, can be started as if it also
+ were a none start event. This means that calling for example
+ executionService.startProcessInstanceByKey(key) just works.
+ </listitem>
+ <listitem>
+ The timer start event is internally implemented as a scheduled job. This means
+ that a <emphasis role="bold">job executor</emphasis> has to be configured for
+ the timer start event to work. The advantage of this implementation is that the
+ timer start event firing is transactional (eg. if a service tasks right after the
+ timer start event fails, the transaction will be rolled back and the timer start event
+ will be retried later) and able to cope with a server crash (ie. the when the server
+ comes back up, the timer start event will be picked up by the job executor just as if
+ nothing has happened).
+ </listitem>
+ <listitem>
+ When a new version of a process definition with a timer start event is deployed, the
+ old timer start event job is removed from the system. This means that
+ <emphasis role="bold">only the latest version of the process definition will be used</emphasis>
+ to create a new process instances.
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ </section> <!-- end of Timer start event -->
+
<section id="intermediateEvents">
<title>Intermediate events</title>
@@ -1275,7 +1393,7 @@
</para>
<para>
- Following delay definitions are possible.
+ Following delay definitions are possible (similar to those for a Timer Start Event).
<itemizedlist>
<listitem>
<emphasis role="bold">timeDate: </emphasis>specifies a fixed date when the timer will
@@ -1292,7 +1410,7 @@
</listitem>
<listitem>
<emphasis role="bold">timeCycle: </emphasis>specifies a delay duration relative to the
- time when the execution enters the timer event. Two possible definitions are possible
+ time when the execution enters the timer event. Two types are possible
<para>
<emphasis role="bold">Duration expression: </emphasis>
Added: jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/bpmn/event/timerstart/TimerStartTest.java
===================================================================
--- jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/bpmn/event/timerstart/TimerStartTest.java (rev 0)
+++ jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/bpmn/event/timerstart/TimerStartTest.java 2010-01-27 12:03:08 UTC (rev 6138)
@@ -0,0 +1,79 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.examples.bpmn.event.timerstart;
+
+import java.util.Calendar;
+
+import org.jbpm.api.NewDeployment;
+import org.jbpm.api.ProcessInstanceQuery;
+import org.jbpm.api.job.Job;
+import org.jbpm.pvm.internal.util.Clock;
+import org.jbpm.test.JbpmTestCase;
+import org.jbpm.test.util.DateUtils;
+
+
+/**
+ * @author Joram Barrez
+ */
+public class TimerStartTest extends JbpmTestCase {
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ Clock.setExplicitTime(DateUtils.getDateAtMidnight(10, Calendar.OCTOBER, 2099));
+ NewDeployment deployment = repositoryService.createDeployment();
+ deployment.addResourceFromClasspath("org/jbpm/examples/bpmn/event/timerstart/timer_start_event.bpmn.xml");
+ registerDeployment(deployment.deploy());
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ Clock.setExplicitTime(null);
+ super.tearDown();
+ }
+
+ public void testTimerStartEventWithDurationAsTimeCycle() {
+
+ // After deployment, there should be one job in the database that starts a new process instance
+ Job startProcessTimer = managementService.createJobQuery().uniqueResult();
+ assertNotNull(startProcessTimer);
+ assertEquals(DateUtils.getDate(10, Calendar.OCTOBER, 2099, 10, 0, 0).getTime(), startProcessTimer.getDuedate().getTime());
+
+ // Triggering the job should start a new process instance of the deployed process definition
+ ProcessInstanceQuery procInstQuery = executionService.createProcessInstanceQuery();
+ assertEquals(0, procInstQuery.count());
+
+ // need to change current date to calculate the next duedate internally correctl
+ Clock.setExplicitTime(DateUtils.getDate(10, Calendar.OCTOBER, 2099, 10, 0, 0));
+ managementService.executeJob(startProcessTimer.getId());
+ assertEquals(1, procInstQuery.count());
+
+ // Since a timeCycle was used, the job should have been recreated with a new duedate
+ startProcessTimer = managementService.createJobQuery().uniqueResult();
+ assertEquals(DateUtils.getDate(10, Calendar.OCTOBER, 2099, 20, 0, 0).getTime(), startProcessTimer.getDuedate().getTime());
+
+
+ // So we need to manually delete it
+ managementService.deleteJob(Long.valueOf(startProcessTimer.getId()));
+ }
+
+}
Added: jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/bpmn/event/timerstart/timer_start_event.bpmn.xml
===================================================================
--- jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/bpmn/event/timerstart/timer_start_event.bpmn.xml (rev 0)
+++ jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/bpmn/event/timerstart/timer_start_event.bpmn.xml 2010-01-27 12:03:08 UTC (rev 6138)
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definitions
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://schema.omg.org/spec/BPMN/2.0 ../../../../../../../../../../bpmn/src/main/resources/BPMN20.xsd"
+ xmlns="http://schema.omg.org/spec/BPMN/2.0"
+ typeLanguage="http://www.w3.org/2001/XMLSchema"
+ expressionLanguage="http://www.w3.org/1999/XPath"
+ targetNamespace="http://jbpm.org/example/bpmn2/timer_start_end_event"
+ xmlns:jbpm="http://jbpm.org/bpmn2">
+
+ <process id="noneStartEndEvent">
+
+ <startEvent id="start" >
+ <timerEventDefinition>
+ <timeCycle>10 hours</timeCycle>
+ </timerEventDefinition>
+ </startEvent>
+
+ <sequenceFlow id="flow1" sourceRef="start" targetRef="wait" />
+
+ <receiveTask id="wait" />
+
+ <sequenceFlow id="flow2" sourceRef="wait" targetRef="end" />
+
+ <endEvent id="end" />
+
+ </process>
+
+</definitions>
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cal/Duration.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cal/Duration.java 2010-01-27 07:59:50 UTC (rev 6137)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cal/Duration.java 2010-01-27 12:03:08 UTC (rev 6138)
@@ -110,52 +110,59 @@
}
public static Date calculateDueDate(String durationExpression) {
- Date dueDate;
- // is due date description in date_expression +|- fixed_duration format?
- Matcher dateDurationMatcher = dateDurationPattern.matcher(durationExpression);
- if (dateDurationMatcher.matches()) {
- // evaluate date expression
- String dateExpression = dateDurationMatcher.group(1);
- Object result = ScriptManager.getScriptManager().evaluateExpression(dateExpression, null);
- // convert result to Date
- if (result instanceof Date) {
- dueDate = (Date) result;
- } else if (result instanceof Calendar) {
- Calendar calendar = (Calendar) result;
- dueDate = calendar.getTime();
- } else if (result instanceof String) {
- try {
- // TODO use a locale-sensitive date format?
- dueDate = new SimpleDateFormat(dateFormat).parse((String) result);
- } catch (ParseException e) {
- throw new JbpmException("invalid base date: " + result, e);
+ Date duedate = null;
+ if (durationExpression != null) {
+ ScriptManager scriptManager = ScriptManager.getScriptManager();
+
+ Date baseDate;
+ String durationString = null;
+ char durationSeparator = '+'; // needs to be initialized
+
+ if (durationExpression.startsWith("#")) {
+
+ String baseDateEL = durationExpression.substring(0, durationExpression.indexOf("}") + 1);
+ Object result = scriptManager.evaluateExpression(baseDateEL, null);
+
+ 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()
+ + ". Only Date and Calendar are supported");
}
+
+ int endOfELIndex = durationExpression.indexOf("}");
+ if (endOfELIndex < (durationExpression.length() - 1)) {
+ durationSeparator = durationExpression.substring(endOfELIndex + 1).trim().charAt(0);
+ if (durationSeparator != '+' && durationSeparator != '-') {
+ throw new JbpmException("Invalid duedate, + or - missing after EL");
+ }
+ durationString = durationExpression.substring(endOfELIndex + 1).substring(2).trim();
+ }
+
} else {
- throw new JbpmException("invalid base date: " + result);
+
+ baseDate = Clock.getTime();
+ durationString = durationExpression;
+
}
- // fixed duration is optional
- String operationString = dateDurationMatcher.group(2);
- if (operationString != null) {
- char operation = operationString.charAt(0);
- String duration = dateDurationMatcher.group(3);
- // add duration to base date
+ if (durationString == null || durationString.length() == 0) {
+ duedate = baseDate;
+ } else {
+ if (durationString.contains("business") && durationSeparator == '-') {
+ throw new JbpmException("Invalid duedate, subtraction ('-') not supported if duedate contains 'business'");
+ }
BusinessCalendar businessCalendar = EnvironmentImpl.getFromCurrent(BusinessCalendar.class);
- dueDate = operation == '+' ? businessCalendar.add(dueDate, duration)
- : businessCalendar.subtract(dueDate, duration);
+ if (durationSeparator == '+') {
+ duedate = businessCalendar.add(baseDate, durationString);
+ } else {
+ duedate = businessCalendar.subtract(baseDate, durationString);
+ }
}
- } else {
- // is due date description in fixed_duration format?
- Matcher durationMatcher = durationPattern.matcher(durationExpression);
- if (durationMatcher.matches()) {
- // add duration to current date
- dueDate = EnvironmentImpl.getFromCurrent(BusinessCalendar.class).add(
- Clock.getTime(), durationMatcher.group(1));
- } else {
- throw new JbpmException("invalid due date duration: " + durationExpression);
- }
}
- return dueDate;
+ return duedate;
}
public Duration(boolean isBusinessTime, int millis, int seconds, int minutes, int hours, int days, int weeks, int months, int years) {
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/hibernate/DbSessionImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/hibernate/DbSessionImpl.java 2010-01-27 07:59:50 UTC (rev 6137)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/hibernate/DbSessionImpl.java 2010-01-27 12:03:08 UTC (rev 6138)
@@ -43,6 +43,7 @@
import org.jbpm.pvm.internal.history.model.HistoryProcessInstanceImpl;
import org.jbpm.pvm.internal.id.DbidGenerator;
import org.jbpm.pvm.internal.job.JobImpl;
+import org.jbpm.pvm.internal.job.StartProcessTimer;
import org.jbpm.pvm.internal.model.ExecutionImpl;
import org.jbpm.pvm.internal.query.DeploymentQueryImpl;
import org.jbpm.pvm.internal.query.HistoryActivityInstanceQueryImpl;
@@ -427,6 +428,14 @@
return (JobImpl<?>) query.uniqueResult();
}
+ public List<StartProcessTimer> findStartProcessTimers(String processDefinitionName) {
+ Query query = session.createQuery(
+ "select spt from " + StartProcessTimer.class.getName() + " as spt " +
+ "where spt.signalName = :procDefName");
+ query.setString("procDefName", processDefinitionName);
+ return query.list();
+ }
+
public ProcessInstanceQueryImpl createProcessInstanceQuery() {
return new ProcessInstanceQueryImpl();
}
Deleted: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/PeriodicStartProcessTimer.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/PeriodicStartProcessTimer.java 2010-01-27 07:59:50 UTC (rev 6137)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/PeriodicStartProcessTimer.java 2010-01-27 12:03:08 UTC (rev 6138)
@@ -1,200 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jbpm.pvm.internal.job;
-
-import java.text.ParseException;
-
-import org.jbpm.api.ExecutionService;
-import org.jbpm.api.JbpmException;
-import org.jbpm.api.RepositoryService;
-import org.jbpm.api.cmd.Environment;
-import org.jbpm.internal.log.Log;
-import org.jbpm.pvm.internal.cal.CronExpression;
-import org.jbpm.pvm.internal.cal.Duration;
-import org.jbpm.pvm.internal.env.EnvironmentImpl;
-import org.jbpm.pvm.internal.session.DbSession;
-import org.jbpm.pvm.internal.util.Clock;
-
-
-/**
- * Job that periodically startes a new process instance of a given process definition.
- *
- * @author Joram Barrez
- */
-public class PeriodicStartProcessTimer extends TimerImpl {
-
- private static final long serialVersionUID = 1L;
-
- private static final Log LOG = Log.getLog(PeriodicStartProcessTimer.class.getName());
-
- // Override execution logic of regular timer
- public Boolean execute(Environment environment) throws Exception {
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("Periodic start process triggered at " + Clock.getTime());
- }
-
- boolean processDefinitionExists = processDefinitionExists(environment);
- boolean newDueDateCalculated = false;
-
- if (processDefinitionExists) {
- startProcessInstance(environment);
- newDueDateCalculated = calculateDueDate(environment);
- }
-
- if (!processDefinitionExists || !newDueDateCalculated) {
- deleteThisJob(environment);
- } else {
- saveThisJob(environment);
- }
-
- return null;
- }
-
- protected boolean processDefinitionExists(Environment environment) {
- RepositoryService repositoryService = environment.get(RepositoryService.class);
- boolean processExists = !repositoryService.createProcessDefinitionQuery()
- .processDefinitionName(getProcessDefinitionName()).list().isEmpty();
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("Process definition with name " + getProcessDefinitionName() + " still exists: " + processExists);
- }
-
- return processExists;
- }
-
- protected void startProcessInstance(Environment environment) {
- ExecutionService executionService = environment.get(ExecutionService.class);
- if (executionService == null) {
- throw new JbpmException("no " + ExecutionService.class.getName() + " in environment");
- }
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("Starting a new process instance for process definition with name " + getProcessDefinitionName());
- }
-
- executionService.startProcessInstanceByKey(getProcessDefinitionName());
- }
-
- protected boolean calculateDueDate(Environment environment) throws ParseException {
-
- if (getIntervalExpression() != null && Duration.isValidExpression(getIntervalExpression())) {
- duedate = Duration.calculateDueDate(getIntervalExpression());
- } else if (getIntervalExpression() != null && CronExpression.isValidExpression(getIntervalExpression())) {
- duedate = new CronExpression(getIntervalExpression()).getNextValidTimeAfter(Clock.getTime());
- } else {
- if (LOG.isDebugEnabled()) {
- LOG.debug("No next duedate calculated for periodic start process job " +
- "with intervalExpression " + getIntervalExpression());
- }
- return false;
- }
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("Next process start duedate: " + duedate);
- }
-
- return true;
- }
-
- protected void saveThisJob(Environment environment) {
- DbSession dbSession = environment.get(DbSession.class);
- if (dbSession == null) {
- throw new JbpmException("no " + DbSession.class.getName() + " in environment");
- }
- dbSession.save(this);
- }
-
- protected void deleteThisJob(Environment environment) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Deleting periodic start job for process definition with name " + getProcessDefinitionName());
- }
-
- DbSession dbSession = environment.get(DbSession.class);
- if (dbSession == null) {
- throw new JbpmException("no " + DbSession.class.getName() + " in environment");
- }
- dbSession.delete(this);
- }
-
- @Override
- public void schedule() {
- if (duedate == null && getIntervalExpression() != null) {
- try {
- calculateDueDate(EnvironmentImpl.getCurrent());
- } catch (ParseException e) {
- throw new JbpmException("Cannot parse intervalExpression", e);
- }
- } else if (duedate == null) {
- throw new JbpmException("Cannot schedule periodic start process timer: " +
- "no duedate or intervalExpression set");
- }
- super.schedule();
- }
-
- @Override
- public void validate() {
- if (getProcessDefinitionName() == null) {
- throw new JbpmException("No process definition name set for periodic start process timer");
- }
- if (duedate == null && getIntervalExpression() == null) {
- throw new JbpmException("No duedate or intervalExpression found for periodic start process timer");
- }
- }
-
- public String getProcessDefinitionName() {
- return signalName;
- }
-
- public void setProcessDefinitionName(String processDefinitionName) {
- this.signalName = processDefinitionName;
- }
-
- public String getIntervalExpression() {
- return eventName;
- }
-
- /**
- * Sets the expression that will define the interval between
- * two sequential process starts by this job.
- *
- * Possible expression types are {@link Duration} and {@link CronExpression}.
- */
- public void setIntervalExpression(String intervalExpression) {
- this.eventName = intervalExpression;
- }
-
- @Override
- public String toString() {
- StringBuilder strb = new StringBuilder();
- strb.append("PeriodicProcessStart[");
- if (duedate != null) {
- strb.append(duedate);
- }
- if (getIntervalExpression() != null) {
- strb.append("| " + getIntervalExpression());
- }
- strb.append("]");
- return strb.toString();
- }
-
-}
Copied: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/StartProcessTimer.java (from rev 6135, jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/PeriodicStartProcessTimer.java)
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/StartProcessTimer.java (rev 0)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/StartProcessTimer.java 2010-01-27 12:03:08 UTC (rev 6138)
@@ -0,0 +1,213 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.pvm.internal.job;
+
+import java.text.ParseException;
+
+import org.jbpm.api.ExecutionService;
+import org.jbpm.api.JbpmException;
+import org.jbpm.api.ProcessDefinition;
+import org.jbpm.api.RepositoryService;
+import org.jbpm.api.cmd.Environment;
+import org.jbpm.internal.log.Log;
+import org.jbpm.pvm.internal.cal.CronExpression;
+import org.jbpm.pvm.internal.cal.Duration;
+import org.jbpm.pvm.internal.env.EnvironmentImpl;
+import org.jbpm.pvm.internal.session.DbSession;
+import org.jbpm.pvm.internal.session.RepositorySession;
+import org.jbpm.pvm.internal.util.Clock;
+
+
+/**
+ * Job that starts a new process instance of a given process definition
+ * on a fixed duedate/periodic time.
+ *
+ * @author Joram Barrez
+ */
+public class StartProcessTimer extends TimerImpl {
+
+ private static final long serialVersionUID = 1L;
+
+ private static final Log LOG = Log.getLog(StartProcessTimer.class.getName());
+
+ // Override execution logic of regular timer
+ public Boolean execute(Environment environment) throws Exception {
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Periodic start process triggered at " + Clock.getTime());
+ }
+
+ boolean processDefinitionExists = processDefinitionExists(environment);
+ boolean newDueDateCalculated = false;
+
+ if (processDefinitionExists) {
+ startProcessInstance(environment);
+ newDueDateCalculated = calculateDueDate(environment);
+ }
+
+ if (!processDefinitionExists || !newDueDateCalculated) {
+ deleteThisJob(environment);
+ } else {
+ saveThisJob(environment);
+ }
+
+ return null;
+ }
+
+ protected boolean processDefinitionExists(Environment environment) {
+ RepositoryService repositoryService = environment.get(RepositoryService.class);
+ boolean processExists = !repositoryService.createProcessDefinitionQuery()
+ .processDefinitionName(getProcessDefinitionName()).list().isEmpty();
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Process definition with name " + getProcessDefinitionName() + " still exists: " + processExists);
+ }
+
+ return processExists;
+ }
+
+ protected void startProcessInstance(Environment environment) {
+ ExecutionService executionService = environment.get(ExecutionService.class);
+ if (executionService == null) {
+ throw new JbpmException("no " + ExecutionService.class.getName() + " in environment");
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Starting a new process instance for process definition with name " + getProcessDefinitionName());
+ }
+
+ RepositorySession repoSession = environment.get(RepositorySession.class);
+ if (repoSession == null) {
+ throw new JbpmException("Could not find a" + RepositorySession.class.getName() + " impl in environment");
+ }
+
+ ProcessDefinition procDef = repoSession.findLatestProcessDefinitionByName(getProcessDefinitionName());
+ executionService.startProcessInstanceById(procDef.getId());
+ }
+
+ protected boolean calculateDueDate(Environment environment) throws ParseException {
+
+ if (getIntervalExpression() != null && Duration.isValidExpression(getIntervalExpression())) {
+ duedate = Duration.calculateDueDate(getIntervalExpression());
+ } else if (getIntervalExpression() != null && CronExpression.isValidExpression(getIntervalExpression())) {
+ duedate = new CronExpression(getIntervalExpression()).getNextValidTimeAfter(Clock.getTime());
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("No next duedate calculated for start process job " +
+ "with intervalExpression " + getIntervalExpression());
+ }
+ return false;
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Next process start duedate: " + duedate);
+ }
+
+ return true;
+ }
+
+ protected void saveThisJob(Environment environment) {
+ DbSession dbSession = environment.get(DbSession.class);
+ if (dbSession == null) {
+ throw new JbpmException("no " + DbSession.class.getName() + " in environment");
+ }
+ dbSession.save(this);
+ }
+
+ protected void deleteThisJob(Environment environment) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Deleting start process job for process definition with name " + getProcessDefinitionName());
+ }
+
+ DbSession dbSession = environment.get(DbSession.class);
+ if (dbSession == null) {
+ throw new JbpmException("no " + DbSession.class.getName() + " in environment");
+ }
+ dbSession.delete(this);
+ }
+
+ @Override
+ public void schedule() {
+ if (duedate == null && getIntervalExpression() != null) {
+ try {
+ calculateDueDate(EnvironmentImpl.getCurrent());
+ } catch (ParseException e) {
+ throw new JbpmException("Cannot parse intervalExpression", e);
+ }
+ } else if (duedate == null) {
+ throw new JbpmException("Cannot schedule start process timer: " +
+ "no duedate or intervalExpression set");
+ }
+ super.schedule();
+ }
+
+ @Override
+ public void validate() {
+ if (getProcessDefinitionName() == null) {
+ throw new JbpmException("No process definition name set for start process timer");
+ }
+ if (duedate == null && getIntervalExpression() == null) {
+ throw new JbpmException("No duedate or intervalExpression found for start process timer");
+ }
+ }
+
+ public String getProcessDefinitionName() {
+ return signalName;
+ }
+
+ public void setProcessDefinitionName(String processDefinitionName) {
+ this.signalName = processDefinitionName;
+ }
+
+ public String getIntervalExpression() {
+ return eventName;
+ }
+
+ /**
+ * Sets the expression that will define the interval between
+ * two sequential process starts by this job.
+ *
+ * Possible expression types are {@link Duration} and {@link CronExpression}.
+ */
+ public void setIntervalExpression(String intervalExpression) {
+ this.eventName = intervalExpression;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder strb = new StringBuilder();
+ strb.append("PeriodicProcessStart[");
+ if (getProcessDefinitionName() != null) {
+ strb.append(getProcessDefinitionName());
+ }
+ if (duedate != null) {
+ strb.append("| " + duedate);
+ }
+ if (getIntervalExpression() != null) {
+ strb.append("| " + getIntervalExpression());
+ }
+
+ strb.append("]");
+ return strb.toString();
+ }
+
+}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/repository/RepositorySessionImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/repository/RepositorySessionImpl.java 2010-01-27 07:59:50 UTC (rev 6137)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/repository/RepositorySessionImpl.java 2010-01-27 12:03:08 UTC (rev 6138)
@@ -179,7 +179,23 @@
return null;
}
+
+ public ProcessDefinitionImpl findLatestProcessDefinitionByName(String processDefinitionName) {
+ ProcessDefinition processDefinition = createProcessDefinitionQuery()
+ .processDefinitionName(processDefinitionName)
+ .orderDesc(ProcessDefinitionQuery.PROPERTY_VERSION)
+ .page(0, 1)
+ .uniqueResult();
+ if (processDefinition != null) {
+ return findProcessDefinitionById(processDefinition.getId());
+ } else {
+ validateRepositoryCache();
+ }
+
+ return null;
+ }
+
public DeploymentProperty findDeploymentPropertyByProcessDefinitionId(String processDefinitionId) {
DeploymentProperty deploymentProperty = (DeploymentProperty) session.createQuery(
"select deploymentProperty " +
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/session/DbSession.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/session/DbSession.java 2010-01-27 07:59:50 UTC (rev 6137)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/session/DbSession.java 2010-01-27 12:03:08 UTC (rev 6138)
@@ -28,6 +28,7 @@
import org.jbpm.pvm.internal.client.ClientExecution;
import org.jbpm.pvm.internal.client.ClientProcessDefinition;
import org.jbpm.pvm.internal.job.JobImpl;
+import org.jbpm.pvm.internal.job.StartProcessTimer;
import org.jbpm.pvm.internal.model.ExecutionImpl;
import org.jbpm.pvm.internal.model.ScopeInstanceImpl;
import org.jbpm.pvm.internal.query.DeploymentQueryImpl;
@@ -122,4 +123,7 @@
/** the first job to finish among non-owned jobs or null if none */
public JobImpl<?> findFirstDueJob();
+
+ /** returns a list of start process timers for the given process definition */
+ public List<StartProcessTimer> findStartProcessTimers(String processDefinitionId);
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/session/RepositorySession.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/session/RepositorySession.java 2010-01-27 07:59:50 UTC (rev 6137)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/session/RepositorySession.java 2010-01-27 12:03:08 UTC (rev 6138)
@@ -46,6 +46,8 @@
ProcessDefinitionImpl findProcessDefinitionById(String processDefinitionId);
ProcessDefinitionImpl findProcessDefinitionByKey(String processDefinitionKey);
+
+ ProcessDefinitionImpl findLatestProcessDefinitionByName(String processDefinitionName);
void updateDeploymentResource(String deploymentId, String resourceName, byte[] bytes);
}
Modified: jbpm4/trunk/modules/pvm/src/main/resources/jbpm.execution.hbm.xml
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/resources/jbpm.execution.hbm.xml 2010-01-27 07:59:50 UTC (rev 6137)
+++ jbpm4/trunk/modules/pvm/src/main/resources/jbpm.execution.hbm.xml 2010-01-27 12:03:08 UTC (rev 6138)
@@ -248,7 +248,7 @@
<property name="eventName" column="EVENT_" />
<property name="repeat" column="REPEAT_" />
- <subclass name="org.jbpm.pvm.internal.job.PeriodicStartProcessTimer" discriminator-value="PeriodicStartProcess" />
+ <subclass name="org.jbpm.pvm.internal.job.StartProcessTimer" discriminator-value="PeriodicStartProcess" />
</subclass>
Modified: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/startevent/TimerStartEventTest.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/startevent/TimerStartEventTest.java 2010-01-27 07:59:50 UTC (rev 6137)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/startevent/TimerStartEventTest.java 2010-01-27 12:03:08 UTC (rev 6138)
@@ -22,8 +22,12 @@
package org.jbpm.bpmn.test.startevent;
import java.util.Calendar;
+import java.util.List;
import org.jbpm.api.JbpmException;
+import org.jbpm.api.ProcessDefinition;
+import org.jbpm.api.ProcessDefinitionQuery;
+import org.jbpm.api.ProcessInstance;
import org.jbpm.api.ProcessInstanceQuery;
import org.jbpm.api.job.Job;
import org.jbpm.pvm.internal.util.Clock;
@@ -119,7 +123,7 @@
private static final String TIMER_START_TIMECYCLE_CRON_EXPR =
"<definitions xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>" +
- " <process id='timerStartTimeCycleCronExpression'>" +
+ " <process id='timerStartTimeCycleCronExpression' name='timerStartCron'>" +
" <startEvent id='theStart' >" +
" <timerEventDefinition >" +
" <timeCycle>0 0 22 * * ?</timeCycle>" + // every day at 22:00
@@ -189,7 +193,7 @@
.processDefinitionId(findProcessDefinitionId("timerStartTimeCycleDuration"));
assertEquals(0, procInstQuery.count());
- // need to change current date to calculate the next duedate correctly
+ // need to change current date to calculate the next duedate internally correctly
Clock.setExplicitTime(DateUtils.getDate(10, Calendar.OCTOBER, 2099, 10, 0, 0));
managementService.executeJob(startProcessTimer.getId());
assertEquals(1, procInstQuery.count());
@@ -235,6 +239,7 @@
String deployId = deployBpmn2XmlString(TIMER_START_TIMECYCLE_DURATION);
// Delete the process definition
+ String procDefId = findProcessDefinitionId("timerStartTimeCycleDuration");
repositoryService.deleteDeploymentCascade(deployId);
registeredDeployments.remove(0);
@@ -243,11 +248,65 @@
assertNotNull(startProcessTimer);
// When the timer triggers, it notices that the process definition is gone and it deletes itselves
+ // No new process instance should have been started
+ ProcessInstanceQuery procInstQuery = executionService.createProcessInstanceQuery().processDefinitionId(procDefId);
+ assertEquals(0, procInstQuery.count());
+
managementService.executeJob(startProcessTimer.getId());
startProcessTimer = managementService.createJobQuery().uniqueResult();
assertNull(startProcessTimer);
+ assertEquals(0, procInstQuery.count());
}
+ /*
+ * Processes with a timer start event should be createable through the executionService.
+ */
+ public void testStartProcessInstanceByKey() {
+ deployBpmn2XmlString(TIMER_START_TIMECYCLE_DURATION);
+ ProcessInstance pi = executionService.startProcessInstanceByKey("timerStartTimeCycleDuration");
+ assertNotNull(pi);
+
+ Job startProcessTimer = managementService.createJobQuery().uniqueResult();
+ managementService.deleteJob(Long.valueOf(startProcessTimer.getId()));
+ }
+
+ public void testOnlyOneStartProcessActiveAfterRedeploy() {
+ deployBpmn2XmlString(TIMER_START_TIMECYCLE_DURATION);
+ List<Job> startProcessTimers = managementService.createJobQuery().list();
+ assertEquals(1, startProcessTimers.size());
+ String firstJobId = startProcessTimers.get(0).getId();
+
+ // Redeploy -> first job should be deleted
+ deployBpmn2XmlString(TIMER_START_TIMECYCLE_DURATION);
+ assertEquals(2, repositoryService.createProcessDefinitionQuery().list().size());
+ startProcessTimers = managementService.createJobQuery().list();
+ assertEquals(1, startProcessTimers.size());
+
+ String secondJobId = startProcessTimers.get(0).getId();
+ assertTrue(!firstJobId.equals(secondJobId));
+
+ managementService.deleteJob(Long.valueOf(secondJobId));
+ }
+
+ public void testLatestProcessDefinitionUsedAfterRedeploy() {
+ deployBpmn2XmlString(TIMER_START_TIMECYCLE_DURATION);
+ Job startProcessTimer = managementService.createJobQuery().uniqueResult();
+
+ // Redeploy
+ deployBpmn2XmlString(TIMER_START_TIMECYCLE_DURATION);
+ List<ProcessDefinition> procDefs = repositoryService.createProcessDefinitionQuery()
+ .orderAsc(ProcessDefinitionQuery.PROPERTY_VERSION).list();
+ assertEquals(2, procDefs.size());
+
+ // Firing start process timer -> new process instance for latests version of proc def
+ startProcessTimer = managementService.createJobQuery().uniqueResult();
+ managementService.executeJob(startProcessTimer.getId());
+ ProcessInstance procInst = executionService.createProcessInstanceQuery().uniqueResult();
+ assertEquals(procDefs.get(1).getId(), procInst.getProcessDefinitionId());
+
+ managementService.deleteJob(Long.valueOf(startProcessTimer.getId()));
+ }
+
private String findProcessDefinitionId(String processDefinitionKey) {
return repositoryService.createProcessDefinitionQuery()
.processDefinitionName(processDefinitionKey).uniqueResult().getId();
14 years, 3 months
JBoss JBPM SVN: r6137 - in jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main: java/org/jbpm and 3 other directories.
by do-not-reply@jboss.org
Author: alex.guizar(a)jboss.com
Date: 2010-01-27 02:59:50 -0500 (Wed, 27 Jan 2010)
New Revision: 6137
Added:
jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/command/
jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/command/jms/
jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/command/jms/JmsCommandService.java
jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/command/jms/JmsCommandServiceFactory.java
jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/ejb/impl/SaveJobExceptionCommand.java
Modified:
jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/etc/jbpm.cfg.xml
jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/ejb/impl/CommandServiceBean.java
jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/ejb/impl/ExecuteJobCommand.java
Log:
JBPM-2691: save job exception in separate transaction - enterprise module
Modified: jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/etc/jbpm.cfg.xml
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/etc/jbpm.cfg.xml 2010-01-26 18:45:01 UTC (rev 6136)
+++ jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/etc/jbpm.cfg.xml 2010-01-27 07:59:50 UTC (rev 6137)
@@ -7,6 +7,7 @@
<service name="tx" factory="org.jbpm.tx.TxServiceFactory" />
<service name="logging" factory="org.jbpm.logging.db.DbLoggingServiceFactory" />
<service name="authentication" factory="org.jbpm.security.authentication.DefaultAuthenticationServiceFactory" />
+ <service name="command" factory="org.jbpm.command.jms.JmsCommandServiceFactory" />
</jbpm-context>
<!-- use the context class loader -->
Added: jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/command/jms/JmsCommandService.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/command/jms/JmsCommandService.java (rev 0)
+++ jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/command/jms/JmsCommandService.java 2010-01-27 07:59:50 UTC (rev 6137)
@@ -0,0 +1,94 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.command.jms;
+
+import javax.jms.Connection;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.jbpm.JbpmException;
+import org.jbpm.command.Command;
+import org.jbpm.command.CommandService;
+import org.jbpm.msg.jms.JmsMessageService;
+import org.jbpm.svc.Service;
+
+/**
+ * @author Alejandro Guizar
+ */
+public class JmsCommandService implements Service, CommandService {
+
+ private Connection connection;
+ private Session session;
+ private MessageProducer messageProducer;
+
+ public static final String SERVICE_NAME = "command";
+
+ private static final long serialVersionUID = 1L;
+
+ private static final Log log = LogFactory.getLog(JmsMessageService.class);
+
+ public JmsCommandService(JmsCommandServiceFactory serviceFactory) throws JMSException {
+ connection = serviceFactory.getConnectionFactory().createConnection();
+ session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ messageProducer = session.createProducer(serviceFactory.getDestination());
+ }
+
+ public Object execute(Command command) {
+ try {
+ Message message = session.createObjectMessage(command);
+ messageProducer.send(message);
+ return null;
+ }
+ catch (JMSException e) {
+ throw new JbpmException("could not send jms message", e);
+ }
+ }
+
+ public void close() {
+ try {
+ messageProducer.close();
+ }
+ catch (JMSException e) {
+ log.warn("could not close message producer", e);
+ }
+
+ try {
+ session.close();
+ }
+ catch (JMSException e) {
+ log.warn("could not close jms session", e);
+ }
+
+ try {
+ connection.close();
+ }
+ catch (JMSException e) {
+ log.warn("could not close jms connection", e);
+ }
+ }
+
+}
Property changes on: jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/command/jms/JmsCommandService.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ native
Added: jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/command/jms/JmsCommandServiceFactory.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/command/jms/JmsCommandServiceFactory.java (rev 0)
+++ jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/command/jms/JmsCommandServiceFactory.java 2010-01-27 07:59:50 UTC (rev 6137)
@@ -0,0 +1,111 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.command.jms;
+
+import javax.jms.ConnectionFactory;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.jbpm.JbpmException;
+import org.jbpm.ejb.impl.CommandListenerBean;
+import org.jbpm.svc.Service;
+import org.jbpm.svc.ServiceFactory;
+
+/**
+ * The JMS command service leverages the reliable communication infrastructure
+ * available through JMS to deliver commands to the {@link CommandListenerBean}
+ * for asynchronous execution.
+ *
+ * <h3>Configuration</h3>
+ *
+ * The JMS command service factory provides the following configurable fields.
+ * <ul>
+ * <li><code>connectionFactoryJndiName</code></li>
+ * <li><code>destinationJndiName</code></li>
+ * </ul>
+ *
+ * @author Alejandro Guizar
+ */
+public class JmsCommandServiceFactory implements ServiceFactory {
+
+ String connectionFactoryJndiName = "java:comp/env/jms/JbpmConnectionFactory";
+ String destinationJndiName = "java:comp/env/jms/CommandQueue";
+
+ private ConnectionFactory connectionFactory;
+ private Destination destination;
+
+ private static final long serialVersionUID = 1L;
+
+ public ConnectionFactory getConnectionFactory() {
+ if (connectionFactory == null) {
+ try {
+ connectionFactory =
+ (ConnectionFactory) lookup(connectionFactoryJndiName);
+ }
+ catch (NamingException e) {
+ throw new JbpmException(
+ "could not retrieve command connection factory", e);
+ }
+ }
+ return connectionFactory;
+ }
+
+ public Destination getDestination() {
+ if (destination == null) {
+ try {
+ destination = (Destination) lookup(destinationJndiName);
+ }
+ catch (NamingException e) {
+ throw new JbpmException("could not retrieve command destination", e);
+ }
+ }
+ return destination;
+ }
+
+ private static Object lookup(String name) throws NamingException {
+ Context initial = new InitialContext();
+ try {
+ return initial.lookup(name);
+ }
+ finally {
+ initial.close();
+ }
+ }
+
+ public Service openService() {
+ try {
+ return new JmsCommandService(this);
+ }
+ catch (JMSException e) {
+ throw new JbpmException("could not open command service", e);
+ }
+ }
+
+ public void close() {
+ connectionFactory = null;
+ destination = null;
+ }
+
+}
Property changes on: jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/command/jms/JmsCommandServiceFactory.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ native
Modified: jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/ejb/impl/CommandServiceBean.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/ejb/impl/CommandServiceBean.java 2010-01-26 18:45:01 UTC (rev 6136)
+++ jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/ejb/impl/CommandServiceBean.java 2010-01-27 07:59:50 UTC (rev 6137)
@@ -40,14 +40,16 @@
import org.jbpm.tx.TxService;
/**
- * Stateless session bean that executes {@linkplain Command commands} by
- * calling their {@link Command#execute(JbpmContext) execute} method on
- * a separate {@link JbpmContext jBPM context}.
+ * Stateless session bean that executes {@linkplain Command commands} by calling
+ * their {@link Command#execute(JbpmContext) execute} method on a separate
+ * {@link JbpmContext jBPM context}.
*
* <h3>Environment</h3>
*
- * <p>The environment entries and resources available for customization are
- * summarized in the table below.</p>
+ * <p>
+ * The environment entries and resources available for customization are
+ * summarized in the table below.
+ * </p>
*
* <table border="1">
* <tr>
@@ -58,17 +60,16 @@
* <tr>
* <td><code>JbpmCfgResource</code></td>
* <td>Environment Entry</td>
- * <td>The classpath resource from which to read the {@linkplain
- * JbpmConfiguration jBPM configuration}. Optional, defaults to <code>
- * jbpm.cfg.xml</code>.
- * </td>
+ * <td>The classpath resource from which to read the
+ * {@linkplain JbpmConfiguration jBPM configuration}. Optional, defaults to
+ * <code>
+ * jbpm.cfg.xml</code>.</td>
* </tr>
* <tr>
* <td><code>ejb/TimerEntityBean</code></td>
* <td>EJB Reference</td>
* <td>Link to the local {@linkplain TimerEntityBean entity bean} that
- * implements the scheduler service. Required for processes that contain
- * timers.
+ * implements the scheduler service. Required for processes that contain timers.
* </td>
* </tr>
* <tr>
@@ -76,26 +77,23 @@
* <td>Resource Manager Reference</td>
* <td>Logical name of the data source that provides JDBC connections to the
* {@linkplain JtaDbPersistenceServiceFactory persistence service}. Must match
- * the <code>hibernate.connection.datasource</code> property in the Hibernate
- * configuration file.
- * </td>
+ * the <code>hibernate.connection.datasource</code> property in the Hibernate
+ * configuration file.</td>
* </tr>
* <tr>
* <td><code>jms/JbpmConnectionFactory</code></td>
* <td>Resource Manager Reference</td>
- * <td>Logical name of the factory that provides JMS connections to the
- * {@linkplain JmsMessageServiceFactory message service}. Required for
- * processes that contain asynchronous continuations.
- * </td>
+ * <td>Logical name of the factory that provides JMS connections to the
+ * {@linkplain JmsMessageServiceFactory message service}. Required for processes
+ * that contain asynchronous continuations.</td>
* </tr>
* <tr>
* <td><code>jms/JobQueue</code></td>
* <td>Message Destination Reference</td>
- * <td>The message service sends job messages to the queue referenced here.
- * To ensure this is the same queue from which the {@linkplain JobListenerBean
- * job listener bean} receives messages, the <code>message-destination-link
- * </code> points to a common logical destination, <code>JobQueue</code>.
- * </td>
+ * <td>The message service sends job messages to the queue referenced here. To
+ * ensure this is the same queue from which the {@linkplain JobListenerBean job
+ * listener bean} receives messages, the <code>message-destination-link
+ * </code> points to a common logical destination, <code>JobQueue</code>.</td>
* </tr>
* </table>
*
@@ -111,29 +109,32 @@
SessionContext sessionContext = null;
/**
- * creates a command service that will be used to execute the commands that
- * are passed in the execute method. The command service will be build by
- * creating a jbpm configuration. In case the environment key JbpmCfgResource
- * is specified for this bean, that value will be used to resolve the jbpm
- * configuration file as a resource. If that key is not configured, the default
- * jbpm configuration file will be used (jbpm.cfg.xml).
+ * creates a command service that will be used to execute the commands that
+ * are passed in the execute method. The command service will be build by
+ * creating a jbpm configuration. In case the environment key JbpmCfgResource
+ * is specified for this bean, that value will be used to resolve the jbpm
+ * configuration file as a resource. If that key is not configured, the
+ * default jbpm configuration file will be used (jbpm.cfg.xml).
*/
public void ejbCreate() throws CreateException {
- String jbpmCfgResource = null;
+ String jbpmCfgResource = null;
try {
log.debug("getting jbpm configuration resource from the environment properties");
Context initial = new InitialContext();
- jbpmCfgResource = (String) initial.lookup("java:comp/env/JbpmCfgResource");
- } catch (NamingException e) {
+ jbpmCfgResource =
+ (String) initial.lookup("java:comp/env/JbpmCfgResource");
+ }
+ catch (NamingException e) {
log.debug("couldn't find configuration property JbpmCfgResource through JNDI");
}
if (log.isDebugEnabled()) {
- if (jbpmCfgResource==null) {
+ if (jbpmCfgResource == null) {
log.debug("getting default jbpm configuration resource (jbpm.cfg.xml)");
- } else {
- log.debug("getting jbpm configuration from resource "+jbpmCfgResource);
}
+ else {
+ log.debug("getting jbpm configuration from resource " + jbpmCfgResource);
+ }
}
jbpmConfiguration = JbpmConfiguration.getInstance(jbpmCfgResource);
@@ -150,11 +151,14 @@
if (txService.isRollbackOnly()) {
sessionContext.setRollbackOnly();
}
- } catch (RuntimeException e) {
+ }
+ catch (RuntimeException e) {
throw e;
- } catch (Exception e) {
+ }
+ catch (Exception e) {
throw new JbpmException("failed to execute " + command, e);
- } finally {
+ }
+ finally {
jbpmContext.close();
}
return result;
@@ -169,9 +173,11 @@
jbpmConfiguration = null;
}
- public void ejbActivate() {}
+ public void ejbActivate() {
+ }
- public void ejbPassivate() {}
+ public void ejbPassivate() {
+ }
private static final Log log = LogFactory.getLog(CommandServiceBean.class);
}
Modified: jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/ejb/impl/ExecuteJobCommand.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/ejb/impl/ExecuteJobCommand.java 2010-01-26 18:45:01 UTC (rev 6136)
+++ jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/ejb/impl/ExecuteJobCommand.java 2010-01-27 07:59:50 UTC (rev 6137)
@@ -21,17 +21,11 @@
*/
package org.jbpm.ejb.impl;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
import org.jbpm.JbpmContext;
-import org.jbpm.JbpmException;
import org.jbpm.command.Command;
+import org.jbpm.command.CommandService;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.job.Job;
-import org.jbpm.persistence.db.DbPersistenceService;
/**
* Individual job processing command.
@@ -72,27 +66,24 @@
return job;
}
- static void executeJob(Job job, JbpmContext jbpmContext) {
- log.debug("executing " + job);
+ private static void executeJob(Job job, JbpmContext jbpmContext)
+ throws Exception {
try {
if (job.execute(jbpmContext)) {
jbpmContext.getJobSession().deleteJob(job);
}
}
catch (Exception e) {
- log.debug("exception while executing " + job, e);
- if (!DbPersistenceService.isPersistenceException(e)) {
- StringWriter memoryWriter = new StringWriter();
- e.printStackTrace(new PrintWriter(memoryWriter));
- job.setException(memoryWriter.toString());
- }
- else {
- // prevent unsafe use of the session after an exception occurs
- throw e instanceof RuntimeException ? (RuntimeException) e :
- new JbpmException("failed to execute " + job, e);
- }
+ jbpmContext.setRollbackOnly();
+ saveJobException(job, jbpmContext, e);
}
}
- private static Log log = LogFactory.getLog(ExecuteJobCommand.class);
+ private static void saveJobException(Job job, JbpmContext jbpmContext,
+ Exception exception) {
+ CommandService commandService =
+ (CommandService) jbpmContext.getServices().getService("command");
+ commandService.execute(new SaveJobExceptionCommand(job.getId(), exception));
+ }
+
}
Added: jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/ejb/impl/SaveJobExceptionCommand.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/ejb/impl/SaveJobExceptionCommand.java (rev 0)
+++ jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/ejb/impl/SaveJobExceptionCommand.java 2010-01-27 07:59:50 UTC (rev 6137)
@@ -0,0 +1,66 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.ejb.impl;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import org.jbpm.JbpmContext;
+import org.jbpm.command.Command;
+import org.jbpm.command.CommandService;
+import org.jbpm.db.JobSession;
+import org.jbpm.job.Job;
+
+/**
+ * @author Alejandro Guizar
+ */
+public class SaveJobExceptionCommand implements Command {
+
+ private final long jobId;
+ private final Exception exception;
+
+ private static final long serialVersionUID = 1L;
+
+ public SaveJobExceptionCommand(long jobId, Exception exception) {
+ this.jobId = jobId;
+ this.exception = exception;
+ }
+
+ public Object execute(JbpmContext jbpmContext) throws Exception {
+ JobSession jobSession = jbpmContext.getJobSession();
+ Job job = jobSession.loadJob(jobId);
+
+ StringWriter out = new StringWriter();
+ exception.printStackTrace(new PrintWriter(out));
+ job.setException(out.toString());
+
+ int retries = job.getRetries();
+ if (retries > 0) {
+ job.setRetries(retries - 1);
+ CommandService commandService = (CommandService) jbpmContext.getServices()
+ .getService("command");
+ commandService.execute(new ExecuteJobCommand(jobId));
+ }
+ return job;
+ }
+
+}
Property changes on: jbpm3/branches/jbpm-3.2-soa/modules/enterprise/src/main/java/org/jbpm/ejb/impl/SaveJobExceptionCommand.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ native
14 years, 3 months
JBoss JBPM SVN: r6136 - jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/bpmn/usertask.
by do-not-reply@jboss.org
Author: jbarrez
Date: 2010-01-26 13:45:01 -0500 (Tue, 26 Jan 2010)
New Revision: 6136
Added:
jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/bpmn/usertask/UserTaskTest.java
Log:
User Task test wasn't committed yet
Added: jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/bpmn/usertask/UserTaskTest.java
===================================================================
--- jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/bpmn/usertask/UserTaskTest.java (rev 0)
+++ jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/bpmn/usertask/UserTaskTest.java 2010-01-26 18:45:01 UTC (rev 6136)
@@ -0,0 +1,121 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.examples.bpmn.usertask;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.jbpm.api.NewDeployment;
+import org.jbpm.api.ProcessInstance;
+import org.jbpm.api.task.Task;
+import org.jbpm.test.JbpmTestCase;
+
+
+/**
+ * @author Joram Barrez
+ */
+public class UserTaskTest extends JbpmTestCase {
+
+ private static String[] PROCESS_LOCATIONS =
+ {"org/jbpm/examples/bpmn/task/usertask/user_task_potential_owner_user.bpmn.xml",
+ "org/jbpm/examples/bpmn/task/usertask/user_task_potential_owner_group.bpmn.xml",
+ "org/jbpm/examples/bpmn/task/usertask/user_task_human_performer_user.bpmn.xml",
+ "org/jbpm/examples/bpmn/task/usertask/user_task_human_performer_variable.bpmn.xml"};
+
+ private static final String PETER = "peter";
+ private static final String MARY = "mary";
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ for (String processLocation: PROCESS_LOCATIONS) {
+ NewDeployment deployment = repositoryService.createDeployment();
+ deployment.addResourceFromClasspath(processLocation);
+ registerDeployment(deployment.deploy());
+ }
+
+ identityService.createGroup("management");
+
+ identityService.createUser(PETER, "Peter", "Pan");
+ identityService.createMembership(PETER, "management");
+
+ identityService.createUser(MARY, "Mary", "Littlelamb");
+ identityService.createMembership(MARY, "management");
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ identityService.deleteGroup("management");
+ identityService.deleteUser(PETER);
+ identityService.deleteUser(MARY);
+ super.tearDown();
+ }
+
+ public void testPotentialOwnerUser() {
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("userTaskPotentialOwnerUser");
+ Task task = taskService.createTaskQuery().candidate(PETER).uniqueResult();
+ assertEquals("My User task", task.getName());
+ taskService.completeTask(task.getId());
+ assertProcessInstanceEnded(processInstance);
+ }
+
+ public void testPotentialOwnerGroup() {
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("userTaskPotentialOwnerGroup");
+
+ // Peter and Mary are both part of management, so they both should see the task
+ List<Task> tasks = taskService.findGroupTasks(PETER);
+ assertEquals(1, tasks.size());
+ tasks = taskService.findGroupTasks(MARY);
+ assertEquals(1, tasks.size());
+
+ // Mary claims the task
+ Task task = tasks.get(0);
+ taskService.takeTask(task.getId(), MARY);
+ assertNull(taskService.createTaskQuery().candidate(PETER).uniqueResult());
+
+ taskService.completeTask(task.getId());
+ assertProcessInstanceEnded(processInstance);
+ }
+
+ public void testHumanPerformerUser() {
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("userTaskHumanPerformerUser");
+ Task task = taskService.findPersonalTasks(MARY).get(0);
+ assertNotNull(task);
+ taskService.completeTask(task.getId());
+ assertProcessInstanceEnded(processInstance);
+ }
+
+ public void testHumanPerformerVariableExpression() {
+ Map<String, Object> variables = new HashMap<String, Object>();
+ variables.put("user", PETER);
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("userTaskHumanPerformerVariable", variables);
+ Task task = taskService.createTaskQuery().assignee(PETER).uniqueResult();
+ assertNotNull(task);
+ assertNull(taskService.createTaskQuery().assignee(MARY).uniqueResult());
+ taskService.completeTask(task.getId());
+ assertProcessInstanceEnded(processInstance);
+ }
+
+
+}
14 years, 3 months
JBoss JBPM SVN: r6135 - in jbpm4/trunk/modules: bpmn/src/main/java/org/jbpm/bpmn/flownodes and 15 other directories.
by do-not-reply@jboss.org
Author: jbarrez
Date: 2010-01-26 13:44:04 -0500 (Tue, 26 Jan 2010)
New Revision: 6135
Added:
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/TimerStartEventActivity.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/DeleteJobCmd.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/PeriodicStartProcessTimer.java
jbpm4/trunk/modules/test-base/src/main/java/org/jbpm/test/util/
jbpm4/trunk/modules/test-base/src/main/java/org/jbpm/test/util/DateUtils.java
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/startevent/
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/startevent/TimerStartEventTest.java
Removed:
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/TimerStartEvent.java
Modified:
jbpm4/trunk/modules/api/src/main/java/org/jbpm/api/ManagementService.java
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/StartEventBinding.java
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/parser/BpmnParser.java
jbpm4/trunk/modules/devguide/src/main/docbook/en/modules/ch03-Bpmn2.xml
jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/TaskActivity.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cal/CronExpression.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cal/Duration.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/TimerImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/JobExecutorTimerSession.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ScopeInstanceImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/svc/ManagementServiceImpl.java
jbpm4/trunk/modules/pvm/src/main/resources/jbpm.execution.hbm.xml
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/intermediatecatch/IntermediateCatchTimerEventTest.java
Log:
JBPM-2722: impl of timer start event + basic test coverage
Modified: jbpm4/trunk/modules/api/src/main/java/org/jbpm/api/ManagementService.java
===================================================================
--- jbpm4/trunk/modules/api/src/main/java/org/jbpm/api/ManagementService.java 2010-01-26 18:25:52 UTC (rev 6134)
+++ jbpm4/trunk/modules/api/src/main/java/org/jbpm/api/ManagementService.java 2010-01-26 18:44:04 UTC (rev 6135)
@@ -39,4 +39,10 @@
/** search for jobs */
JobQuery createJobQuery();
+
+ /**
+ * Deletes the job with the given id.
+ * @return True if the deletion was succesful.
+ */
+ boolean deleteJob(long jobId);
}
Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/StartEventBinding.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/StartEventBinding.java 2010-01-26 18:25:52 UTC (rev 6134)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/StartEventBinding.java 2010-01-26 18:44:04 UTC (rev 6135)
@@ -23,7 +23,7 @@
import org.jbpm.bpmn.model.BpmnProcessDefinition;
import org.jbpm.bpmn.parser.BpmnParser;
-import org.jbpm.pvm.internal.job.JobImpl;
+import org.jbpm.pvm.internal.job.PeriodicStartProcessTimer;
import org.jbpm.pvm.internal.model.ActivityImpl;
import org.jbpm.pvm.internal.model.TimerDefinitionImpl;
import org.jbpm.pvm.internal.util.XmlUtil;
@@ -50,10 +50,10 @@
parse.addProblem("multiple start events not yet supported", element);
}
- String id = XmlUtil.attribute(element, "id");
+ String id = XmlUtil.attribute(element, "id", true, parse);
Element eventDefinition = XmlUtil.element(element);
if (eventDefinition != null && "timerEventDefinition".equals(eventDefinition.getNodeName())) {
- return createTimerStartEvent((BpmnParser) parser, parse, id);
+ return createTimerStartEvent(processDefinition, eventDefinition, id, (BpmnParser) parser, parse);
} else if (eventDefinition != null){
parse.addProblem("Invalid eventDefinition type : " + eventDefinition.getNodeName());
}
@@ -61,13 +61,28 @@
return new NoneStartEventActivity(); // default
}
- protected TimerStartEvent createTimerStartEvent(BpmnParser parser, Parse parse, String eventId) {
- TimerStartEvent timerStartEvent = new TimerStartEvent();
+ protected TimerStartEventActivity createTimerStartEvent(BpmnProcessDefinition processDefinition,
+ Element timerEventDefinition, String eventId, BpmnParser parser, Parse parse) {
- TimerDefinitionImpl timerDefinition = parser.parseTimerEventDefinition(null, parse, eventId);
+ TimerStartEventActivity timerStartEvent = new TimerStartEventActivity();
+ TimerDefinitionImpl timerDefinition = parser.parseTimerEventDefinition(timerEventDefinition, parse, eventId);
- // schedule job
+ if (timerDefinition == null) { // problem explanation will already be added to parse, no need to do it here
+ return null;
+ }
+ PeriodicStartProcessTimer startProcessTimer = new PeriodicStartProcessTimer();
+ startProcessTimer.setProcessDefinitionName(processDefinition.getName());
+
+ if (timerDefinition.getDueDate() != null) {
+ startProcessTimer.setDuedate(timerDefinition.getDueDate());
+ } else if (timerDefinition.getDueDateDescription() != null) {
+ startProcessTimer.setIntervalExpression(timerDefinition.getDueDateDescription());
+ } else if (timerDefinition.getCronExpression() != null) {
+ startProcessTimer.setIntervalExpression(timerDefinition.getCronExpression());
+ }
+
+ startProcessTimer.schedule();
return timerStartEvent;
}
Deleted: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/TimerStartEvent.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/TimerStartEvent.java 2010-01-26 18:25:52 UTC (rev 6134)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/TimerStartEvent.java 2010-01-26 18:44:04 UTC (rev 6135)
@@ -1,45 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jbpm.bpmn.flownodes;
-
-import org.jbpm.api.activity.ActivityExecution;
-import org.jbpm.pvm.internal.model.ExecutionImpl;
-
-
-/**
- * @author Joram Barrez
- */
-public class TimerStartEvent extends BpmnActivity {
-
- private static final long serialVersionUID = 1L;
-
- public void execute(ActivityExecution execution) {
-
- }
-
- public void execute(ExecutionImpl execution) {
-
- }
-
-
-
-}
Copied: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/TimerStartEventActivity.java (from rev 6124, jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/TimerStartEvent.java)
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/TimerStartEventActivity.java (rev 0)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/TimerStartEventActivity.java 2010-01-26 18:44:04 UTC (rev 6135)
@@ -0,0 +1,35 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.bpmn.flownodes;
+
+
+
+/**
+ * @author Joram Barrez
+ */
+public class TimerStartEventActivity extends NoneStartEventActivity {
+
+ private static final long serialVersionUID = 1L;
+
+ // At the moment no difference with a none start event. Could change in the future.
+
+}
Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/parser/BpmnParser.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/parser/BpmnParser.java 2010-01-26 18:25:52 UTC (rev 6134)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/parser/BpmnParser.java 2010-01-26 18:44:04 UTC (rev 6135)
@@ -111,7 +111,7 @@
parse.contextStackPush(processDefinition);
try {
- String id = XmlUtil.attribute(processElement, "id", false, parse);
+ String id = XmlUtil.attribute(processElement, "id", true, parse);
String name = XmlUtil.attribute(processElement, "name", false, parse);
if (id != null && !"".equals(id)) {
@@ -335,6 +335,11 @@
}
/**
+ * Parses a <timerEventDefinition> element:
+ * * sets dueDate if 'timeDate' is used
+ * * sets duedateDescription if a duration expression is used
+ * * set cronExpression if a cron expression is used
+ *
* @param timerEventDefinitionElement The XML element that defines the timer definition
* @param activity The activity on which the timer definition must be created
* @param eventId The id of the event on which the timer is defined
@@ -346,7 +351,7 @@
if ( (timeDate != null && timeCycle != null)
|| (timeDate == null && timeCycle == null) ) {
- parse.addProblem("Intermediate catch event '" + eventId +
+ parse.addProblem("timerEventDefinition for event '" + eventId +
"' requires either a timeDate or a timeCycle definition (but not both)");
return null;
}
@@ -363,18 +368,6 @@
return timerDefinition;
}
-
- protected void parseTimeCycle(String catchEventId, Parse parse, Element timeCycle, TimerDefinitionImpl timerDefinition) {
- String cycleExpression = timeCycle.getTextContent();
- if (Duration.isValidExpression(cycleExpression)) {
- timerDefinition.setDueDateDescription(cycleExpression);
- } else if (CronExpression.isValidExpression(cycleExpression)) {
- timerDefinition.setCronExpression(cycleExpression);
- } else {
- parse.addProblem("couldn't parse timeDate duration '"+ cycleExpression
- + "' on intermediate catch timer event " + catchEventId);
- }
- }
protected void parseTimeDate(String catchEventId, Parse parse, Element timeDate, TimerDefinitionImpl timerDefinition) {
String dueDateTime = timeDate.getTextContent();
@@ -391,6 +384,18 @@
+ "' on intermediate catch timer event " + catchEventId, e);
}
}
+
+ protected void parseTimeCycle(String catchEventId, Parse parse, Element timeCycle, TimerDefinitionImpl timerDefinition) {
+ String cycleExpression = timeCycle.getTextContent();
+ if (Duration.isValidExpression(cycleExpression)) {
+ timerDefinition.setDueDateDescription(cycleExpression);
+ } else if (CronExpression.isValidExpression(cycleExpression)) {
+ timerDefinition.setCronExpression(cycleExpression);
+ } else {
+ parse.addProblem("couldn't parse timeDate duration '"+ cycleExpression
+ + "' on intermediate catch timer event " + catchEventId);
+ }
+ }
public void parseResources(Element documentElement, Parse parse, BpmnProcessDefinition processDefinition) {
Modified: jbpm4/trunk/modules/devguide/src/main/docbook/en/modules/ch03-Bpmn2.xml
===================================================================
--- jbpm4/trunk/modules/devguide/src/main/docbook/en/modules/ch03-Bpmn2.xml 2010-01-26 18:25:52 UTC (rev 6134)
+++ jbpm4/trunk/modules/devguide/src/main/docbook/en/modules/ch03-Bpmn2.xml 2010-01-26 18:44:04 UTC (rev 6135)
@@ -242,8 +242,9 @@
If a name is defined for the process element, it is be used as <emphasis role="bold">key</emphasis>
for that process (ie. starting a process can be done by calling executionService.startProcessInstanceByKey("myBusinessProcess").
If no name is defined, the id will be used as key. So having only an id defined, will allow
- to start a process instance using that id. Note that for a key the same rules apply as with
- JPDL: whitespace and non alpha-numeric characters are replace by an underscore.
+ to start a process instance using that id. So basically, name and key are of equivalent
+ in usage, for example to search process definitions. Note that for a key the same rules apply as with
+ JPDL: whitespace and non alpha-numeric characters are replaced by an underscore.
</para>
</section>
Modified: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/TaskActivity.java
===================================================================
--- jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/TaskActivity.java 2010-01-26 18:25:52 UTC (rev 6134)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/TaskActivity.java 2010-01-26 18:44:04 UTC (rev 6135)
@@ -27,10 +27,10 @@
import org.jbpm.api.JbpmException;
import org.jbpm.api.activity.ActivityExecution;
import org.jbpm.api.model.Transition;
+import org.jbpm.pvm.internal.cal.Duration;
import org.jbpm.pvm.internal.env.EnvironmentImpl;
import org.jbpm.pvm.internal.history.HistoryEvent;
import org.jbpm.pvm.internal.history.events.TaskActivityStart;
-import org.jbpm.pvm.internal.job.TimerImpl;
import org.jbpm.pvm.internal.model.ActivityImpl;
import org.jbpm.pvm.internal.model.ExecutionImpl;
import org.jbpm.pvm.internal.script.ScriptManager;
@@ -85,7 +85,7 @@
// calculate the due date of the task based on the due date duration
String dueDateDescription = taskDefinition.getDueDateDescription();
if (dueDateDescription != null) {
- task.setDuedate(TimerImpl.calculateDueDate(dueDateDescription));
+ task.setDuedate(Duration.calculateDueDate(dueDateDescription));
}
// save task so that TaskDbSession.findTaskByExecution works for assign event listeners
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cal/CronExpression.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cal/CronExpression.java 2010-01-26 18:25:52 UTC (rev 6134)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cal/CronExpression.java 2010-01-26 18:44:04 UTC (rev 6135)
@@ -360,7 +360,7 @@
try {
new CronExpression(cronExpression);
- } catch (ParseException pe) {
+ } catch (Exception pe) {
return false;
}
@@ -746,7 +746,7 @@
return i;
}
- public String getCronExpression() {
+ public String getCronExpressionString() {
return cronExpression;
}
@@ -1502,7 +1502,7 @@
public Object clone() {
CronExpression copy = null;
try {
- copy = new CronExpression(getCronExpression());
+ copy = new CronExpression(getCronExpressionString());
copy.setTimeZone(getTimeZone());
} catch (ParseException ex) { // never happens since the source is valid...
throw new IncompatibleClassChangeError("Not Cloneable.");
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cal/Duration.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cal/Duration.java 2010-01-26 18:25:52 UTC (rev 6134)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cal/Duration.java 2010-01-26 18:44:04 UTC (rev 6135)
@@ -22,12 +22,21 @@
package org.jbpm.pvm.internal.cal;
import java.io.Serializable;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.jbpm.api.JbpmException;
+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.
@@ -59,6 +68,14 @@
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*");
/** constructor for persistence. note that this type is to be immutable. */
protected Duration() {
@@ -91,7 +108,56 @@
}
return true;
}
+
+ public static Date calculateDueDate(String durationExpression) {
+ Date dueDate;
+ // is due date description in date_expression +|- fixed_duration format?
+ Matcher dateDurationMatcher = dateDurationPattern.matcher(durationExpression);
+ if (dateDurationMatcher.matches()) {
+ // evaluate date expression
+ String dateExpression = dateDurationMatcher.group(1);
+ Object result = ScriptManager.getScriptManager().evaluateExpression(dateExpression, null);
+ // convert result to Date
+ if (result instanceof Date) {
+ dueDate = (Date) result;
+ } else if (result instanceof Calendar) {
+ Calendar calendar = (Calendar) result;
+ dueDate = calendar.getTime();
+ } else if (result instanceof String) {
+ try {
+ // TODO use a locale-sensitive date format?
+ dueDate = new SimpleDateFormat(dateFormat).parse((String) result);
+ } catch (ParseException e) {
+ throw new JbpmException("invalid base date: " + result, e);
+ }
+ } else {
+ throw new JbpmException("invalid base date: " + result);
+ }
+ // fixed duration is optional
+ String operationString = dateDurationMatcher.group(2);
+ if (operationString != null) {
+ char operation = operationString.charAt(0);
+ String duration = dateDurationMatcher.group(3);
+ // add duration to base date
+ BusinessCalendar businessCalendar = EnvironmentImpl.getFromCurrent(BusinessCalendar.class);
+ dueDate = operation == '+' ? businessCalendar.add(dueDate, duration)
+ : businessCalendar.subtract(dueDate, duration);
+ }
+ } else {
+ // is due date description in fixed_duration format?
+ Matcher durationMatcher = durationPattern.matcher(durationExpression);
+ if (durationMatcher.matches()) {
+ // add duration to current date
+ dueDate = EnvironmentImpl.getFromCurrent(BusinessCalendar.class).add(
+ Clock.getTime(), durationMatcher.group(1));
+ } else {
+ throw new JbpmException("invalid due date duration: " + durationExpression);
+ }
+ }
+ return dueDate;
+ }
+
public Duration(boolean isBusinessTime, int millis, int seconds, int minutes, int hours, int days, int weeks, int months, int years) {
this.isBusinessTime = isBusinessTime;
this.millis = millis;
Added: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/DeleteJobCmd.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/DeleteJobCmd.java (rev 0)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/cmd/DeleteJobCmd.java 2010-01-26 18:44:04 UTC (rev 6135)
@@ -0,0 +1,56 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.pvm.internal.cmd;
+
+import org.jbpm.api.JbpmException;
+import org.jbpm.api.cmd.Environment;
+import org.jbpm.pvm.internal.job.JobImpl;
+import org.jbpm.pvm.internal.session.DbSession;
+
+
+/**
+ * @author Joram Barrez
+ */
+public class DeleteJobCmd extends AbstractCommand<Boolean>{
+
+ private static final long serialVersionUID = 1L;
+
+ protected long jobId;
+
+ public DeleteJobCmd(long jobId) {
+ this.jobId = jobId;
+ }
+
+ public Boolean execute(Environment environment) throws Exception {
+ DbSession dbSession = environment.get(DbSession.class);
+ if (dbSession==null) {
+ throw new JbpmException("no " + DbSession.class.getName() + " found in environment");
+ }
+ JobImpl job = dbSession.get(JobImpl.class, jobId);
+ if (job != null) {
+ dbSession.delete(job);
+ return true;
+ }
+ return false;
+ }
+
+}
Added: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/PeriodicStartProcessTimer.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/PeriodicStartProcessTimer.java (rev 0)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/PeriodicStartProcessTimer.java 2010-01-26 18:44:04 UTC (rev 6135)
@@ -0,0 +1,200 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.pvm.internal.job;
+
+import java.text.ParseException;
+
+import org.jbpm.api.ExecutionService;
+import org.jbpm.api.JbpmException;
+import org.jbpm.api.RepositoryService;
+import org.jbpm.api.cmd.Environment;
+import org.jbpm.internal.log.Log;
+import org.jbpm.pvm.internal.cal.CronExpression;
+import org.jbpm.pvm.internal.cal.Duration;
+import org.jbpm.pvm.internal.env.EnvironmentImpl;
+import org.jbpm.pvm.internal.session.DbSession;
+import org.jbpm.pvm.internal.util.Clock;
+
+
+/**
+ * Job that periodically startes a new process instance of a given process definition.
+ *
+ * @author Joram Barrez
+ */
+public class PeriodicStartProcessTimer extends TimerImpl {
+
+ private static final long serialVersionUID = 1L;
+
+ private static final Log LOG = Log.getLog(PeriodicStartProcessTimer.class.getName());
+
+ // Override execution logic of regular timer
+ public Boolean execute(Environment environment) throws Exception {
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Periodic start process triggered at " + Clock.getTime());
+ }
+
+ boolean processDefinitionExists = processDefinitionExists(environment);
+ boolean newDueDateCalculated = false;
+
+ if (processDefinitionExists) {
+ startProcessInstance(environment);
+ newDueDateCalculated = calculateDueDate(environment);
+ }
+
+ if (!processDefinitionExists || !newDueDateCalculated) {
+ deleteThisJob(environment);
+ } else {
+ saveThisJob(environment);
+ }
+
+ return null;
+ }
+
+ protected boolean processDefinitionExists(Environment environment) {
+ RepositoryService repositoryService = environment.get(RepositoryService.class);
+ boolean processExists = !repositoryService.createProcessDefinitionQuery()
+ .processDefinitionName(getProcessDefinitionName()).list().isEmpty();
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Process definition with name " + getProcessDefinitionName() + " still exists: " + processExists);
+ }
+
+ return processExists;
+ }
+
+ protected void startProcessInstance(Environment environment) {
+ ExecutionService executionService = environment.get(ExecutionService.class);
+ if (executionService == null) {
+ throw new JbpmException("no " + ExecutionService.class.getName() + " in environment");
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Starting a new process instance for process definition with name " + getProcessDefinitionName());
+ }
+
+ executionService.startProcessInstanceByKey(getProcessDefinitionName());
+ }
+
+ protected boolean calculateDueDate(Environment environment) throws ParseException {
+
+ if (getIntervalExpression() != null && Duration.isValidExpression(getIntervalExpression())) {
+ duedate = Duration.calculateDueDate(getIntervalExpression());
+ } else if (getIntervalExpression() != null && CronExpression.isValidExpression(getIntervalExpression())) {
+ duedate = new CronExpression(getIntervalExpression()).getNextValidTimeAfter(Clock.getTime());
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("No next duedate calculated for periodic start process job " +
+ "with intervalExpression " + getIntervalExpression());
+ }
+ return false;
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Next process start duedate: " + duedate);
+ }
+
+ return true;
+ }
+
+ protected void saveThisJob(Environment environment) {
+ DbSession dbSession = environment.get(DbSession.class);
+ if (dbSession == null) {
+ throw new JbpmException("no " + DbSession.class.getName() + " in environment");
+ }
+ dbSession.save(this);
+ }
+
+ protected void deleteThisJob(Environment environment) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Deleting periodic start job for process definition with name " + getProcessDefinitionName());
+ }
+
+ DbSession dbSession = environment.get(DbSession.class);
+ if (dbSession == null) {
+ throw new JbpmException("no " + DbSession.class.getName() + " in environment");
+ }
+ dbSession.delete(this);
+ }
+
+ @Override
+ public void schedule() {
+ if (duedate == null && getIntervalExpression() != null) {
+ try {
+ calculateDueDate(EnvironmentImpl.getCurrent());
+ } catch (ParseException e) {
+ throw new JbpmException("Cannot parse intervalExpression", e);
+ }
+ } else if (duedate == null) {
+ throw new JbpmException("Cannot schedule periodic start process timer: " +
+ "no duedate or intervalExpression set");
+ }
+ super.schedule();
+ }
+
+ @Override
+ public void validate() {
+ if (getProcessDefinitionName() == null) {
+ throw new JbpmException("No process definition name set for periodic start process timer");
+ }
+ if (duedate == null && getIntervalExpression() == null) {
+ throw new JbpmException("No duedate or intervalExpression found for periodic start process timer");
+ }
+ }
+
+ public String getProcessDefinitionName() {
+ return signalName;
+ }
+
+ public void setProcessDefinitionName(String processDefinitionName) {
+ this.signalName = processDefinitionName;
+ }
+
+ public String getIntervalExpression() {
+ return eventName;
+ }
+
+ /**
+ * Sets the expression that will define the interval between
+ * two sequential process starts by this job.
+ *
+ * Possible expression types are {@link Duration} and {@link CronExpression}.
+ */
+ public void setIntervalExpression(String intervalExpression) {
+ this.eventName = intervalExpression;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder strb = new StringBuilder();
+ strb.append("PeriodicProcessStart[");
+ if (duedate != null) {
+ strb.append(duedate);
+ }
+ if (getIntervalExpression() != null) {
+ strb.append("| " + getIntervalExpression());
+ }
+ strb.append("]");
+ return strb.toString();
+ }
+
+}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/TimerImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/TimerImpl.java 2010-01-26 18:25:52 UTC (rev 6134)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/job/TimerImpl.java 2010-01-26 18:44:04 UTC (rev 6135)
@@ -21,24 +21,19 @@
*/
package org.jbpm.pvm.internal.job;
-import java.text.ParseException;
import java.text.SimpleDateFormat;
-import java.util.Calendar;
import java.util.Date;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import org.jbpm.api.JbpmException;
import org.jbpm.api.cmd.Environment;
import org.jbpm.api.job.Timer;
import org.jbpm.internal.log.Log;
-import org.jbpm.pvm.internal.cal.BusinessCalendar;
+import org.jbpm.pvm.internal.cal.Duration;
import org.jbpm.pvm.internal.env.EnvironmentImpl;
import org.jbpm.pvm.internal.id.DbidGenerator;
import org.jbpm.pvm.internal.jobexecutor.JobAddedNotification;
import org.jbpm.pvm.internal.jobexecutor.JobExecutor;
import org.jbpm.pvm.internal.model.ObservableElement;
-import org.jbpm.pvm.internal.script.ScriptManager;
import org.jbpm.pvm.internal.session.DbSession;
import org.jbpm.pvm.internal.session.TimerSession;
import org.jbpm.pvm.internal.tx.Transaction;
@@ -58,10 +53,6 @@
private static final Log log = Log.getLog(TimerImpl.class.getName());
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*");
protected String signalName;
protected String eventName;
@@ -80,62 +71,13 @@
public void setDueDateDescription(String dueDateDescription) {
if (dueDateDescription != null) {
- duedate = calculateDueDate(dueDateDescription);
+ duedate = Duration.calculateDueDate(dueDateDescription);
}
}
- public static Date calculateDueDate(String dueDateDescription) {
- Date dueDate;
- // is due date description in date_expression +|- fixed_duration format?
- Matcher dateDurationMatcher = dateDurationPattern.matcher(dueDateDescription);
- if (dateDurationMatcher.matches()) {
- // evaluate date expression
- String dateExpression = dateDurationMatcher.group(1);
- Object result = ScriptManager.getScriptManager().evaluateExpression(dateExpression, null);
- // convert result to Date
- if (result instanceof Date) {
- dueDate = (Date) result;
- } else if (result instanceof Calendar) {
- Calendar calendar = (Calendar) result;
- dueDate = calendar.getTime();
- } else if (result instanceof String) {
- try {
- // TODO use a locale-sensitive date format?
- dueDate = new SimpleDateFormat(dateFormat).parse((String) result);
- } catch (ParseException e) {
- throw new JbpmException("invalid base date: " + result, e);
- }
- } else {
- throw new JbpmException("invalid base date: " + result);
- }
-
- // fixed duration is optional
- String operationString = dateDurationMatcher.group(2);
- if (operationString != null) {
- char operation = operationString.charAt(0);
- String duration = dateDurationMatcher.group(3);
- // add duration to base date
- BusinessCalendar businessCalendar = EnvironmentImpl.getFromCurrent(BusinessCalendar.class);
- dueDate = operation == '+' ? businessCalendar.add(dueDate, duration)
- : businessCalendar.subtract(dueDate, duration);
- }
- } else {
- // is due date description in fixed_duration format?
- Matcher durationMatcher = durationPattern.matcher(dueDateDescription);
- if (durationMatcher.matches()) {
- // add duration to current date
- dueDate = EnvironmentImpl.getFromCurrent(BusinessCalendar.class).add(
- Clock.getTime(), durationMatcher.group(1));
- } else {
- throw new JbpmException("invalid due date duration: " + dueDateDescription);
- }
- }
- return dueDate;
- }
-
public Boolean execute(Environment environment) throws Exception {
if (log.isDebugEnabled()) log.debug("executing " + this);
-
+
if (environment==null) {
throw new JbpmException("environment is null");
}
@@ -189,6 +131,18 @@
return deleteThisJob;
}
+
+ public void validate() {
+ if (getExecution() == null) {
+ throw new JbpmException("timer has no execution specified");
+ }
+ if ((getSignalName() == null) && (getEventName() == null)) {
+ throw new JbpmException("timer has no signalName or eventName specified");
+ }
+ if (getDueDate() == null) {
+ throw new JbpmException("timer scheduled at null date");
+ }
+ }
public String toString() {
StringBuilder text = new StringBuilder();
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/JobExecutorTimerSession.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/JobExecutorTimerSession.java 2010-01-26 18:25:52 UTC (rev 6134)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/jobexecutor/JobExecutorTimerSession.java 2010-01-26 18:44:04 UTC (rev 6135)
@@ -49,10 +49,9 @@
public void schedule(Timer timer) {
if (timer == null) throw new JbpmException("null timer scheduled");
- if (timer.getExecution() == null) throw new JbpmException("timer has no execution specified");
- if ((timer.getSignalName() == null) && (timer.getEventName() == null)) throw new JbpmException("timer has no signalName or eventName specified");
- if (timer.getDueDate() == null) throw new JbpmException("timer scheduled at null date");
-
+ TimerImpl timerImpl = (TimerImpl) timer;
+ timerImpl.validate();
+
log.debug("scheduling " + timer);
session.save(timer);
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ScopeInstanceImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ScopeInstanceImpl.java 2010-01-26 18:25:52 UTC (rev 6134)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ScopeInstanceImpl.java 2010-01-26 18:44:04 UTC (rev 6135)
@@ -307,8 +307,7 @@
if (timer.getDuedate() == null && timerDefinition.getCronExpression() != null) {
try {
- timer.setDuedate(new CronExpression(timerDefinition.getCronExpression())
- .getNextValidTimeAfter(Clock.getTime()));
+ timer.setDuedate(new CronExpression(timerDefinition.getCronExpression()).getNextValidTimeAfter(Clock.getTime()));
} catch (ParseException pe) {
throw new JbpmException("Can't parse cron expression " + timerDefinition.getCronExpression(), pe);
}
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/svc/ManagementServiceImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/svc/ManagementServiceImpl.java 2010-01-26 18:25:52 UTC (rev 6134)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/svc/ManagementServiceImpl.java 2010-01-26 18:44:04 UTC (rev 6135)
@@ -24,6 +24,7 @@
import org.jbpm.api.JobQuery;
import org.jbpm.api.ManagementService;
import org.jbpm.pvm.internal.cmd.CreateJobQueryCmd;
+import org.jbpm.pvm.internal.cmd.DeleteJobCmd;
import org.jbpm.pvm.internal.cmd.ExecuteJobCmd;
import org.jbpm.pvm.internal.query.JobQueryImpl;
@@ -42,4 +43,8 @@
query.setCommandService(commandService);
return query;
}
+
+ public boolean deleteJob(long jobId) {
+ return commandService.execute(new DeleteJobCmd(jobId));
+ }
}
Modified: jbpm4/trunk/modules/pvm/src/main/resources/jbpm.execution.hbm.xml
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/resources/jbpm.execution.hbm.xml 2010-01-26 18:25:52 UTC (rev 6134)
+++ jbpm4/trunk/modules/pvm/src/main/resources/jbpm.execution.hbm.xml 2010-01-26 18:44:04 UTC (rev 6135)
@@ -247,8 +247,11 @@
<property name="signalName" column="SIGNAL_" />
<property name="eventName" column="EVENT_" />
<property name="repeat" column="REPEAT_" />
+
+ <subclass name="org.jbpm.pvm.internal.job.PeriodicStartProcessTimer" discriminator-value="PeriodicStartProcess" />
+
</subclass>
-
+
</class>
<!-- ### HibernatePvmDbSession QUERIES ################################## -->
Added: jbpm4/trunk/modules/test-base/src/main/java/org/jbpm/test/util/DateUtils.java
===================================================================
--- jbpm4/trunk/modules/test-base/src/main/java/org/jbpm/test/util/DateUtils.java (rev 0)
+++ jbpm4/trunk/modules/test-base/src/main/java/org/jbpm/test/util/DateUtils.java 2010-01-26 18:44:04 UTC (rev 6135)
@@ -0,0 +1,60 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.test.util;
+
+import java.util.Calendar;
+import java.util.Date;
+
+
+/**
+ * @author Joram Barrez
+ */
+public class DateUtils {
+
+ // No need to instantiate
+ private DateUtils() {}
+
+ public static Date getDate(int day, int month, int year, int hour, int minute, int second) {
+ Calendar cal = Calendar.getInstance();
+ cal.set(Calendar.DAY_OF_MONTH, day);
+ cal.set(Calendar.MONTH, month);
+ cal.set(Calendar.YEAR, year);
+ cal.set(Calendar.HOUR_OF_DAY, hour);
+ cal.set(Calendar.MINUTE, minute);
+ cal.set(Calendar.SECOND, second);
+ cal.set(Calendar.MILLISECOND, 0);
+ return cal.getTime();
+ }
+
+ public static Date getDateAtMidnight(int day, int month, int year) {
+ Calendar cal = Calendar.getInstance();
+ cal.set(Calendar.DAY_OF_MONTH, day);
+ cal.set(Calendar.MONTH, month);
+ cal.set(Calendar.YEAR, year);
+ cal.set(Calendar.HOUR_OF_DAY, 0);
+ cal.set(Calendar.MINUTE, 0);
+ cal.set(Calendar.SECOND, 0);
+ cal.set(Calendar.MILLISECOND, 0);
+ return cal.getTime();
+ }
+
+}
Modified: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/intermediatecatch/IntermediateCatchTimerEventTest.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/intermediatecatch/IntermediateCatchTimerEventTest.java 2010-01-26 18:25:52 UTC (rev 6134)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/intermediatecatch/IntermediateCatchTimerEventTest.java 2010-01-26 18:44:04 UTC (rev 6135)
@@ -30,6 +30,7 @@
import org.jbpm.pvm.internal.util.Clock;
import org.jbpm.test.JbpmTestCase;
import org.jbpm.test.assertion.CollectionAssertions;
+import org.jbpm.test.util.DateUtils;
/**
* @author Joram Barrez
@@ -65,7 +66,7 @@
" </process>" +
"</definitions>";
- private static final String TIMER_CATCH_WITH_TIMECYCLE =
+ private static final String TIMER_CATCH_WITH_TIMECYCLE_DURATION =
"<definitions xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>" +
" <process id='timeCycleProcess'>" +
" <startEvent id='theStart' />" +
@@ -132,8 +133,7 @@
}
public void testInvalidProcess() {
- final String expectedMsg = "Intermediate catch event 'intermediateTimer' requires either a " +
- "timeDate or a timeCycle definition (but not both)";
+ final String expectedMsg = "requires either a timeDate or a timeCycle definition (but not both)";
try {
deployBpmn2XmlString(BAD_PROCESS_1);
fail();
@@ -150,7 +150,7 @@
}
public void testTimeCycleExpression() {
- deployBpmn2XmlString(TIMER_CATCH_WITH_TIMECYCLE);
+ deployBpmn2XmlString(TIMER_CATCH_WITH_TIMECYCLE_DURATION);
long processStartTime = 5000;
Clock.setExplicitTime(new Date(processStartTime));
@@ -173,7 +173,7 @@
CollectionAssertions.assertContainsSameElements(pi.findActiveActivityNames(), "intermediateTimer");
Job timerJob = managementService.createJobQuery().processInstanceId(pi.getId()).uniqueResult();
- Date expectedDueDate = getDateAtMidnight(10, Calendar.OCTOBER, 2099);
+ Date expectedDueDate = DateUtils.getDateAtMidnight(10, Calendar.OCTOBER, 2099);
assertEquals(expectedDueDate.getTime(), timerJob.getDuedate().getTime());
managementService.executeJob(timerJob.getId());
@@ -182,13 +182,13 @@
public void testCronExpression() {
deployBpmn2XmlString(TIMER_CATCH_WITH_CRON_EXPRESSION);
- Clock.setExplicitTime(getDate(20, Calendar.JANUARY, 2010, 0, 1, 1)); // Start on 61 seconds
+ Clock.setExplicitTime(DateUtils.getDate(20, Calendar.JANUARY, 2010, 0, 1, 1)); // Start on 61 seconds
ProcessInstance pi = executionService.startProcessInstanceByKey("timeDateProcess");
CollectionAssertions.assertContainsSameElements(pi.findActiveActivityNames(), "intermediateTimer");
Job timerJob = managementService.createJobQuery().processInstanceId(pi.getId()).uniqueResult();
- assertEquals(getDate(20, Calendar.JANUARY, 2010, 0, 2, 0).getTime(), timerJob.getDuedate().getTime());
+ assertEquals(DateUtils.getDate(20, Calendar.JANUARY, 2010, 0, 2, 0).getTime(), timerJob.getDuedate().getTime());
managementService.executeJob(timerJob.getId());
assertProcessInstanceEnded(pi);
@@ -196,41 +196,19 @@
public void testCronExpression2() {
deployBpmn2XmlString(TIMER_CATCH_WITH_CRON_EXPRESSION_2);
- Clock.setExplicitTime(getDateAtMidnight(21, Calendar.JANUARY, 2010)); // 21/01/2009 is a Thursday
+ Clock.setExplicitTime(DateUtils.getDateAtMidnight(21, Calendar.JANUARY, 2010)); // 21/01/2009 is a Thursday
ProcessInstance pi = executionService.startProcessInstanceByKey("timeDateProcess");
CollectionAssertions.assertContainsSameElements(pi.findActiveActivityNames(), "intermediateTimer");
Job timerJob = managementService.createJobQuery().processInstanceId(pi.getId()).uniqueResult();
- assertEquals(getDate(22, Calendar.JANUARY, 2010, 23, 0, 0).getTime(), timerJob.getDuedate().getTime());
+ assertEquals(DateUtils.getDate(22, Calendar.JANUARY, 2010, 23, 0, 0).getTime(), timerJob.getDuedate().getTime());
managementService.executeJob(timerJob.getId());
assertProcessInstanceEnded(pi);
}
- private Date getDateAtMidnight(int day, int month, int year) {
- Calendar cal = Calendar.getInstance();
- cal.set(Calendar.DAY_OF_MONTH, day);
- cal.set(Calendar.MONTH, month);
- cal.set(Calendar.YEAR, year);
- cal.set(Calendar.HOUR_OF_DAY, 0);
- cal.set(Calendar.MINUTE, 0);
- cal.set(Calendar.SECOND, 0);
- cal.set(Calendar.MILLISECOND, 0);
- return cal.getTime();
- }
-
- private Date getDate(int day, int month, int year, int hour, int minute, int second) {
- Calendar cal = Calendar.getInstance();
- cal.set(Calendar.DAY_OF_MONTH, day);
- cal.set(Calendar.MONTH, month);
- cal.set(Calendar.YEAR, year);
- cal.set(Calendar.HOUR_OF_DAY, hour);
- cal.set(Calendar.MINUTE, minute);
- cal.set(Calendar.SECOND, second);
- cal.set(Calendar.MILLISECOND, 0);
- return cal.getTime();
- }
+
}
Added: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/startevent/TimerStartEventTest.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/startevent/TimerStartEventTest.java (rev 0)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/startevent/TimerStartEventTest.java 2010-01-26 18:44:04 UTC (rev 6135)
@@ -0,0 +1,256 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.bpmn.test.startevent;
+
+import java.util.Calendar;
+
+import org.jbpm.api.JbpmException;
+import org.jbpm.api.ProcessInstanceQuery;
+import org.jbpm.api.job.Job;
+import org.jbpm.pvm.internal.util.Clock;
+import org.jbpm.test.JbpmTestCase;
+import org.jbpm.test.util.DateUtils;
+
+
+/**
+ * @author Joram Barrez
+ */
+public class TimerStartEventTest extends JbpmTestCase {
+
+ private static final String INVALID_PROCESS_1 =
+ "<definitions xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>" +
+ " <process id='invalidProcess1'>" +
+ " <startEvent id='theStart' >" +
+ " <timerEventDefinition />" +
+ " </startEvent>" +
+ " <sequenceFlow id='flow1' sourceRef='theStart' targetRef='theEnd' />" +
+ " <endEvent id='theEnd' />" +
+ " </process>" +
+ "</definitions>";
+
+ private static final String INVALID_PROCESS_2 =
+ "<definitions xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>" +
+ " <process id='invalidProcess1'>" +
+ " <startEvent id='theStart' >" +
+ " <timerEventDefinition >" +
+ " <timeCycle>5 hours</timeCycle>" +
+ " <timeDate>10/10/1985</timeDate>" +
+ " </timerEventDefinition>" +
+ " </startEvent>" +
+ " <sequenceFlow id='flow1' sourceRef='theStart' targetRef='theEnd' />" +
+ " <endEvent id='theEnd' />" +
+ " </process>" +
+ "</definitions>";
+
+ private static final String INVALID_PROCESS_3 =
+ "<definitions xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>" +
+ " <process id='invalidProcess1'>" +
+ " <startEvent id='theStart' >" +
+ " <timerEventDefinition >" +
+ " <timeCycle>5 abcdefghijklmnop</timeCycle>" +
+ " </timerEventDefinition>" +
+ " </startEvent>" +
+ " <sequenceFlow id='flow1' sourceRef='theStart' targetRef='theEnd' />" +
+ " <endEvent id='theEnd' />" +
+ " </process>" +
+ "</definitions>";
+
+ private static final String INVALID_PROCESS_4 =
+ "<definitions xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>" +
+ " <process id='invalidProcess1'>" +
+ " <startEvent id='theStart' >" +
+ " <timerEventDefinition >" +
+ " <timeCycle>Z 0 22 * * ?</timeCycle>" +
+ " </timerEventDefinition>" +
+ " </startEvent>" +
+ " <sequenceFlow id='flow1' sourceRef='theStart' targetRef='theEnd' />" +
+ " <endEvent id='theEnd' />" +
+ " </process>" +
+ "</definitions>";
+
+ private static final String TIMER_START_FIXED_DUEDATE =
+ "<definitions xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>" +
+ " <process id='timerStartFixedDueDate'>" +
+ " <startEvent id='theStart' >" +
+ " <timerEventDefinition >" +
+ " <timeDate>10/10/2099 00:00:00</timeDate>" +
+ " </timerEventDefinition>" +
+ " </startEvent>" +
+ " <sequenceFlow id='flow1' sourceRef='theStart' targetRef='wait' />" +
+ " <receiveTask id='wait' />" +
+ " <sequenceFlow id='flow2' sourceRef='wait' targetRef='theEnd' />" +
+ " <endEvent id='theEnd' />" +
+ " </process>" +
+ "</definitions>";
+
+ private static final String TIMER_START_TIMECYCLE_DURATION =
+ "<definitions xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>" +
+ " <process id='timerStartTimeCycleDuration'>" +
+ " <startEvent id='theStart' >" +
+ " <timerEventDefinition >" +
+ " <timeCycle>10 hours</timeCycle>" +
+ " </timerEventDefinition>" +
+ " </startEvent>" +
+ " <sequenceFlow id='flow1' sourceRef='theStart' targetRef='wait' />" +
+ " <receiveTask id='wait' />" +
+ " <sequenceFlow id='flow2' sourceRef='wait' targetRef='theEnd' />" +
+ " <endEvent id='theEnd' />" +
+ " </process>" +
+ "</definitions>";
+
+ private static final String TIMER_START_TIMECYCLE_CRON_EXPR =
+ "<definitions xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>" +
+ " <process id='timerStartTimeCycleCronExpression'>" +
+ " <startEvent id='theStart' >" +
+ " <timerEventDefinition >" +
+ " <timeCycle>0 0 22 * * ?</timeCycle>" + // every day at 22:00
+ " </timerEventDefinition>" +
+ " </startEvent>" +
+ " <sequenceFlow id='flow1' sourceRef='theStart' targetRef='wait' />" +
+ " <receiveTask id='wait' />" +
+ " <sequenceFlow id='flow2' sourceRef='wait' targetRef='theEnd' />" +
+ " <endEvent id='theEnd' />" +
+ " </process>" +
+ "</definitions>";
+
+ @Override
+ protected void tearDown() throws Exception {
+ Clock.setExplicitTime(null);
+ super.tearDown();
+ }
+
+ public void testInvalidProcess() {
+ testDeployInvalidProcess(INVALID_PROCESS_1);
+ testDeployInvalidProcess(INVALID_PROCESS_2);
+ testDeployInvalidProcess(INVALID_PROCESS_3);
+ testDeployInvalidProcess(INVALID_PROCESS_4);
+ }
+
+ private void testDeployInvalidProcess(String process) {
+ try {
+ deployBpmn2XmlString(process);
+ fail();
+ } catch (JbpmException e) {
+ // Exception is expected
+ }
+ }
+
+ public void testTimerStartEventWithFixedDuedate() {
+ deployBpmn2XmlString(TIMER_START_FIXED_DUEDATE);
+
+ // After deployment, there should be one job in the database that starts a new process instance
+ Job startProcessTimer = managementService.createJobQuery().uniqueResult();
+ assertNotNull(startProcessTimer);
+ assertEquals(DateUtils.getDateAtMidnight(10, Calendar.OCTOBER, 2099).getTime(), startProcessTimer.getDuedate().getTime());
+
+ ProcessInstanceQuery procInstQuery = executionService.createProcessInstanceQuery()
+ .processDefinitionId(findProcessDefinitionId("timerStartFixedDueDate"));
+
+ // Triggering the job should start a new process instance of the deployed process definition
+ assertEquals(0, procInstQuery.count());
+ managementService.executeJob(startProcessTimer.getId());
+ assertEquals(1, procInstQuery.count());
+
+ // Since a fixed duedate was used, the job should have been deleted from the database
+ startProcessTimer = managementService.createJobQuery().uniqueResult();
+ assertNull(startProcessTimer);
+ }
+
+ public void testTimerStartEventWithDurationAsTimeCycle() {
+ Clock.setExplicitTime(DateUtils.getDateAtMidnight(10, Calendar.OCTOBER, 2099));
+ deployBpmn2XmlString(TIMER_START_TIMECYCLE_DURATION);
+
+ // After deployment, there should be one job in the database that starts a new process instance
+ Job startProcessTimer = managementService.createJobQuery().uniqueResult();
+ assertNotNull(startProcessTimer);
+ assertEquals(DateUtils.getDate(10, Calendar.OCTOBER, 2099, 10, 0, 0).getTime(), startProcessTimer.getDuedate().getTime());
+
+ // Triggering the job should start a new process instance of the deployed process definition
+ ProcessInstanceQuery procInstQuery = executionService.createProcessInstanceQuery()
+ .processDefinitionId(findProcessDefinitionId("timerStartTimeCycleDuration"));
+ assertEquals(0, procInstQuery.count());
+
+ // need to change current date to calculate the next duedate correctly
+ Clock.setExplicitTime(DateUtils.getDate(10, Calendar.OCTOBER, 2099, 10, 0, 0));
+ managementService.executeJob(startProcessTimer.getId());
+ assertEquals(1, procInstQuery.count());
+
+ // Since a timeCycle was used, the job should have been recreated with a new duedate
+ startProcessTimer = managementService.createJobQuery().uniqueResult();
+ assertEquals(DateUtils.getDate(10, Calendar.OCTOBER, 2099, 20, 0, 0).getTime(), startProcessTimer.getDuedate().getTime());
+
+
+ // So we need to manually delete it
+ managementService.deleteJob(Long.valueOf(startProcessTimer.getId()));
+ }
+
+ public void testTimerStartEventWithCronExpressionAsTimeCycle() {
+ Clock.setExplicitTime(DateUtils.getDateAtMidnight(10, Calendar.OCTOBER, 2099));
+ deployBpmn2XmlString(TIMER_START_TIMECYCLE_CRON_EXPR);
+
+ // After deployment, there should be one job in the database that starts a new process instance
+ Job startProcessTimer = managementService.createJobQuery().uniqueResult();
+ assertNotNull(startProcessTimer);
+ assertEquals(DateUtils.getDate(10, Calendar.OCTOBER, 2099, 22, 0, 0).getTime(), startProcessTimer.getDuedate().getTime());
+
+ // Triggering the job should start a new process instance of the deployed process definition
+ ProcessInstanceQuery procInstQuery = executionService.createProcessInstanceQuery()
+ .processDefinitionId(findProcessDefinitionId("timerStartTimeCycleCronExpression"));
+ assertEquals(0, procInstQuery.count());
+
+ // need to change current date to calculate the next duedate correctly
+ Clock.setExplicitTime(DateUtils.getDate(10, Calendar.OCTOBER, 2099, 22, 0, 0));
+ managementService.executeJob(startProcessTimer.getId());
+ assertEquals(1, procInstQuery.count());
+
+ // Since a timeCycle was used, the job should have been recreated with a new duedate
+ startProcessTimer = managementService.createJobQuery().uniqueResult();
+ assertEquals(DateUtils.getDate(11, Calendar.OCTOBER, 2099, 22, 0, 0).getTime(), startProcessTimer.getDuedate().getTime());
+
+ // So we need to manually delete it
+ managementService.deleteJob(Long.valueOf(startProcessTimer.getId()));
+ }
+
+ public void testDeleteProcessDefinitionBeforeTimerTriggers() {
+ Clock.setExplicitTime(DateUtils.getDateAtMidnight(10, Calendar.OCTOBER, 2099));
+ String deployId = deployBpmn2XmlString(TIMER_START_TIMECYCLE_DURATION);
+
+ // Delete the process definition
+ repositoryService.deleteDeploymentCascade(deployId);
+ registeredDeployments.remove(0);
+
+ // After process definition deletion, the timer is still in the database
+ Job startProcessTimer = managementService.createJobQuery().uniqueResult();
+ assertNotNull(startProcessTimer);
+
+ // When the timer triggers, it notices that the process definition is gone and it deletes itselves
+ managementService.executeJob(startProcessTimer.getId());
+ startProcessTimer = managementService.createJobQuery().uniqueResult();
+ assertNull(startProcessTimer);
+ }
+
+ private String findProcessDefinitionId(String processDefinitionKey) {
+ return repositoryService.createProcessDefinitionQuery()
+ .processDefinitionName(processDefinitionKey).uniqueResult().getId();
+ }
+
+}
14 years, 3 months
JBoss JBPM SVN: r6134 - jbpm4/trunk.
by do-not-reply@jboss.org
Author: koen.aers(a)jboss.com
Date: 2010-01-26 13:25:52 -0500 (Tue, 26 Jan 2010)
New Revision: 6134
Modified:
jbpm4/trunk/pom.xml
Log:
update gpd dependency to 4.3
Modified: jbpm4/trunk/pom.xml
===================================================================
--- jbpm4/trunk/pom.xml 2010-01-26 16:33:43 UTC (rev 6133)
+++ jbpm4/trunk/pom.xml 2010-01-26 18:25:52 UTC (rev 6134)
@@ -54,7 +54,7 @@
<aspectjrt.version>1.5.3</aspectjrt.version>
<freemarker.version>2.3.15</freemarker.version>
<gwt.console.version>1.3.0</gwt.console.version>
- <jbpm.gpd.version>4.3-SNAPSHOT</jbpm.gpd.version>
+ <jbpm.gpd.version>4.3</jbpm.gpd.version>
<hibernate.version>3.3.1.GA</hibernate.version>
<slf4j.version>1.5.2</slf4j.version>
<hsqldb.version>1.8.0.7</hsqldb.version>
14 years, 3 months
JBoss JBPM SVN: r6133 - in jbpm4/trunk: modules/pvm and 4 other directories.
by do-not-reply@jboss.org
Author: tom.baeyens(a)jboss.com
Date: 2010-01-26 11:33:43 -0500 (Tue, 26 Jan 2010)
New Revision: 6133
Added:
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmConstantsElResolver.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElContext.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElContextFactory.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElContextFactoryImpl.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmEnvironmentElResolver.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmFunctionMapper.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmVariableElResolver.java
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JstlFunction.java
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/el/
Modified:
jbpm4/trunk/modules/pvm/pom.xml
jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java
jbpm4/trunk/pom.xml
Log:
JBPM-2653 added first pieces of uel expression resolving infrastructure
Modified: jbpm4/trunk/modules/pvm/pom.xml
===================================================================
--- jbpm4/trunk/modules/pvm/pom.xml 2010-01-26 12:39:12 UTC (rev 6132)
+++ jbpm4/trunk/modules/pvm/pom.xml 2010-01-26 16:33:43 UTC (rev 6133)
@@ -171,6 +171,11 @@
<artifactId>servlet-api</artifactId>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>javax.enterprise</groupId>
+ <artifactId>cdi-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
</dependencies>
<!-- Plugins -->
Added: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmConstantsElResolver.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmConstantsElResolver.java (rev 0)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmConstantsElResolver.java 2010-01-26 16:33:43 UTC (rev 6133)
@@ -0,0 +1,119 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.pvm.internal.el;
+
+import java.beans.FeatureDescriptor;
+import java.util.Iterator;
+
+import javax.el.ELContext;
+import javax.el.ELResolver;
+
+import org.jbpm.pvm.internal.model.ExecutionImpl;
+import org.jbpm.pvm.internal.model.ScopeInstanceImpl;
+import org.jbpm.pvm.internal.task.TaskImpl;
+
+
+/**
+ * @author Tom Baeyens
+ */
+public class JbpmConstantsElResolver extends ELResolver {
+
+ private static final String NAME_EXECUTION = "execution";
+ private static final String NAME_PROCESSINSTANCE = "processInstance";
+ private static final String NAME_TASK = "task";
+
+ ExecutionImpl execution;
+ ExecutionImpl processInstance;
+ TaskImpl task;
+
+ public JbpmConstantsElResolver(ScopeInstanceImpl scopeInstance) {
+ if (scopeInstance instanceof ExecutionImpl) {
+ this.execution = (ExecutionImpl) scopeInstance;
+ this.processInstance = execution.getProcessInstance();
+
+ } else {
+ this.task = (TaskImpl) scopeInstance;
+ this.execution = task.getExecution();
+ if (this.execution!=null) {
+ this.processInstance = execution.getProcessInstance();
+ }
+ }
+ }
+
+ public Object getValue(ELContext context, Object base, Object property) {
+ // this resolver only resolves top level variable names to execution variable names.
+ // only handle if this is a top level variable
+ if (base==null) {
+ // we assume a NPE-check for property is not needed
+ // i don't think the next cast can go wrong. can it?
+ String name = (String) property;
+
+ if (execution!=null && NAME_EXECUTION.equals(name)) {
+ context.setPropertyResolved(true);
+ return execution;
+ }
+
+ if (processInstance!=null && NAME_PROCESSINSTANCE.equals(name)) {
+ context.setPropertyResolved(true);
+ return processInstance;
+ }
+
+ if (task!=null && NAME_TASK.equals(name)) {
+ context.setPropertyResolved(true);
+ return task;
+ }
+ }
+
+ return null;
+ }
+
+ public boolean isReadOnly(ELContext context, Object base, Object property) {
+ // this resolver only resolves top level variable names to execution variable names.
+ // only handle if this is a top level variable
+ if (base==null) {
+ // we assume a NPE-check for property is not needed
+ // i don't think the next cast can go wrong. can it?
+ String name = (String) property;
+
+ if (NAME_EXECUTION.equals(name)
+ || NAME_PROCESSINSTANCE.equals(name)
+ || NAME_TASK.equals(name)) {
+ return true;
+ }
+ }
+
+ return true;
+ }
+
+ public void setValue(ELContext context, Object base, Object property, Object value) {
+ }
+
+ public Class< ? > getType(ELContext context, Object base, Object property) {
+ return Object.class;
+ }
+ public Class< ? > getCommonPropertyType(ELContext context, Object base) {
+ return Object.class;
+ }
+ public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
+ return null;
+ }
+}
Property changes on: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmConstantsElResolver.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElContext.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElContext.java (rev 0)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElContext.java 2010-01-26 16:33:43 UTC (rev 6133)
@@ -0,0 +1,54 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.pvm.internal.el;
+
+import javax.el.ELContext;
+import javax.el.ELResolver;
+import javax.el.FunctionMapper;
+import javax.el.VariableMapper;
+
+
+/**
+ * @author Tom Baeyens
+ */
+public class JbpmElContext extends ELContext {
+
+ ELResolver elResolver;
+ FunctionMapper functionMapper;
+
+ public JbpmElContext(ELResolver elResolver, FunctionMapper functionMapper) {
+ this.elResolver = elResolver;
+ this.functionMapper = functionMapper;
+ }
+
+ public ELResolver getELResolver() {
+ return elResolver;
+ }
+
+ public FunctionMapper getFunctionMapper() {
+ return functionMapper;
+ }
+
+ public VariableMapper getVariableMapper() {
+ return null;
+ }
+}
Property changes on: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElContext.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElContextFactory.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElContextFactory.java (rev 0)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElContextFactory.java 2010-01-26 16:33:43 UTC (rev 6133)
@@ -0,0 +1,35 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.pvm.internal.el;
+
+import javax.el.ELContext;
+
+import org.jbpm.pvm.internal.model.ScopeInstanceImpl;
+
+/**
+ * @author Tom Baeyens
+ */
+public interface JbpmElContextFactory {
+
+ ELContext createElContext();
+ ELContext createElContext(ScopeInstanceImpl scopeInstance);
+}
\ No newline at end of file
Property changes on: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElContextFactory.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElContextFactoryImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElContextFactoryImpl.java (rev 0)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElContextFactoryImpl.java 2010-01-26 16:33:43 UTC (rev 6133)
@@ -0,0 +1,113 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.pvm.internal.el;
+
+import javax.el.ArrayELResolver;
+import javax.el.BeanELResolver;
+import javax.el.CompositeELResolver;
+import javax.el.ELContext;
+import javax.el.ELResolver;
+import javax.el.FunctionMapper;
+import javax.el.ListELResolver;
+import javax.el.MapELResolver;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.jbpm.internal.log.Log;
+import org.jbpm.pvm.internal.env.EnvironmentImpl;
+import org.jbpm.pvm.internal.model.ScopeInstanceImpl;
+
+
+/**
+ * @author Tom Baeyens
+ */
+public class JbpmElContextFactoryImpl implements JbpmElContextFactory {
+
+ private static Log log = Log.getLog(JbpmElContextFactoryImpl.class.getName());
+
+ Class<?> functionClass = JstlFunction.class;
+
+ /** create ElContext used during parsing time */
+ public ELContext createElContext() {
+ return createCompositeResolver(null);
+ }
+
+ /** create ElContext used during evaluation time related to an execution */
+ public ELContext createElContext(ScopeInstanceImpl scopeInstance) {
+ return createCompositeResolver(scopeInstance);
+ }
+
+ protected ELContext createCompositeResolver(ScopeInstanceImpl scopeInstance) {
+ CompositeELResolver compositeELResolver = new CompositeELResolver();
+
+ if (scopeInstance!=null) {
+ compositeELResolver.add(new JbpmConstantsElResolver(scopeInstance));
+ compositeELResolver.add(new JbpmVariableElResolver(scopeInstance));
+ }
+
+ EnvironmentImpl environment = EnvironmentImpl.getCurrent();
+ if (environment!=null) {
+ compositeELResolver.add(new JbpmEnvironmentElResolver(environment));
+ }
+
+ addCdiResolver(compositeELResolver);
+
+ addBasicResolvers(compositeELResolver);
+
+ FunctionMapper functionMapper = createFunctionMapper();
+
+ return createElContext(compositeELResolver, functionMapper);
+ }
+
+ protected void addCdiResolver(CompositeELResolver compositeELResolver) {
+ try {
+ InitialContext initialContext = new InitialContext();
+ Object object = initialContext.lookup("java:comp/BeanManager");
+ if (object!=null) {
+ BeanManager beanManager = (BeanManager) object;
+ ELResolver cdiResolver = beanManager.getELResolver();
+ if (cdiResolver!=null) {
+ compositeELResolver.add(cdiResolver);
+ log.debug("added cdi el resolver");
+ }
+ }
+ } catch (NamingException e) {
+ log.debug("no cdi bean manager available in jndi");
+ }
+ }
+
+ protected void addBasicResolvers(CompositeELResolver compositeELResolver) {
+ compositeELResolver.add(new BeanELResolver());
+ compositeELResolver.add(new MapELResolver());
+ compositeELResolver.add(new ListELResolver());
+ compositeELResolver.add(new ArrayELResolver());
+ }
+
+ protected FunctionMapper createFunctionMapper() {
+ return new JbpmFunctionMapper(functionClass);
+ }
+
+ protected JbpmElContext createElContext(CompositeELResolver compositeELResolver, FunctionMapper functionMapper) {
+ return new JbpmElContext(compositeELResolver, functionMapper);
+ }
+}
Property changes on: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmElContextFactoryImpl.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmEnvironmentElResolver.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmEnvironmentElResolver.java (rev 0)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmEnvironmentElResolver.java 2010-01-26 16:33:43 UTC (rev 6133)
@@ -0,0 +1,78 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.pvm.internal.el;
+
+import java.beans.FeatureDescriptor;
+import java.util.Iterator;
+
+import javax.el.ELContext;
+import javax.el.ELResolver;
+
+import org.jbpm.pvm.internal.env.EnvironmentImpl;
+
+
+/**
+ * @author Tom Baeyens
+ */
+public class JbpmEnvironmentElResolver extends ELResolver {
+
+ EnvironmentImpl environment;
+
+ public JbpmEnvironmentElResolver(EnvironmentImpl environment) {
+ this.environment = environment;
+ }
+
+ public Object getValue(ELContext context, Object base, Object property) {
+ // this resolver only resolves top level variable names to execution variable names.
+ // only handle if this is a top level variable
+ if (base==null) {
+ // we assume a NPE-check for property is not needed
+ // i don't think the next cast can go wrong. can it?
+ String name = (String) property;
+
+ Object object = environment.get(name);
+ if (object!=null) {
+ context.setPropertyResolved(true);
+ return object;
+ }
+ }
+
+ return null;
+ }
+
+ public boolean isReadOnly(ELContext context, Object base, Object property) {
+ return true;
+ }
+
+ public void setValue(ELContext context, Object base, Object property, Object value) {
+ }
+
+ public Class< ? > getType(ELContext context, Object base, Object property) {
+ return Object.class;
+ }
+ public Class< ? > getCommonPropertyType(ELContext context, Object base) {
+ return Object.class;
+ }
+ public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
+ return null;
+ }
+}
Property changes on: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmEnvironmentElResolver.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmFunctionMapper.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmFunctionMapper.java (rev 0)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmFunctionMapper.java 2010-01-26 16:33:43 UTC (rev 6133)
@@ -0,0 +1,48 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.pvm.internal.el;
+
+import java.lang.reflect.Method;
+
+import javax.el.FunctionMapper;
+
+
+/**
+ * @author Tom Baeyens
+ */
+public class JbpmFunctionMapper extends FunctionMapper {
+
+ Class<?> functionClass;
+
+ public JbpmFunctionMapper(Class< ? > funtionClass) {
+ this.functionClass = funtionClass;
+ }
+
+ public Method resolveFunction(String prefix, String localName) {
+ for (Method method: functionClass.getDeclaredMethods()) {
+ if (method.getName().equals(localName)) {
+ return method;
+ }
+ }
+ return null;
+ }
+}
Property changes on: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmFunctionMapper.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmVariableElResolver.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmVariableElResolver.java (rev 0)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmVariableElResolver.java 2010-01-26 16:33:43 UTC (rev 6133)
@@ -0,0 +1,100 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.pvm.internal.el;
+
+import java.beans.FeatureDescriptor;
+import java.util.Iterator;
+
+import javax.el.CompositeELResolver;
+import javax.el.ELContext;
+
+import org.jbpm.pvm.internal.model.ScopeInstanceImpl;
+
+
+/**
+ * @author Tom Baeyens
+ */
+public class JbpmVariableElResolver extends CompositeELResolver {
+
+ ScopeInstanceImpl scopeInstance;
+
+ public JbpmVariableElResolver(ScopeInstanceImpl scopeInstance) {
+ this.scopeInstance = scopeInstance;
+ }
+
+ public Object getValue(ELContext context, Object base, Object property) {
+ // this resolver only resolves top level variable names to execution variable names.
+ // only handle if this is a top level variable
+ if (base==null) {
+ // we assume a NPE-check for property is not needed
+ // i don't think the next cast can go wrong. can it?
+ String name = (String) property;
+
+ if (scopeInstance.hasVariable(name)) {
+ context.setPropertyResolved(true);
+ return scopeInstance.getVariable(name);
+ }
+ }
+
+ return null;
+ }
+
+ public boolean isReadOnly(ELContext context, Object base, Object property) {
+ // this resolver only resolves top level variable names to execution variable names.
+ // only handle if this is a top level variable
+ if (base==null) {
+ // we assume a NPE-check for property is not needed
+ // i don't think the next cast can go wrong. can it?
+ String name = (String) property;
+
+ if (scopeInstance.hasVariable(name)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public void setValue(ELContext context, Object base, Object property, Object value) {
+ // this resolver only resolves top level variable names to execution variable names.
+ // only handle if this is a top level variable
+ if (base==null) {
+ // we assume a NPE-check for property is not needed
+ // i don't think the next cast can go wrong. can it?
+ String variableName = (String) property;
+
+ if (scopeInstance.hasVariable(variableName)) {
+ scopeInstance.setVariable(variableName, value);
+ }
+ }
+ }
+
+ public Class< ? > getType(ELContext context, Object base, Object property) {
+ return Object.class;
+ }
+ public Class< ? > getCommonPropertyType(ELContext context, Object base) {
+ return Object.class;
+ }
+ public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
+ return null;
+ }
+}
Property changes on: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmVariableElResolver.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JstlFunction.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JstlFunction.java (rev 0)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JstlFunction.java 2010-01-26 16:33:43 UTC (rev 6133)
@@ -0,0 +1,330 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can obtain
+ * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
+ * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
+ * Sun designates this particular file as subject to the "Classpath" exception
+ * as provided by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the License
+ * Header, with the fields enclosed by brackets [] replaced by your own
+ * identifying information: "Portions Copyrighted [year]
+ * [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jbpm.pvm.internal.el;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+/**
+ * Implementations of JSTL Functions
+ *
+ * @author Jacob Hookom
+ * @version $Id: JstlFunction.java 7265 2009-05-01 19:46:08Z rlubke $
+ */
+public final class JstlFunction {
+
+ private JstlFunction() {
+ }
+
+ public static boolean contains(String name, String searchString) {
+ if (name == null) {
+ name = "";
+ }
+ if (searchString == null) {
+ searchString = "";
+ }
+ return name.contains(searchString);
+ }
+
+ public static boolean containsIgnoreCase(String name, String searchString) {
+ if (name == null) {
+ name = "";
+ }
+ if (searchString == null) {
+ searchString = "";
+ }
+ return name.toLowerCase().contains(searchString.toLowerCase());
+ }
+
+ public static boolean endsWith(String name, String searchString) {
+ if (name == null) {
+ name = "";
+ }
+ if (searchString == null) {
+ searchString = "";
+ }
+ return name.endsWith(searchString);
+ }
+
+ public static String escapeXml(String value) {
+ if (value == null || value.length() == 0) {
+ value = "";
+ }
+ StringBuilder b = new StringBuilder(value.length());
+ final char[] lookahead = { 'a', 'm', 'p', ';' };
+ for (int i = 0, len = value.length(); i < len; i++) {
+ char c = value.charAt(i);
+ if (c == '<') {
+ b.append("<");
+ } else if (c == '>') {
+ b.append(">");
+ } else if (c == '\'') {
+ b.append("'");
+ } else if (c == '"') {
+ b.append(""");
+ } else if (c == '&') {
+ boolean matched = true;
+ for (int j = 0, jlen = lookahead.length; j < jlen; j++) {
+ if (lookahead[j] != value.charAt(i + (j + 1))) {
+ matched = false;
+ break;
+ }
+ }
+ if (matched) {
+ i += 4;
+ }
+ b.append("&");
+ } else {
+ b.append(c);
+ }
+ }
+ return b.toString();
+ }
+
+ public static int indexOf(String name, String searchString) {
+ if (name == null) {
+ name = "";
+ }
+ if (searchString == null) {
+ searchString = "";
+ }
+ return name.indexOf(searchString);
+ }
+
+ public static String join(String[] a, String delim) {
+ if (a == null || a.length == 0) {
+ return "";
+ }
+ boolean skipDelim = false;
+ if (delim == null || delim.length() == 0) {
+ skipDelim = true;
+ }
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0, len = a.length, delimCount = (len - 1); i < len; i++) {
+ sb.append(a[i]);
+ if (!skipDelim && (i < delimCount)) {
+ sb.append(delim);
+ }
+ }
+ return sb.toString();
+ }
+
+ public static int length(Object obj) {
+ if (obj == null) {
+ return 0;
+ }
+ if (obj instanceof Collection) {
+ return ((Collection) obj).size();
+ }
+ if (obj.getClass().isArray()) {
+ return Array.getLength(obj);
+ }
+ if (obj instanceof String) {
+ return ((String) obj).length();
+ }
+ if (obj instanceof Map) {
+ return ((Map) obj).size();
+ }
+ if (obj instanceof Enumeration) {
+ Enumeration e = (Enumeration) obj;
+ int count = 0;
+ while (e.hasMoreElements()) {
+ e.nextElement();
+ count++;
+ }
+ return count;
+ }
+ if (obj instanceof Iterator) {
+ Iterator i = (Iterator) obj;
+ int count = 0;
+ while (i.hasNext()) {
+ i.next();
+ count++;
+ }
+ return count;
+ }
+ throw new IllegalArgumentException("Object type not supported: " + obj.getClass().getName());
+ }
+
+ public static String replace(String value, String before, String after) {
+ if (value == null) {
+ value = "";
+ }
+ if (before == null) {
+ before = "";
+ }
+ if (before.length() == 0) {
+ return value;
+ }
+ if (value.length() == 0) {
+ return "";
+ }
+ if (after == null) {
+ after = "";
+ }
+
+ return value.replaceAll(before, after);
+ }
+
+ public static String[] split(String value, String d) {
+ if (value == null) {
+ value = "";
+ }
+ if (value.length() == 0) {
+ return new String[] { "" };
+ }
+ if (d == null) {
+ d = "";
+ }
+ if (d.length() == 0) {
+ return new String[] { value };
+ }
+
+ List<String> tokens = new ArrayList<String>();
+ for (StringTokenizer st = new StringTokenizer(value, d); st.hasMoreTokens();) {
+ tokens.add(st.nextToken());
+ }
+
+ return tokens.toArray(new String[tokens.size()]);
+ }
+
+ public static boolean startsWith(String value, String p) {
+ if (value == null) {
+ value = "";
+ }
+ if (p == null) {
+ p = "";
+ }
+ return value.startsWith(p);
+ }
+
+ public static String substring(String v, int s, int e) {
+ if (v == null) {
+ v = "";
+ }
+ if (s >= v.length()) {
+ return "";
+ }
+ if (s < 0) {
+ s = 0;
+ }
+ if (e < 0 || e >= v.length()) {
+ e = v.length();
+ }
+ if (e < s) {
+ return "";
+ }
+ return v.substring(s, e);
+ }
+
+ public static String substringAfter(String v, String p) {
+ if (v == null) {
+ v = "";
+ }
+ if (v.length() == 0) {
+ return "";
+ }
+ if (p == null) {
+ p = "";
+ }
+ int i = v.indexOf(p);
+ if (i == -1) {
+ return "";
+ }
+ return v.substring(i + p.length());
+ }
+
+ public static String substringBefore(String v, String s) {
+ if (v == null) {
+ v = "";
+ }
+ if (v.length() == 0) {
+ return "";
+ }
+ if (s == null) {
+ s = "";
+ }
+ int i = v.indexOf(s);
+ if (i == -1) {
+ return "";
+ }
+ return v.substring(0, i);
+ }
+
+ public static String toLowerCase(String v) {
+ if (v == null || v.length() == 0) {
+ return "";
+ }
+ return v.toLowerCase();
+ }
+
+ public static String toUpperCase(String v) {
+ if (v == null || v.length() == 0) {
+ return "";
+ }
+ return v.toUpperCase();
+ }
+
+ public static String trim(String v) {
+ if (v == null || v.length() == 0) {
+ return "";
+ }
+ return v.trim();
+ }
+
+}
Property changes on: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JstlFunction.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java 2010-01-26 12:39:12 UTC (rev 6132)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/model/ExecutionImpl.java 2010-01-26 16:33:43 UTC (rev 6133)
@@ -34,11 +34,14 @@
import java.util.Set;
import java.util.StringTokenizer;
-import org.hibernate.Session;
+import javax.el.ELContext;
+import javax.el.ExpressionFactory;
+import javax.el.MethodExpression;
+import javax.el.ValueExpression;
+
import org.jbpm.api.Execution;
import org.jbpm.api.JbpmException;
import org.jbpm.api.activity.ActivityExecution;
-import org.jbpm.api.cmd.Environment;
import org.jbpm.api.job.Job;
import org.jbpm.api.job.Timer;
import org.jbpm.api.listener.EventListenerExecution;
@@ -51,6 +54,8 @@
import org.jbpm.internal.log.Log;
import org.jbpm.pvm.internal.client.ClientProcessDefinition;
import org.jbpm.pvm.internal.client.ClientProcessInstance;
+import org.jbpm.pvm.internal.el.JbpmElContextFactory;
+import org.jbpm.pvm.internal.el.JbpmElContextFactoryImpl;
import org.jbpm.pvm.internal.env.Context;
import org.jbpm.pvm.internal.env.EnvironmentImpl;
import org.jbpm.pvm.internal.env.ExecutionContext;
@@ -159,6 +164,8 @@
protected int eventListenerIndex;
protected ObservableElementImpl eventSource;
+
+ protected Object cachedElContext = null;
// cached named executions //////////////////////////////////////////////////
@@ -674,7 +681,34 @@
atomicOperations.offer(operation);
}
}
-
+
+ public Object resolveElValueExpressionGet(ValueExpression valueExpression) {
+ initCachedElContext();
+ return valueExpression.getValue((ELContext) cachedElContext);
+ }
+
+ public void resolveElValueExpressionSet(ValueExpression valueExpression, Object value) {
+ initCachedElContext();
+ valueExpression.setValue((ELContext) cachedElContext, value);
+ }
+
+ public void resolveElMethodExpressionInvoke(MethodExpression methodExpression) {
+ initCachedElContext();
+ Object[] params = new Object[]{};
+ // TODO figure out how to resolve the params
+ methodExpression.invoke((ELContext) cachedElContext, params);
+ }
+
+ protected void initCachedElContext() {
+ if (cachedElContext==null) {
+ JbpmElContextFactory contextFactory = EnvironmentImpl.getFromCurrent(JbpmElContextFactory.class, false);
+ if (contextFactory==null) {
+ contextFactory = new JbpmElContextFactoryImpl();
+ }
+ cachedElContext = contextFactory.createElContext(this);
+ }
+ }
+
/**
* Important: Only use this if resolving an expression on another execution then the current execution
*
Modified: jbpm4/trunk/pom.xml
===================================================================
--- jbpm4/trunk/pom.xml 2010-01-26 12:39:12 UTC (rev 6132)
+++ jbpm4/trunk/pom.xml 2010-01-26 16:33:43 UTC (rev 6133)
@@ -77,6 +77,7 @@
<postgresql.version>8.3-603.jdbc3</postgresql.version>
<jtds.version>1.2.2</jtds.version>
<oracle.version>10.2.0.4</oracle.version>
+ <cdi.version>1.0</cdi.version>
</properties>
<!-- DependencyManagement -->
@@ -415,6 +416,11 @@
<artifactId>jtds</artifactId>
<version>${jtds.version}</version>
</dependency>
+ <dependency>
+ <groupId>javax.enterprise</groupId>
+ <artifactId>cdi-api</artifactId>
+ <version>${cdi.version}</version>
+ </dependency>
</dependencies>
</dependencyManagement>
14 years, 3 months
JBoss JBPM SVN: r6132 - in jbpm4/trunk/modules: test-db/src/test/java/org/jbpm/bpmn/test and 1 other directories.
by do-not-reply@jboss.org
Author: jbarrez
Date: 2010-01-26 07:39:12 -0500 (Tue, 26 Jan 2010)
New Revision: 6132
Added:
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/deployment/
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/deployment/Bpmn2DeploymentTest.java
Modified:
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/parser/BpmnParser.java
Log:
Added test case for deployment/redeployment in BPMN2
Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/parser/BpmnParser.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/parser/BpmnParser.java 2010-01-26 11:30:19 UTC (rev 6131)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/parser/BpmnParser.java 2010-01-26 12:39:12 UTC (rev 6132)
@@ -114,7 +114,11 @@
String id = XmlUtil.attribute(processElement, "id", false, parse);
String name = XmlUtil.attribute(processElement, "name", false, parse);
- processDefinition.setName(id);
+ if (id != null && !"".equals(id)) {
+ processDefinition.setName(id);
+ } else {
+ parse.addProblem("Process has no or an empty id");
+ }
if (name != null) {
processDefinition.setKey(name);
Added: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/deployment/Bpmn2DeploymentTest.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/deployment/Bpmn2DeploymentTest.java (rev 0)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/deployment/Bpmn2DeploymentTest.java 2010-01-26 12:39:12 UTC (rev 6132)
@@ -0,0 +1,145 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.bpmn.test.deployment;
+
+import java.util.List;
+
+import org.jbpm.api.JbpmException;
+import org.jbpm.api.ProcessDefinition;
+import org.jbpm.api.ProcessDefinitionQuery;
+import org.jbpm.api.ProcessInstance;
+import org.jbpm.test.JbpmTestCase;
+import org.jbpm.test.assertion.CollectionAssertions;
+
+
+/**
+ * @author Joram Barrez
+ */
+public class Bpmn2DeploymentTest extends JbpmTestCase {
+
+ private static final String TEST_PROCESS_ONLY_ID =
+ "<definitions>" +
+ " <process id='myProcess' >" +
+ " <startEvent id='start'/>" +
+ " <sequenceFlow id='flow1' sourceRef='start' targetRef='end' />" +
+ " <endEvent id='end'/>" +
+ " </process>" +
+ "</definitions>";
+
+ private static final String TEST_PROCESS_ONLY_NAME =
+ "<definitions>" +
+ " <process name='myProcess' >" +
+ " <startEvent id='start'/>" +
+ " <sequenceFlow id='flow1' sourceRef='start' targetRef='end' />" +
+ " <endEvent id='end'/>" +
+ " </process>" +
+ "</definitions>";
+
+ private static final String TEST_PROCESS_ID_AND_NAME =
+ "<definitions>" +
+ " <process id='myProcess' name='myFirstProcess'>" +
+ " <startEvent id='start'/>" +
+ " <sequenceFlow id='flow1' sourceRef='start' targetRef='end' />" +
+ " <endEvent id='end'/>" +
+ " </process>" +
+ "</definitions>";
+
+ public void testDeployProcessWithOnlyName() {
+ try {
+ deployBpmn2XmlString(TEST_PROCESS_ONLY_NAME);
+ fail();
+ } catch (JbpmException e) {
+ // Exception is to be expected
+ }
+ }
+
+ public void testDeployProcessWithOnlyId() {
+ deployBpmn2XmlString(TEST_PROCESS_ONLY_ID);
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("myProcess");
+ assertNotNull(processInstance);
+ assertProcessInstanceEnded(processInstance);
+ }
+
+ public void testDeployProcessWithIdAndName() {
+ deployBpmn2XmlString(TEST_PROCESS_ID_AND_NAME);
+
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("myFirstProcess");
+ assertNotNull(processInstance);
+ assertProcessInstanceEnded(processInstance);
+
+ try {
+ executionService.startProcessInstanceByKey("myProcess");
+ fail();
+ } catch (JbpmException e) {
+ assertTrue(e.getMessage().contains("no process definition with key"));
+ // exception expected: when a key is given, the id can't be used as a key
+ }
+ }
+
+ /* ------------
+ * REDEPLOYMENT
+ * ------------
+ */
+
+ public void testRedeployProcessWithOnlyId() {
+ deployBpmn2XmlString(TEST_PROCESS_ONLY_ID);
+
+ ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery().processDefinitionKey("myProcess");
+ List<ProcessDefinition> definitions = query.list();
+ assertEquals(1, definitions.size());
+
+ deployBpmn2XmlString(TEST_PROCESS_ONLY_ID);
+ query.orderAsc(ProcessDefinitionQuery.PROPERTY_VERSION);
+ definitions = query.list();
+
+ assertEquals(2, definitions.size());
+ assertEquals(1, definitions.get(0).getVersion());
+ assertEquals(2, definitions.get(1).getVersion());
+
+ // Check if the key is replaced with the name (query should give same result)
+ List<ProcessDefinition> definitionsByName = repositoryService.createProcessDefinitionQuery()
+ .processDefinitionName("myProcess").list();
+ CollectionAssertions.assertContainsSameElements(definitions, definitionsByName);
+ }
+
+ public void testRedeployProcessWithIdAndName() {
+ deployBpmn2XmlString(TEST_PROCESS_ID_AND_NAME);
+
+ ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery().processDefinitionName("myProcess");
+ List<ProcessDefinition> definitions = query.list();
+ assertEquals(1, definitions.size());
+
+ deployBpmn2XmlString(TEST_PROCESS_ID_AND_NAME);
+ query.orderAsc(ProcessDefinitionQuery.PROPERTY_VERSION);
+ definitions = query.list();
+
+ assertEquals(2, definitions.size());
+ assertEquals(1, definitions.get(0).getVersion());
+ assertEquals(2, definitions.get(1).getVersion());
+
+ // Check if the key is replaced with the name (query should give same result)
+ List<ProcessDefinition> definitionsByKey = repositoryService.createProcessDefinitionQuery()
+ .processDefinitionKey("myFirstProcess").list();
+ CollectionAssertions.assertContainsSameElements(definitions, definitionsByKey);
+ }
+
+}
14 years, 3 months