### Eclipse Workspace Patch 1.0
#P jbpm4
Index: modules/test-db/src/test/java/org/jbpm/test/variables/VariableExpressionTest.java
===================================================================
--- modules/test-db/src/test/java/org/jbpm/test/variables/VariableExpressionTest.java (revision 6285)
+++ modules/test-db/src/test/java/org/jbpm/test/variables/VariableExpressionTest.java (working copy)
@@ -27,6 +27,7 @@
import java.util.HashMap;
import java.util.Map;
+import org.jbpm.api.JbpmException;
import org.jbpm.api.ProcessInstance;
import org.jbpm.api.activity.ActivityBehaviour;
import org.jbpm.api.activity.ActivityExecution;
@@ -35,6 +36,7 @@
/**
* @author Joram Barrez
+ * @author Maciej Swiderski
*/
public class VariableExpressionTest extends JbpmTestCase {
@@ -72,6 +74,76 @@
assertEquals(new Integer(10), counter);
}
+ public void testNullValueExpression() {
+ deployJpdlXmlString(
+ "" +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ ""
+ );
+
+ Map vars = new HashMap();
+ vars.put("counter", null);
+
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("theProcess", vars);
+ assertActivityActive(processInstance.getId(), "waitHere");
+
+ Object value = executionService.getVariable(processInstance.getId(), "counter");
+ assertEquals(null, value);
+ }
+
+ public void testMissingVariableExpression() {
+ deployJpdlXmlString(
+ "" +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ " " +
+ ""
+ );
+
+ Map vars = new HashMap();
+ try {
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("theProcess", vars);
+
+ fail("Variable counter is not set, should fail");
+ } catch (JbpmException e) {
+
+ assertTrue(e.getMessage().indexOf("Cannot find property counter") != -1);
+ }
+
+ }
+
public static class MyJavaActivity implements ActivityBehaviour {
Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/env/EnvironmentImpl.java
===================================================================
--- modules/pvm/src/main/java/org/jbpm/pvm/internal/env/EnvironmentImpl.java (revision 6285)
+++ modules/pvm/src/main/java/org/jbpm/pvm/internal/env/EnvironmentImpl.java (working copy)
@@ -141,6 +141,10 @@
* @return the object if it exists in the environment, null
if there is no object with the given name in the specified searchOrder contexts.
*/
public abstract Object get(String name, String[] searchOrder);
+
+ public abstract Object get(String name,String[] searchOrder, boolean nullAllowed) throws JbpmException;
+
+ public abstract Object get(String name, boolean nullAllowed) throws JbpmException;
/** searches an object based on type. The search doesn take superclasses of the context elements
* into account.
Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/env/BasicEnvironment.java
===================================================================
--- modules/pvm/src/main/java/org/jbpm/pvm/internal/env/BasicEnvironment.java (revision 6285)
+++ modules/pvm/src/main/java/org/jbpm/pvm/internal/env/BasicEnvironment.java (working copy)
@@ -93,16 +93,30 @@
public Object get(String name) {
return get(name, null);
}
-
+
public Object get(String name, String[] searchOrder) {
- if (searchOrder==null) {
- searchOrder = getDefaultSearchOrder();
- }
- for (String contextName : searchOrder) {
- Context context = contexts.get(contextName);
- if (context.has(name)) return context.get(name);
+ return get(name, searchOrder, true);
+ }
+
+ public Object get(String name, boolean nullIfNotFound) {
+ return get(name, null, nullIfNotFound);
+ }
+
+ public Object get(String name, String[] searchOrder, boolean nullIfNotFound) {
+ if (searchOrder == null) {
+ searchOrder = getDefaultSearchOrder();
+ }
+ for (String contextName : searchOrder) {
+ Context context = contexts.get(contextName);
+ if (context.has(name)) {
+ return context.get(name);
+ }
+ }
+ if (nullIfNotFound) {
+ return null;
+ } else {
+ throw new JbpmException("Null value found for " + name + " but null is not allowed");
}
- return null;
}
public T get(Class type) {
Index: modules/pvm/src/test/java/org/jbpm/pvm/internal/expr/UelExpressionTest.java
===================================================================
--- modules/pvm/src/test/java/org/jbpm/pvm/internal/expr/UelExpressionTest.java (revision 0)
+++ modules/pvm/src/test/java/org/jbpm/pvm/internal/expr/UelExpressionTest.java (revision 0)
@@ -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.expr;
+
+import org.jbpm.pvm.activities.WaitState;
+import org.jbpm.pvm.internal.builder.ProcessDefinitionBuilder;
+
+import org.jbpm.pvm.internal.el.Expression;
+import org.jbpm.pvm.internal.el.UelValueExpression;
+import org.jbpm.pvm.internal.model.ExecutionImpl;
+import org.jbpm.test.JbpmTestCase;
+
+
+/**
+ * @author Tom Baeyens
+ */
+public class UelExpressionTest extends JbpmTestCase {
+
+ public void testUelExpression() {
+ ExecutionImpl execution = (ExecutionImpl) ProcessDefinitionBuilder
+ .startProcess()
+ .startActivity("initial", new WaitState())
+ .initial()
+ .endActivity()
+ .endProcess()
+ .startProcessInstance();
+
+ Expression expression = Expression.create("#{pv}", Expression.LANGUAGE_UEL_VALUE);
+ UelValueExpression uve = ((UelValueExpression) expression);
+
+ execution.setVariable("pv", null);
+
+ assertEquals(null, uve.evaluate(execution));
+ }
+}
Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmEnvironmentElResolver.java
===================================================================
--- modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmEnvironmentElResolver.java (revision 6285)
+++ modules/pvm/src/main/java/org/jbpm/pvm/internal/el/JbpmEnvironmentElResolver.java (working copy)
@@ -27,32 +27,36 @@
import javax.el.ELContext;
import javax.el.ELResolver;
+import org.jbpm.api.JbpmException;
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.
+ // this resolver only resolves top level variable names to execution
+ // variable names.
// only handle if this is a top level variable
- if (base==null) {
+ 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?
+ // i don't think the next cast can go wrong. can it?
String name = (String) property;
- Object object = environment.get(name);
- if (object!=null) {
+ try {
+ Object object = environment.get(name, false);
context.setPropertyResolved(true);
return object;
+ } catch (JbpmException je) {
+ // Property not found... ignore in this case and return null below...
+ // Will be interpreted as property not found
}
}
Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/script/JuelScriptEngine.java
===================================================================
--- modules/pvm/src/main/java/org/jbpm/pvm/internal/script/JuelScriptEngine.java (revision 6285)
+++ modules/pvm/src/main/java/org/jbpm/pvm/internal/script/JuelScriptEngine.java (working copy)
@@ -21,14 +21,38 @@
*/
package org.jbpm.pvm.internal.script;
-import de.odysseus.el.util.SimpleResolver;
-
-import javax.el.*;
-import javax.script.*;
import java.io.IOException;
import java.io.Reader;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
+import java.util.Properties;
+
+import javax.el.ArrayELResolver;
+import javax.el.BeanELResolver;
+import javax.el.CompositeELResolver;
+import javax.el.ELContext;
+import javax.el.ELException;
+import javax.el.ELResolver;
+import javax.el.ExpressionFactory;
+import javax.el.FunctionMapper;
+import javax.el.ListELResolver;
+import javax.el.MapELResolver;
+import javax.el.ResourceBundleELResolver;
+import javax.el.ValueExpression;
+import javax.el.VariableMapper;
+import javax.script.AbstractScriptEngine;
+import javax.script.Bindings;
+import javax.script.Compilable;
+import javax.script.CompiledScript;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+import javax.script.ScriptException;
+import javax.script.SimpleBindings;
+
+import org.jbpm.pvm.internal.env.ExecutionContext;
+
+import de.odysseus.el.util.SimpleResolver;
class JuelScriptEngine extends AbstractScriptEngine
implements Compilable
@@ -369,8 +393,16 @@
return exprFactory.createValueExpression(
value, Object.class);
+ } else {
+ // to support null value for existing variables
+ Bindings b = this.ctx.getBindings(ScriptContext.ENGINE_SCOPE);
+ ExecutionContext execContext = (ExecutionContext) ((EnvironmentBindings) b).environment.getContext("execution");
+ // if variable name exist then set value expression as null
+ // since it was not discovered by attribute scope method
+ if (execContext.getExecution().getVariables().containsKey(variable)) {
+ return exprFactory.createValueExpression(null, Object.class);
+ }
}
-
return null;
}