[jbpm-commits] JBoss JBPM SVN: r5706 - in jbpm4/trunk/modules: jpdl/src/main/java/org/jbpm/jpdl/internal/activity and 11 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Tue Oct 6 11:38:05 EDT 2009


Author: tom.baeyens at jboss.com
Date: 2009-10-06 11:38:04 -0400 (Tue, 06 Oct 2009)
New Revision: 5706

Added:
   jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/CustomActivity.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/UserCodeReference.java
   jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/
   jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/custom/
   jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/custom/CustomConfigurationsTest.java
   jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/java/
   jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/java/Hand.java
   jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/java/JavaActivity40Test.java
   jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/java/JoeSmoe.java
Modified:
   jbpm4/trunk/modules/devguide/src/main/docbook/en/modules/ch02-Incubation.xml
   jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/CustomBinding.java
   jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/DecisionBinding.java
   jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/EndBinding.java
   jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/EndCancelBinding.java
   jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/EndErrorBinding.java
   jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/EventListenerBinding.java
   jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/ForkBinding.java
   jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/GroupBinding.java
   jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/HqlBinding.java
   jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/JavaBinding.java
   jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/JoinBinding.java
   jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/JpdlBinding.java
   jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/MailBinding.java
   jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/ScriptBinding.java
   jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/StartBinding.java
   jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/StateBinding.java
   jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/SubProcessBinding.java
   jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/TaskBinding.java
   jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/xml/JpdlParser.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/binding/ObjectBinding.java
   jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/xml/Bindings.java
   jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/eventlistener/EventListenerTest.java
   jbpm4/trunk/modules/test-db/src/test/resources/logging.properties
   jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch06-Jpdl.xml
Log:
JBPM-2565 refactored custom parsing to use UserCodeReference

Modified: jbpm4/trunk/modules/devguide/src/main/docbook/en/modules/ch02-Incubation.xml
===================================================================
--- jbpm4/trunk/modules/devguide/src/main/docbook/en/modules/ch02-Incubation.xml	2009-10-06 06:19:58 UTC (rev 5705)
+++ jbpm4/trunk/modules/devguide/src/main/docbook/en/modules/ch02-Incubation.xml	2009-10-06 15:38:04 UTC (rev 5706)
@@ -692,4 +692,20 @@
     </section>
   </section>
 
+  <section>
+    <title>User object caching</title>
+    <para>As indicated in section "User code" in the Users guide, instantiated user objects 
+    are by default cached as part of the process definition.  So the single user object will 
+    be used to serve all requests.  So you have to make sure that when your user code is used, 
+    that it doesn't change the member fields of the user object.  In that case it will be safe
+    for your user object to be used by all threads/requests.  This is also called stateless 
+    user objects.       
+    </para>
+    <para>In case you do have a need for stateful user objects, you can specify 
+    parameter <literal>cache="disabled"</literal> on the definition of the user 
+    code.  In that case a new user code object will be instatiated for every 
+    usage.
+    </para>
+  </section>
+  
 </chapter>

Added: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/CustomActivity.java
===================================================================
--- jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/CustomActivity.java	                        (rev 0)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/CustomActivity.java	2009-10-06 15:38:04 UTC (rev 5706)
@@ -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.jpdl.internal.activity;
+
+import java.util.Map;
+
+import org.jbpm.api.activity.ActivityBehaviour;
+import org.jbpm.api.activity.ActivityExecution;
+import org.jbpm.api.activity.ExternalActivityBehaviour;
+import org.jbpm.pvm.internal.wire.UserCodeReference;
+
+
+/**
+ * @author Tom Baeyens
+ */
+public class CustomActivity extends JpdlExternalActivity {
+
+  private static final long serialVersionUID = 1L;
+
+  protected UserCodeReference customActivityReference;
+
+  public void execute(ActivityExecution execution) throws Exception {
+    ActivityBehaviour activityBehaviour = (ActivityBehaviour) customActivityReference.getObject(execution);
+    activityBehaviour.execute(execution);
+  }
+
+  public void signal(ActivityExecution execution, String signalName, Map<String, ? > parameters) throws Exception {
+    ExternalActivityBehaviour externalActivityBehaviour = (ExternalActivityBehaviour) customActivityReference.getObject(execution);
+    externalActivityBehaviour.signal(execution, signalName, parameters);
+  }
+
+  public void setCustomActivityReference(UserCodeReference customActivityReference) {
+    this.customActivityReference = customActivityReference;
+  }
+}


Property changes on: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/CustomActivity.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Modified: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/CustomBinding.java
===================================================================
--- jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/CustomBinding.java	2009-10-06 06:19:58 UTC (rev 5705)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/CustomBinding.java	2009-10-06 15:38:04 UTC (rev 5706)
@@ -21,13 +21,11 @@
  */
 package org.jbpm.jpdl.internal.activity;
 
-import org.jbpm.api.activity.ActivityBehaviour;
-import org.jbpm.pvm.internal.wire.JbpmClassNotFoundException;
-import org.jbpm.pvm.internal.wire.WireContext;
+import org.jbpm.jpdl.internal.xml.JpdlParser;
+import org.jbpm.pvm.internal.wire.UserCodeReference;
 import org.jbpm.pvm.internal.wire.binding.ObjectBinding;
 import org.jbpm.pvm.internal.wire.descriptor.ObjectDescriptor;
 import org.jbpm.pvm.internal.xml.Parse;
-import org.jbpm.pvm.internal.xml.Parser;
 import org.w3c.dom.Element;
 
 
@@ -42,14 +40,10 @@
     super("custom");
   }
 
-  public Object parse(Element element, Parse parse, Parser parser) {
-    ObjectDescriptor customActivitydescriptor = (ObjectDescriptor) objectBinding.parse(element, parse, wireParser);
-    try {
-      ActivityBehaviour customActivityBehaviour = (ActivityBehaviour) WireContext.create(customActivitydescriptor);
-      return customActivityBehaviour;
-      
-    } catch (JbpmClassNotFoundException e) {
-      return customActivitydescriptor;
-    }
+  public Object parseJpdl(Element element, Parse parse, JpdlParser parser) {
+    CustomActivity customActivity = new CustomActivity();
+    UserCodeReference customActivityReference = parser.parseUserCodeReference(element, parse);
+    customActivity.setCustomActivityReference(customActivityReference);
+    return customActivity;
   }
 }

Modified: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/DecisionBinding.java
===================================================================
--- jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/DecisionBinding.java	2009-10-06 06:19:58 UTC (rev 5705)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/DecisionBinding.java	2009-10-06 15:38:04 UTC (rev 5706)
@@ -23,6 +23,7 @@
 
 import java.util.List;
 
+import org.jbpm.jpdl.internal.xml.JpdlParser;
 import org.jbpm.pvm.internal.model.ActivityImpl;
 import org.jbpm.pvm.internal.model.TransitionImpl;
 import org.jbpm.pvm.internal.util.XmlUtil;
@@ -32,7 +33,6 @@
 import org.jbpm.pvm.internal.wire.descriptor.ReferenceDescriptor;
 import org.jbpm.pvm.internal.wire.xml.WireParser;
 import org.jbpm.pvm.internal.xml.Parse;
-import org.jbpm.pvm.internal.xml.Parser;
 import org.w3c.dom.Element;
 
 
@@ -48,7 +48,7 @@
     super("decision");
   }
 
-  public Object parse(Element element, Parse parse, Parser parser) {
+  public Object parseJpdl(Element element, Parse parse, JpdlParser parser) {
     if (element.hasAttribute("expr")) {
       DecisionExpressionActivity decisionExpressionActivity = new DecisionExpressionActivity();
       String expr = element.getAttribute("expr");

Modified: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/EndBinding.java
===================================================================
--- jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/EndBinding.java	2009-10-06 06:19:58 UTC (rev 5705)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/EndBinding.java	2009-10-06 15:38:04 UTC (rev 5706)
@@ -21,9 +21,9 @@
  */
 package org.jbpm.jpdl.internal.activity;
 
+import org.jbpm.jpdl.internal.xml.JpdlParser;
 import org.jbpm.pvm.internal.util.XmlUtil;
 import org.jbpm.pvm.internal.xml.Parse;
-import org.jbpm.pvm.internal.xml.Parser;
 import org.w3c.dom.Element;
 
 
@@ -40,7 +40,7 @@
     super(tag);
   }
 
-  public Object parse(Element element, Parse parse, Parser parser) {
+  public Object parseJpdl(Element element, Parse parse, JpdlParser parser) {
     
     boolean endProcessInstance = true;
     String ends = XmlUtil.attribute(element, "ends", false, parse);

Modified: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/EndCancelBinding.java
===================================================================
--- jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/EndCancelBinding.java	2009-10-06 06:19:58 UTC (rev 5705)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/EndCancelBinding.java	2009-10-06 15:38:04 UTC (rev 5706)
@@ -21,8 +21,8 @@
  */
 package org.jbpm.jpdl.internal.activity;
 
+import org.jbpm.jpdl.internal.xml.JpdlParser;
 import org.jbpm.pvm.internal.xml.Parse;
-import org.jbpm.pvm.internal.xml.Parser;
 import org.w3c.dom.Element;
 
 
@@ -35,8 +35,8 @@
     super("end-cancel");
   }
 
-  public Object parse(Element element, Parse parse, Parser parser) {
-    EndActivity endActivity = (EndActivity) super.parse(element, parse, parser);
+  public Object parseJpdl(Element element, Parse parse, JpdlParser parser) {
+    EndActivity endActivity = (EndActivity) super.parseJpdl(element, parse, parser);
     endActivity.setState("cancel");
     return endActivity;
   }

Modified: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/EndErrorBinding.java
===================================================================
--- jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/EndErrorBinding.java	2009-10-06 06:19:58 UTC (rev 5705)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/EndErrorBinding.java	2009-10-06 15:38:04 UTC (rev 5706)
@@ -21,8 +21,8 @@
  */
 package org.jbpm.jpdl.internal.activity;
 
+import org.jbpm.jpdl.internal.xml.JpdlParser;
 import org.jbpm.pvm.internal.xml.Parse;
-import org.jbpm.pvm.internal.xml.Parser;
 import org.w3c.dom.Element;
 
 
@@ -35,8 +35,8 @@
     super("end-error");
   }
 
-  public Object parse(Element element, Parse parse, Parser parser) {
-    EndActivity endActivity = (EndActivity) super.parse(element, parse, parser);
+  public Object parseJpdl(Element element, Parse parse, JpdlParser parser) {
+    EndActivity endActivity = (EndActivity) super.parseJpdl(element, parse, parser);
     endActivity.setState("error");
     return endActivity;
   }

Modified: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/EventListenerBinding.java
===================================================================
--- jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/EventListenerBinding.java	2009-10-06 06:19:58 UTC (rev 5705)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/EventListenerBinding.java	2009-10-06 15:38:04 UTC (rev 5706)
@@ -27,7 +27,6 @@
 import org.jbpm.pvm.internal.wire.JbpmClassNotFoundException;
 import org.jbpm.pvm.internal.wire.WireContext;
 import org.jbpm.pvm.internal.xml.Parse;
-import org.jbpm.pvm.internal.xml.Parser;
 import org.w3c.dom.Element;
 
 
@@ -40,7 +39,7 @@
     super("event-listener");
   }
 
-  public Object parse(Element element, Parse parse, Parser parser) {
+  public Object parseJpdl(Element element, Parse parse, JpdlParser parser) {
     Descriptor eventListenerDescriptor = JpdlParser.parseObjectDescriptor(element, parse);
     try {
       EventListener eventListener = (EventListener) WireContext.create(eventListenerDescriptor);

Modified: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/ForkBinding.java
===================================================================
--- jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/ForkBinding.java	2009-10-06 06:19:58 UTC (rev 5705)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/ForkBinding.java	2009-10-06 15:38:04 UTC (rev 5706)
@@ -21,8 +21,8 @@
  */
 package org.jbpm.jpdl.internal.activity;
 
+import org.jbpm.jpdl.internal.xml.JpdlParser;
 import org.jbpm.pvm.internal.xml.Parse;
-import org.jbpm.pvm.internal.xml.Parser;
 import org.w3c.dom.Element;
 
 
@@ -35,7 +35,7 @@
     super("fork");
   }
 
-  public Object parse(Element element, Parse parse, Parser parser) {
+  public Object parseJpdl(Element element, Parse parse, JpdlParser parser) {
     return new ForkActivity();
   }
 

Modified: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/GroupBinding.java
===================================================================
--- jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/GroupBinding.java	2009-10-06 06:19:58 UTC (rev 5705)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/GroupBinding.java	2009-10-06 15:38:04 UTC (rev 5706)
@@ -24,7 +24,6 @@
 import org.jbpm.jpdl.internal.xml.JpdlParser;
 import org.jbpm.pvm.internal.model.ActivityImpl;
 import org.jbpm.pvm.internal.xml.Parse;
-import org.jbpm.pvm.internal.xml.Parser;
 import org.w3c.dom.Element;
 
 
@@ -37,13 +36,12 @@
     super("group");
   }
 
-  public Object parse(Element element, Parse parse, Parser parser) {
+  public Object parseJpdl(Element element, Parse parse, JpdlParser parser) {
     GroupActivity groupActivity = new GroupActivity();
     
     ActivityImpl activity = parse.contextStackFind(ActivityImpl.class);
 
-    JpdlParser jpdlParser = (JpdlParser) parser;
-    jpdlParser.parseActivities(element, parse, activity);
+    parser.parseActivities(element, parse, activity);
 
     return groupActivity;
   }

Modified: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/HqlBinding.java
===================================================================
--- jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/HqlBinding.java	2009-10-06 06:19:58 UTC (rev 5705)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/HqlBinding.java	2009-10-06 15:38:04 UTC (rev 5706)
@@ -24,12 +24,12 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.jbpm.jpdl.internal.xml.JpdlParser;
 import org.jbpm.pvm.internal.util.XmlUtil;
 import org.jbpm.pvm.internal.wire.Descriptor;
 import org.jbpm.pvm.internal.wire.descriptor.ListDescriptor;
 import org.jbpm.pvm.internal.wire.xml.WireParser;
 import org.jbpm.pvm.internal.xml.Parse;
-import org.jbpm.pvm.internal.xml.Parser;
 import org.w3c.dom.Element;
 
 
@@ -48,7 +48,7 @@
     super(tagName);
   }
 
-  public Object parse(Element element, Parse parse, Parser parser) {
+  public Object parseJpdl(Element element, Parse parse, JpdlParser parser) {
     HqlActivity hqlActivity = createHqlActivity();
     
     Element queryElement = XmlUtil.element(element, "query", true, parse);

Modified: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/JavaBinding.java
===================================================================
--- jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/JavaBinding.java	2009-10-06 06:19:58 UTC (rev 5705)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/JavaBinding.java	2009-10-06 15:38:04 UTC (rev 5706)
@@ -30,7 +30,6 @@
 import org.jbpm.pvm.internal.wire.descriptor.ObjectDescriptor;
 import org.jbpm.pvm.internal.wire.operation.InvokeOperation;
 import org.jbpm.pvm.internal.xml.Parse;
-import org.jbpm.pvm.internal.xml.Parser;
 import org.w3c.dom.Element;
 
 
@@ -45,7 +44,7 @@
     super(TAG);
   }
 
-  public Object parse(Element element, Parse parse, Parser parser) {
+  public Object parseJpdl(Element element, Parse parse, JpdlParser parser) {
     JavaActivity javaActivity = new JavaActivity();
 
     String methodName = XmlUtil.attribute(element, "method", true, parse, null);

Modified: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/JoinBinding.java
===================================================================
--- jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/JoinBinding.java	2009-10-06 06:19:58 UTC (rev 5705)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/JoinBinding.java	2009-10-06 15:38:04 UTC (rev 5706)
@@ -22,8 +22,8 @@
 package org.jbpm.jpdl.internal.activity;
 
 import org.hibernate.LockMode;
+import org.jbpm.jpdl.internal.xml.JpdlParser;
 import org.jbpm.pvm.internal.xml.Parse;
-import org.jbpm.pvm.internal.xml.Parser;
 import org.w3c.dom.Element;
 
 
@@ -40,7 +40,7 @@
     super("join");
   }
 
-  public Object parse(Element element, Parse parse, Parser parser) {
+  public Object parseJpdl(Element element, Parse parse, JpdlParser parser) {
     JoinActivity joinActivity = new JoinActivity();
                             
     if (element.hasAttribute(MULTIPLICITY)) {

Modified: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/JpdlBinding.java
===================================================================
--- jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/JpdlBinding.java	2009-10-06 06:19:58 UTC (rev 5705)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/JpdlBinding.java	2009-10-06 15:38:04 UTC (rev 5706)
@@ -34,6 +34,7 @@
 import org.jbpm.pvm.internal.util.XmlUtil;
 import org.jbpm.pvm.internal.wire.xml.WireParser;
 import org.jbpm.pvm.internal.xml.Parse;
+import org.jbpm.pvm.internal.xml.Parser;
 import org.w3c.dom.Element;
 
 
@@ -48,6 +49,12 @@
     super(tagName, null, null);
   }
 
+  public abstract Object parseJpdl(Element element, Parse parse, JpdlParser parser);
+
+  public final Object parse(Element element, Parse parse, Parser parser) {
+    return parseJpdl(element, parse, (JpdlParser) parser);
+  }
+
   public void parseName(Element element, ActivityImpl activity, Parse parse) {
     String name = XmlUtil.attribute(element, "name", isNameRequired(), parse);
     

Modified: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/MailBinding.java
===================================================================
--- jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/MailBinding.java	2009-10-06 06:19:58 UTC (rev 5705)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/MailBinding.java	2009-10-06 15:38:04 UTC (rev 5706)
@@ -21,11 +21,9 @@
  */
 package org.jbpm.jpdl.internal.activity;
 
-import org.w3c.dom.Element;
-
 import org.jbpm.jpdl.internal.xml.JpdlParser;
 import org.jbpm.pvm.internal.xml.Parse;
-import org.jbpm.pvm.internal.xml.Parser;
+import org.w3c.dom.Element;
 
 /**
  * @author Alejandro Guizar
@@ -36,7 +34,7 @@
     super("mail");
   }
 
-  public Object parse(Element element, Parse parse, Parser parser) {
+  public Object parseJpdl(Element element, Parse parse, JpdlParser parser) {
     MailActivity activity = new MailActivity();
     activity.setMailProducer(JpdlParser.parseMailProducer(element, parse, null));
     return activity;

Modified: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/ScriptBinding.java
===================================================================
--- jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/ScriptBinding.java	2009-10-06 06:19:58 UTC (rev 5705)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/ScriptBinding.java	2009-10-06 15:38:04 UTC (rev 5706)
@@ -21,11 +21,11 @@
  */
 package org.jbpm.jpdl.internal.activity;
 
+import org.jbpm.jpdl.internal.xml.JpdlParser;
 import org.jbpm.pvm.internal.env.EnvironmentImpl;
 import org.jbpm.pvm.internal.script.ScriptManager;
 import org.jbpm.pvm.internal.util.XmlUtil;
 import org.jbpm.pvm.internal.xml.Parse;
-import org.jbpm.pvm.internal.xml.Parser;
 import org.w3c.dom.Element;
 
 
@@ -40,7 +40,7 @@
     super(TAG);
   }
 
-  public Object parse(Element element, Parse parse, Parser parser) {
+  public Object parseJpdl(Element element, Parse parse, JpdlParser parser) {
     String language = null;
 
     String script = XmlUtil.attribute(element, "expr");

Modified: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/StartBinding.java
===================================================================
--- jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/StartBinding.java	2009-10-06 06:19:58 UTC (rev 5705)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/StartBinding.java	2009-10-06 15:38:04 UTC (rev 5706)
@@ -22,10 +22,10 @@
 package org.jbpm.jpdl.internal.activity;
 
 import org.jbpm.jpdl.internal.model.JpdlProcessDefinition;
+import org.jbpm.jpdl.internal.xml.JpdlParser;
 import org.jbpm.pvm.internal.model.ActivityImpl;
 import org.jbpm.pvm.internal.util.XmlUtil;
 import org.jbpm.pvm.internal.xml.Parse;
-import org.jbpm.pvm.internal.xml.Parser;
 import org.w3c.dom.Element;
 
 
@@ -38,7 +38,7 @@
     super("start");
   }
 
-  public Object parse(Element element, Parse parse, Parser parser) {
+  public Object parseJpdl(Element element, Parse parse, JpdlParser parser) {
     ActivityImpl startActivity = parse.contextStackFind(ActivityImpl.class);
     JpdlProcessDefinition processDefinition = parse.contextStackFind(JpdlProcessDefinition.class);
     

Modified: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/StateBinding.java
===================================================================
--- jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/StateBinding.java	2009-10-06 06:19:58 UTC (rev 5705)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/StateBinding.java	2009-10-06 15:38:04 UTC (rev 5706)
@@ -21,8 +21,8 @@
  */
 package org.jbpm.jpdl.internal.activity;
 
+import org.jbpm.jpdl.internal.xml.JpdlParser;
 import org.jbpm.pvm.internal.xml.Parse;
-import org.jbpm.pvm.internal.xml.Parser;
 import org.w3c.dom.Element;
 
 
@@ -35,7 +35,7 @@
     super("state");
   }
 
-  public Object parse(Element element, Parse parse, Parser parser) {
+  public Object parseJpdl(Element element, Parse parse, JpdlParser parser) {
     return new StateActivity();
   }
 

Modified: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/SubProcessBinding.java
===================================================================
--- jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/SubProcessBinding.java	2009-10-06 06:19:58 UTC (rev 5705)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/SubProcessBinding.java	2009-10-06 15:38:04 UTC (rev 5706)
@@ -26,12 +26,12 @@
 import java.util.List;
 import java.util.Map;
 
+import org.jbpm.jpdl.internal.xml.JpdlParser;
 import org.jbpm.pvm.internal.util.XmlUtil;
 import org.jbpm.pvm.internal.wire.Descriptor;
 import org.jbpm.pvm.internal.wire.WireContext;
 import org.jbpm.pvm.internal.wire.xml.WireParser;
 import org.jbpm.pvm.internal.xml.Parse;
-import org.jbpm.pvm.internal.xml.Parser;
 import org.w3c.dom.Element;
 
 
@@ -44,7 +44,7 @@
     super("sub-process");
   }
 
-  public Object parse(Element element, Parse parse, Parser parser) {
+  public Object parseJpdl(Element element, Parse parse, JpdlParser parser) {
     SubProcessActivity subProcessActivity = new SubProcessActivity();
     
     String subProcessKey = XmlUtil.attribute(element, "sub-process-key");

Modified: jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/TaskBinding.java
===================================================================
--- jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/TaskBinding.java	2009-10-06 06:19:58 UTC (rev 5705)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/activity/TaskBinding.java	2009-10-06 15:38:04 UTC (rev 5706)
@@ -25,7 +25,6 @@
 import org.jbpm.pvm.internal.model.ScopeElementImpl;
 import org.jbpm.pvm.internal.task.TaskDefinitionImpl;
 import org.jbpm.pvm.internal.xml.Parse;
-import org.jbpm.pvm.internal.xml.Parser;
 import org.w3c.dom.Element;
 
 /**
@@ -39,7 +38,7 @@
     super(TAG);
   }
 
-  public Object parse(Element element, Parse parse, Parser parser) {
+  public Object parseJpdl(Element element, Parse parse, JpdlParser parser) {
     TaskActivity taskActivity = new TaskActivity();
 
     ScopeElementImpl scopeElement = parse.contextStackFind(ScopeElementImpl.class);

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	2009-10-06 06:19:58 UTC (rev 5705)
+++ jbpm4/trunk/modules/jpdl/src/main/java/org/jbpm/jpdl/internal/xml/JpdlParser.java	2009-10-06 15:38:04 UTC (rev 5706)
@@ -66,6 +66,7 @@
 import org.jbpm.pvm.internal.task.TaskDefinitionImpl;
 import org.jbpm.pvm.internal.util.XmlUtil;
 import org.jbpm.pvm.internal.wire.Descriptor;
+import org.jbpm.pvm.internal.wire.UserCodeReference;
 import org.jbpm.pvm.internal.wire.WireContext;
 import org.jbpm.pvm.internal.wire.binding.MailTemplateBinding;
 import org.jbpm.pvm.internal.wire.binding.ObjectBinding;
@@ -99,6 +100,7 @@
   }
 
   public static final WireParser wireParser = WireParser.getInstance();
+  public static final ObjectBinding objectBinding = ObjectBinding.INSTANCE;
 
   // array elements are mutable, even when final
   // never make a static array public
@@ -167,23 +169,38 @@
 
       // make the process language version available for bindings
       // to allow for specific parsing behaviour per version
+      
+      // first check if the langid is available as a deployment property
       DeploymentImpl deployment = (DeploymentImpl) parse.contextMapGet(Parse.CONTEXT_KEY_DEPLOYMENT);
       if (deployment!=null) {
         String processLanguageId = deployment.getProcessLanguageId(name);
         if (processLanguageId==null) {
+          // if it is not available as a deployment property, check if the 
+          // jpdlparser attribute specifies a specific jpdl version.
+          // this is the case for certain compatibility tests in our test suite
           String jpdlParser = XmlUtil.attribute(documentElement, "jpdlparser");
           if (jpdlParser!=null) {
             processLanguageId = "jpdl-"+jpdlParser;
 
           } else {
-            // specify the jpdltestversion with "mvn -Djpdltestversion=jpdl-4.3 clean install"
+            // if none of the above, check if this is a parser test run for a specific verion
+            // specify the jpdltestversion with "mvn -Djpdlparser=jpdl-4.3 clean install"
             // that way, the whole test suite will be use the specified parser
             jpdlParser = System.getProperty("jpdlparser");
             if (jpdlParser!=null) {
               processLanguageId = "jpdl-"+jpdlParser;
 
             } else {
-              processLanguageId = CURRENT_VERSION_PROCESS_LANGUAGE_ID;
+              // if this process has a namespace, then use the namespace 
+              // to see what jpdl parser version should be used
+              String namespaceUri = documentElement.getNamespaceURI();
+              if (namespaceUri!=null) {
+                processLanguageId = "jpdl-"+namespaceUri.substring(16, 19);
+
+              } else {
+                // if none of the above, just deploy it as the current library version
+                processLanguageId = CURRENT_VERSION_PROCESS_LANGUAGE_ID;
+              }
             }
           }
           // saving the process language will make sure that  
@@ -716,5 +733,20 @@
     parse.addProblem("mail template not found: " + templateName, element);
     return null;
   }
+
+  // generic helper methods for jpdl activity and event listener bindings /////
   
+  public UserCodeReference parseUserCodeReference(Element element, Parse parse) {
+    UserCodeReference userCodeReference = new UserCodeReference();
+
+    ObjectDescriptor objectDescriptor = (ObjectDescriptor) objectBinding.parse(element, parse, wireParser);
+    userCodeReference.setDescriptor(objectDescriptor);
+
+    Boolean isCached = XmlUtil.attributeBoolean(element, "cache", false, parse, null);
+    if (isCached!=null) {
+      userCodeReference.setCached(isCached.booleanValue());
+    }
+    
+    return userCodeReference;
+  }
 }

Added: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/UserCodeReference.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/UserCodeReference.java	                        (rev 0)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/UserCodeReference.java	2009-10-06 15:38:04 UTC (rev 5706)
@@ -0,0 +1,93 @@
+/*
+ * 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.wire;
+
+import java.io.Serializable;
+
+import org.jbpm.api.Execution;
+import org.jbpm.pvm.internal.model.ActivityImpl;
+import org.jbpm.pvm.internal.model.ExecutionImpl;
+import org.jbpm.pvm.internal.model.ProcessDefinitionImpl;
+import org.jbpm.pvm.internal.model.TransitionImpl;
+import org.jbpm.pvm.internal.util.ReflectUtil;
+
+
+/**
+ * @author Tom Baeyens
+ */
+public class UserCodeReference implements Serializable {
+
+  private static final long serialVersionUID = 1L;
+
+  protected boolean isCached = true;
+  protected Object cachedObject;
+  protected Descriptor descriptor;
+
+  public Object getObject(Execution execution) {
+    return getObject(null, execution);
+  }
+
+  public Object getObject(ProcessDefinitionImpl processDefinition) {
+    return getObject(processDefinition, null);
+  }
+
+  protected Object getObject(ProcessDefinitionImpl processDefinition, Execution execution) {
+    if (cachedObject!=null) {
+      return cachedObject;
+    }
+    if (descriptor!=null) {
+      if (processDefinition==null) {
+        processDefinition = getProcessDefinition(execution);
+      }
+
+      Object usedObject = ReflectUtil.instantiateUserCode(descriptor, processDefinition);
+      if (isCached) {
+        cachedObject = usedObject;
+      }
+      return usedObject;
+    }
+    return null;
+  }
+
+  protected ProcessDefinitionImpl getProcessDefinition(Execution execution) {
+    ProcessDefinitionImpl processDefinition = null;
+    ExecutionImpl executionImpl = (ExecutionImpl) execution;
+    ActivityImpl activity = executionImpl.getActivity();
+    TransitionImpl transition = executionImpl.getTransition();
+    if (activity!=null) {
+      processDefinition = activity.getProcessDefinition();
+    }
+    if ( (processDefinition==null)
+         && (transition!=null)
+       ) {
+      processDefinition = transition.getProcessDefinition();
+    }
+    return processDefinition;
+  }
+
+  public void setCached(boolean isCached) {
+    this.isCached = isCached;
+  }
+  public void setDescriptor(Descriptor descriptor) {
+    this.descriptor = descriptor;
+  }
+}


Property changes on: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/UserCodeReference.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/binding/ObjectBinding.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/binding/ObjectBinding.java	2009-10-06 06:19:58 UTC (rev 5705)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/binding/ObjectBinding.java	2009-10-06 15:38:04 UTC (rev 5706)
@@ -47,6 +47,7 @@
 public class ObjectBinding extends WireDescriptorBinding {
   
   public static final String TAG = "object";
+  public static final ObjectBinding INSTANCE = new ObjectBinding();
 
   public ObjectBinding() {
     super(TAG);

Modified: jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/xml/Bindings.java
===================================================================
--- jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/xml/Bindings.java	2009-10-06 06:19:58 UTC (rev 5705)
+++ jbpm4/trunk/modules/pvm/src/main/java/org/jbpm/pvm/internal/xml/Bindings.java	2009-10-06 15:38:04 UTC (rev 5706)
@@ -117,11 +117,15 @@
   
   /** the set of all tagNames for which there is a binding specified in the given category */
   public Set<String> getTagNames(String category) {
+    Set<String> tagNames = new HashSet<String>();
+
     List<Binding> categoryBindings = (bindings!=null ? bindings.get(category) : null );
-    Set<String> tagNames = new HashSet<String>();
-    for (Binding binding: categoryBindings) {
-      tagNames.add(binding.toString());
+    if (categoryBindings!=null) {
+      for (Binding binding: categoryBindings) {
+        tagNames.add(binding.toString());
+      }
     }
+    
     return tagNames;
   }
 }

Added: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/custom/CustomConfigurationsTest.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/custom/CustomConfigurationsTest.java	                        (rev 0)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/custom/CustomConfigurationsTest.java	2009-10-06 15:38:04 UTC (rev 5706)
@@ -0,0 +1,292 @@
+/*
+ * 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.custom;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.jbpm.api.ProcessInstance;
+import org.jbpm.api.activity.ActivityBehaviour;
+import org.jbpm.api.activity.ActivityExecution;
+import org.jbpm.api.activity.ExternalActivityBehaviour;
+import org.jbpm.test.JbpmTestCase;
+
+
+/**
+ * @author Tom Baeyens
+ */
+public class CustomConfigurationsTest extends JbpmTestCase {
+  
+  public static class MyCustomAutomatic implements ActivityBehaviour {
+    private static final long serialVersionUID = 1L;
+    public void execute(ActivityExecution execution) throws Exception {
+    }
+  }
+
+  public void testCustomAutomaticClass() {
+    deployJpdlXmlString(
+        "<process name='CustomClass'>" +
+        "  <start>" +
+        "    <transition to='c' />" +
+        "  </start>" +
+        "  <custom name='c' class='"+MyCustomAutomatic.class.getName()+"'>" +
+        "    <transition to='wait' />" +
+        "  </custom>" +
+        "  <state name='wait'/>" +
+        "</process>"
+    );
+    
+    ProcessInstance processInstance = executionService.startProcessInstanceByKey("CustomClass");
+
+    assertTrue(processInstance.findActiveActivityNames().contains("wait"));
+  }
+
+  public static class MyCustomWait implements ExternalActivityBehaviour {
+    private static final long serialVersionUID = 1L;
+    public void execute(ActivityExecution execution) throws Exception {
+      execution.waitForSignal();
+    }
+    public void signal(ActivityExecution execution, String signalName, Map<String, ? > parameters) throws Exception {
+      execution.take("3");
+    }
+  }
+
+  public void testCustomWaitClass() {
+    deployJpdlXmlString(
+        "<process name='CustomClass'>" +
+        "  <start>" +
+        "    <transition to='c' />" +
+        "  </start>" +
+        "  <custom name='c' class='"+MyCustomWait.class.getName()+"'>" +
+        "    <transition name='1' to='the 1st way' />" +
+        "    <transition name='2' to='the 2nd way' />" +
+        "    <transition name='3' to='the 3rd way' />" +
+        "  </custom>" +
+        "  <state name='the 1st way' />" +
+        "  <state name='the 2nd way' />" +
+        "  <state name='the 3rd way' />" +
+        "</process>"
+    );
+    
+    ProcessInstance processInstance = executionService.startProcessInstanceByKey("CustomClass");
+
+    Set<String> findActiveActivityNames = processInstance.findActiveActivityNames();
+    assertTrue(findActiveActivityNames.contains("c"));
+    
+    processInstance = executionService.signalExecutionById(processInstance.getId());
+    
+    findActiveActivityNames = processInstance.findActiveActivityNames();
+    assertTrue(findActiveActivityNames.contains("the 3rd way"));
+  }
+
+  public static class MyCustomAutomaticWithFieldAndProperty implements ActivityBehaviour {
+    private static final long serialVersionUID = 1L;
+    String text;
+    Long objectLong;
+
+    int basicInt;
+    Integer objectInt;
+    long basicLong;
+    float basicFloat;
+    Float objectFloat;
+    double basicDouble;
+    Double objectDouble;
+    boolean basicBooleanTrue;
+    boolean basicBooleanFalse;
+    Boolean objectBooleanTrue;
+    Boolean objectBooleanFalse;
+    
+    public void execute(ActivityExecution execution) throws Exception {
+      execution.setVariable("text", text);
+      execution.setVariable("number", objectLong);
+      execution.setVariable("basicInt", basicInt);
+      execution.setVariable("objectInt", objectInt);
+      execution.setVariable("basicLong", basicLong);
+      execution.setVariable("basicFloat", basicFloat);
+      execution.setVariable("objectFloat", objectFloat);
+      execution.setVariable("basicDouble", basicDouble);
+      execution.setVariable("objectDouble", objectDouble);
+      execution.setVariable("basicBooleanTrue", basicBooleanTrue);
+      execution.setVariable("basicBooleanFalse", basicBooleanFalse);
+      execution.setVariable("objectBooleanTrue", objectBooleanTrue);
+      execution.setVariable("objectBooleanFalse", objectBooleanFalse);
+    }
+    public void setNumberProperty(Long number) {
+      this.objectLong = number;
+    }
+  }
+
+  public void testCustomAutomaticClassWithInjections() {
+    deployJpdlXmlString(
+        "<process name='CustomClass'>" +
+        "  <start>" +
+        "    <transition to='c' />" +
+        "  </start>" +
+        "  <custom name='c' class='"+MyCustomAutomaticWithFieldAndProperty.class.getName()+"'>" +
+        "    <field name='text'><string value='hi' /></field>" +
+        "    <property name='numberProperty'><long value='5' /></property>" +
+        "    <field name='basicInt'><int value='6' /></field>" +
+        "    <field name='objectInt'><int value='7' /></field>" +
+        "    <field name='basicLong'><long value='99999999999' /></field>" +
+        "    <field name='basicFloat'><float value='99.99' /></field>" +
+        "    <field name='objectFloat'><float value='88.88' /></field>" +
+        "    <field name='basicDouble'><double value='9999999999.99' /></field>" +
+        "    <field name='objectDouble'><double value='8888888888.88' /></field>" +
+        "    <field name='basicBooleanTrue'><true /></field>" +
+        "    <field name='basicBooleanFalse'><false /></field>" +
+        "    <field name='objectBooleanTrue'><true /></field>" +
+        "    <field name='objectBooleanFalse'><false /></field>" +
+        "    <transition to='wait' />" +
+        "  </custom>" +
+        "  <state name='wait'/>" +
+        "</process>"
+    );
+    
+    ProcessInstance processInstance = executionService.startProcessInstanceByKey("CustomClass");
+
+    assertTrue(processInstance.findActiveActivityNames().contains("wait"));
+    
+    assertEquals("hi", executionService.getVariable(processInstance.getId(), "text"));
+    assertEquals(new Long(5), executionService.getVariable(processInstance.getId(), "number"));
+
+    assertEquals(new Integer("6"), executionService.getVariable(processInstance.getId(), "basicInt"));
+    assertEquals(new Integer("7"), executionService.getVariable(processInstance.getId(), "objectInt"));
+    assertEquals(99999999999L, executionService.getVariable(processInstance.getId(), "basicLong"));
+    assertEquals(new Float("99.99"), executionService.getVariable(processInstance.getId(), "basicFloat"));
+    assertEquals(new Float("88.88"), executionService.getVariable(processInstance.getId(), "objectFloat"));
+    assertEquals(new Double("9999999999.99"), executionService.getVariable(processInstance.getId(), "basicDouble"));
+    assertEquals(new Double("8888888888.88"), executionService.getVariable(processInstance.getId(), "objectDouble"));
+    assertEquals(Boolean.TRUE, executionService.getVariable(processInstance.getId(), "basicBooleanTrue"));
+    assertEquals(Boolean.FALSE, executionService.getVariable(processInstance.getId(), "basicBooleanFalse"));
+    assertEquals(Boolean.TRUE, executionService.getVariable(processInstance.getId(), "objectBooleanTrue"));
+    assertEquals(Boolean.FALSE, executionService.getVariable(processInstance.getId(), "objectBooleanFalse"));
+  }
+
+
+  public void testCustomAutomaticExpr() {
+    deployJpdlXmlString(
+        "<process name='CustomExpr'>" +
+        "  <start>" +
+        "    <transition to='c' />" +
+        "  </start>" +
+        "  <custom name='c' expr='#{custombehaviour}'>" +
+        "    <transition to='wait' />" +
+        "  </custom>" +
+        "  <state name='wait'/>" +
+        "</process>"
+    );
+
+    Map<String, Object> variables = new HashMap<String, Object>();
+    variables.put("custombehaviour", new MyCustomAutomatic());
+    ProcessInstance processInstance = executionService.startProcessInstanceByKey("CustomExpr", variables);
+
+    assertTrue(processInstance.findActiveActivityNames().contains("wait"));
+  }
+
+  public void testCustomWaitExpr() {
+    deployJpdlXmlString(
+        "<process name='CustomExpr'>" +
+        "  <start>" +
+        "    <transition to='c' />" +
+        "  </start>" +
+        "  <custom name='c' expr='#{custombehaviour}'>" +
+        "    <transition name='1' to='the 1st way' />" +
+        "    <transition name='2' to='the 2nd way' />" +
+        "    <transition name='3' to='the 3rd way' />" +
+        "  </custom>" +
+        "  <state name='the 1st way' />" +
+        "  <state name='the 2nd way' />" +
+        "  <state name='the 3rd way' />" +
+        "</process>"
+    );
+    
+    Map<String, Object> variables = new HashMap<String, Object>();
+    variables.put("custombehaviour", new MyCustomWait());
+    ProcessInstance processInstance = executionService.startProcessInstanceByKey("CustomExpr", variables);
+
+    Set<String> findActiveActivityNames = processInstance.findActiveActivityNames();
+    assertTrue(findActiveActivityNames.contains("c"));
+    
+    processInstance = executionService.signalExecutionById(processInstance.getId());
+    
+    findActiveActivityNames = processInstance.findActiveActivityNames();
+    assertTrue(findActiveActivityNames.contains("the 3rd way"));
+  }
+
+  public static class ActivityBehaviourWithId implements ActivityBehaviour {
+    private static final long serialVersionUID = 1L;
+    private static int nextObjectId = 1;
+    int objectId = nextObjectId++;
+    public void execute(ActivityExecution execution) throws Exception {
+      execution.setVariable("objectId", objectId);
+    }
+  }
+
+  public void testCustomUserObjectCachingDefault() {
+    ActivityBehaviourWithId.nextObjectId = 1;
+    deployJpdlXmlString(
+        "<process name='CustomClass'>" +
+        "  <start>" +
+        "    <transition to='c' />" +
+        "  </start>" +
+        "  <custom name='c' class='"+ActivityBehaviourWithId.class.getName()+"'>" +
+        "    <transition to='wait' />" +
+        "  </custom>" +
+        "  <state name='wait'/>" +
+        "</process>"
+    );
+    
+    String pid = executionService.startProcessInstanceByKey("CustomClass").getId();
+    assertEquals(1, executionService.getVariable(pid, "objectId"));
+    
+    pid = executionService.startProcessInstanceByKey("CustomClass").getId();
+    assertEquals(1, executionService.getVariable(pid, "objectId"));
+    
+    pid = executionService.startProcessInstanceByKey("CustomClass").getId();
+    assertEquals(1, executionService.getVariable(pid, "objectId"));
+  }
+
+  public void testCustomUserObjectCachingDisabled() {
+    ActivityBehaviourWithId.nextObjectId = 1;
+    deployJpdlXmlString(
+        "<process name='CustomClass'>" +
+        "  <start>" +
+        "    <transition to='c' />" +
+        "  </start>" +
+        "  <custom name='c' cache='false' class='"+ActivityBehaviourWithId.class.getName()+"'>" +
+        "    <transition to='wait' />" +
+        "  </custom>" +
+        "  <state name='wait'/>" +
+        "</process>"
+    );
+    
+    String pid = executionService.startProcessInstanceByKey("CustomClass").getId();
+    assertEquals(1, executionService.getVariable(pid, "objectId"));
+    
+    pid = executionService.startProcessInstanceByKey("CustomClass").getId();
+    assertEquals(2, executionService.getVariable(pid, "objectId"));
+    
+    pid = executionService.startProcessInstanceByKey("CustomClass").getId();
+    assertEquals(3, executionService.getVariable(pid, "objectId"));
+  }
+}


Property changes on: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/custom/CustomConfigurationsTest.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/java/Hand.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/java/Hand.java	                        (rev 0)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/java/Hand.java	2009-10-06 15:38:04 UTC (rev 5706)
@@ -0,0 +1,47 @@
+/*
+ * 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.java;
+
+import java.io.Serializable;
+
+
+/**
+ * @author Tom Baeyens
+ */
+public class Hand implements Serializable {
+
+  private static final long serialVersionUID = 1L;
+
+  private boolean isShaken;
+
+  public String shake(Integer force, Integer duration) {
+    if (force>3 && duration>7) {
+      return "Nice to meet you.  Wow, what a grip!";
+    }
+    
+    return "Nice to meet you";
+  }
+
+  public boolean isShaken() {
+    return isShaken;
+  }
+}


Property changes on: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/java/Hand.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/java/JavaActivity40Test.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/java/JavaActivity40Test.java	                        (rev 0)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/java/JavaActivity40Test.java	2009-10-06 15:38:04 UTC (rev 5706)
@@ -0,0 +1,63 @@
+/*
+ * 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.java;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jbpm.test.JbpmTestCase;
+
+
+/**
+ * @author Tom Baeyens
+ */
+public class JavaActivity40Test extends JbpmTestCase {
+
+  public void testJavaActivityExpressionJpdl40() {
+    deployJpdlXmlString(
+        "<process name='JavaExpr40' xmlns='http://jbpm.org/4.0/jpdl' jpdlparser='4.0'>" +
+        "  <start>" +
+        "    <transition to='shake hand' />" +
+        "  </start>" +
+        "  <java name='shake hand' " +
+        "        expr='#{hand}'" +
+        "        method='shake'" +
+        "        var='answer'>" +
+        "    <arg><object expr='#{joesmoe.handshakes.force}'/></arg>" +
+        "    <arg><object expr='#{joesmoe.handshakes.duration}'/></arg>" +
+        "    <transition to='wait' />" +
+        "  </java>" +
+        "  <state name='wait'/>" +
+        "</process>"
+    );
+    
+    Map<String, Object> variables = new HashMap<String, Object>();
+    variables.put("hand", new Hand());
+    variables.put("joesmoe", new JoeSmoe());
+    String pid = executionService
+        .startProcessInstanceByKey("JavaExpr40", variables)
+        .getId();
+
+    String answer = (String) executionService.getVariable(pid, "answer");
+    assertEquals("Nice to meet you.  Wow, what a grip!", answer);
+  }
+}


Property changes on: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/java/JavaActivity40Test.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/java/JoeSmoe.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/java/JoeSmoe.java	                        (rev 0)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/java/JoeSmoe.java	2009-10-06 15:38:04 UTC (rev 5706)
@@ -0,0 +1,42 @@
+/*
+ * 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.java;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * @author Tom Baeyens
+ */
+public class JoeSmoe implements Serializable {
+
+  private static final long serialVersionUID = 1L;
+
+  public Map<String, Integer> getHandshakes() {
+    Map<String, Integer> handshakes = new HashMap<String, Integer>();
+    handshakes.put("force", 5);
+    handshakes.put("duration", 12);
+    return handshakes;
+  }
+}


Property changes on: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/java/JoeSmoe.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Modified: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/eventlistener/EventListenerTest.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/eventlistener/EventListenerTest.java	2009-10-06 06:19:58 UTC (rev 5705)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/eventlistener/EventListenerTest.java	2009-10-06 15:38:04 UTC (rev 5706)
@@ -242,4 +242,31 @@
     
     assertEquals(expectedOrder, executionService.getVariable(processInstanceId, "order"));
   }
+//
+//  public void testProcessStartListenerExpr() {
+//    deployJpdlXmlString(
+//      "<process name='Insurance claim' key='ICL'>" +
+//      "  <on event='start'>" +
+//      "    <event-listener expr='#{processstartlistener}' />" +
+//      "  </on>" +
+//      "  <start>" +
+//      "    <transition to='a' />" +
+//      "  </start>" +
+//      "  <state name='a' />" +
+//      "</process>"
+//    );
+//    
+//    Map<String, Object> variables = new HashMap<String, Object>();
+//    variables.put("processstartlistener", new ProcessStartListener());
+//    String processInstanceId = executionService.startProcessInstanceByKey("ICL", variables).getId();
+//
+//    assertEquals("true", executionService.getVariable(processInstanceId, "isInvoked"));
+//    
+//    executionService.setVariable(processInstanceId, "isInvoked", "false");
+//    
+//    executionService.signalExecutionById(processInstanceId);
+//    
+//    assertEquals("false", executionService.getVariable(processInstanceId, "isInvoked"));
+//  }
+//
 }

Modified: jbpm4/trunk/modules/test-db/src/test/resources/logging.properties
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/resources/logging.properties	2009-10-06 06:19:58 UTC (rev 5705)
+++ jbpm4/trunk/modules/test-db/src/test/resources/logging.properties	2009-10-06 15:38:04 UTC (rev 5706)
@@ -12,7 +12,7 @@
 org.hibernate.level=INFO
 org.hibernate.cfg.SettingsFactory.level=SEVERE
 org.hibernate.cfg.HbmBinder.level=SEVERE
-org.hibernate.SQL.level=FINEST
-org.hibernate.type.level=FINEST
+# org.hibernate.SQL.level=FINEST
+# org.hibernate.type.level=FINEST
 # org.hibernate.tool.hbm2ddl.SchemaExport.level=FINEST
 # org.hibernate.transaction.level=FINEST
\ No newline at end of file

Modified: jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch06-Jpdl.xml
===================================================================
--- jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch06-Jpdl.xml	2009-10-06 06:19:58 UTC (rev 5705)
+++ jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch06-Jpdl.xml	2009-10-06 15:38:04 UTC (rev 5706)
@@ -1829,8 +1829,9 @@
               <entry>classname</entry>
               <entry></entry>
               <entry>either 'class' or 'expr' has to be specified</entry>
-              <entry>The fully qualified classname.  The class will be instantiated 
-              and the object will be disposed after this method invocation.
+              <entry>The fully qualified classname.  See <xref linkend="usercodeclassloading"/> 
+              for classloading information.  The user code object will be lazy initialized 
+              and cached as part of the process definition. 
               </entry>
             </row>
             <row>
@@ -2890,106 +2891,193 @@
   <section id="usercode">
     <title>User code</title>
     <para>Various elements in the jPDL process language refer to a an 
-    object on which an interface method will be invoked.
+    object on which an interface method will be invoked.  This section 
+    describes the common attributes and elements for the instantiation and 
+    configuration of such user code objects. 
     </para>  
     <itemizedlist>
+      <listitem><literal>custom</literal></listitem>
       <listitem><literal>event-listener</literal></listitem>
-      <listitem><literal>custom</literal></listitem>
-      <listitem><literal>java</literal></listitem>
       <listitem><literal>assignment-handler</literal> in task</listitem>
       <listitem><literal>handler</literal> in decision</listitem>
+      <listitem><literal>condition</literal> in transition</listitem>
     </itemizedlist>
-    <para>For all objects that are referenced by a class name, will be  
-    instantiated during parsing time.  Which implies that the objects aren't
-    allowed to store non-stateless data (ie which can change).
-    This is typically OK since those objects are in practice almost always immutable. 
-    If you do need to use 'dynamic' data in your user code, you can always 
-    fall back to process variables (or Environment.get(xxx) calls).
-    </para>
-    <para>Objects that are referenced by an expression are calculated 
-    dynamically.
-    </para>
-    <table><title>attributes:</title>
-      <tgroup cols="5" rowsep="1" colsep="1">
-        <thead>
-          <row>
-            <entry>Attribute</entry>
-            <entry>Type</entry>
-            <entry>Default</entry>
-            <entry>Required?</entry>
-            <entry>Description</entry>
-          </row>
-        </thead>
-        <tbody>
-          <row>
-            <entry><literal>class</literal></entry>
-            <entry>classname</entry>
-            <entry></entry>
-            <entry>one of {class|expr} is required</entry>
-            <entry>The fully qualified classname.</entry>
-          </row>
-          <row>
-            <entry><literal>expr</literal></entry>
-            <entry>expression</entry>
-            <entry></entry>
-            <entry>one of {class|expr} is required</entry>
-            <entry>Expression for which the resulting value will be taken as the target object.</entry>
-          </row>
-        </tbody>
-      </tgroup>
-    </table>
-    <table><title>sub elements:</title>
-      <tgroup cols="3" rowsep="1" colsep="1">
-        <thead>
-          <row>
-            <entry>Element</entry>
-            <entry>Multiplicity</entry>
-            <entry>Description</entry>
-          </row>
-        </thead>
-        <tbody>
-          <row>
-            <entry><literal>field</literal></entry>
-            <entry>0..*</entry>
-            <entry>describes a configuration value to be injected directly in 
-            a memberfield before this user class is used.</entry>
-          </row>
-          <row>
-            <entry><literal>property</literal></entry>
-            <entry>0..*</entry>
-            <entry>describes a configuration value to injected through a setter 
-            method before this user object is used.</entry>
-          </row>
-        </tbody>
-      </tgroup>
-    </table>
-    <table><title><literal>field</literal> attributes:</title>
-      <tgroup cols="5" rowsep="1" colsep="1">
-        <thead>
-          <row>
-            <entry>Attribute</entry>
-            <entry>Type</entry>
-            <entry>Default</entry>
-            <entry>Required?</entry>
-            <entry>Description</entry>
-          </row>
-        </thead>
-        <tbody>
-          <row>
-            <entry><literal>name</literal></entry>
-            <entry>string</entry>
-            <entry></entry>
-            <entry><emphasis role="bold">required</emphasis></entry>
-            <entry>the name of the field</entry>
-          </row>
-        </tbody>
-      </tgroup>
-    </table>
-    <para>Inside <literal>field</literal> or <literal>property</literal> injections,
-    a lot of different value types can be specified, like <literal>string</literal>,
-    <literal>object</literal>, <literal>map</literal>, <literal>list</literal>
-    <literal>ref</literal> and so on. See jpdl schema docs for more options
-    </para>
+    <section id="usercodeconfiguration">
+      <title>User code configuration</title>
+      <table><title>attributes:</title>
+        <tgroup cols="5" rowsep="1" colsep="1">
+          <thead>
+            <row>
+              <entry>Attribute</entry>
+              <entry>Type</entry>
+              <entry>Default</entry>
+              <entry>Required?</entry>
+              <entry>Description</entry>
+            </row>
+          </thead>
+          <tbody>
+            <row>
+              <entry><literal>class</literal></entry>
+              <entry>classname</entry>
+              <entry></entry>
+              <entry>one of {class|expr} is required</entry>
+              <entry>The fully qualified classname.  Instantiation is done only once and 
+              the user object is cached as part of the process definition.
+              </entry>
+            </row>
+            <row>
+              <entry><literal>expr</literal></entry>
+              <entry>expression</entry>
+              <entry></entry>
+              <entry>one of {class|expr} is required</entry>
+              <entry>Expression for which the resulting value will be taken as the target object.</entry>
+            </row>
+          </tbody>
+        </tgroup>
+      </table>
+      <table><title>user code configuration elements:</title>
+        <tgroup cols="3" rowsep="1" colsep="1">
+          <thead>
+            <row>
+              <entry>Element</entry>
+              <entry>Multiplicity</entry>
+              <entry>Description</entry>
+            </row>
+          </thead>
+          <tbody>
+            <row>
+              <entry><literal>field</literal></entry>
+              <entry>0..*</entry>
+              <entry>describes a configuration value to be injected directly in 
+              a memberfield before this user class is used.</entry>
+            </row>
+            <row>
+              <entry><literal>property</literal></entry>
+              <entry>0..*</entry>
+              <entry>describes a configuration value to injected through a setter 
+              method before this user object is used.</entry>
+            </row>
+          </tbody>
+        </tgroup>
+      </table>
+      <table><title><literal>field</literal> and <literal>property</literal> attributes:</title>
+        <tgroup cols="5" rowsep="1" colsep="1">
+          <thead>
+            <row>
+              <entry>Attribute</entry>
+              <entry>Type</entry>
+              <entry>Default</entry>
+              <entry>Required?</entry>
+              <entry>Description</entry>
+            </row>
+          </thead>
+          <tbody>
+            <row>
+              <entry><literal>name</literal></entry>
+              <entry>string</entry>
+              <entry></entry>
+              <entry><emphasis role="bold">required</emphasis></entry>
+              <entry>the name of the field or property.</entry>
+            </row>
+          </tbody>
+        </tgroup>
+      </table>
+      <table><title>field and property contained element:</title>
+        <para><literal>field</literal> and <literal>property</literal> elements
+        have exactly one child element that represents the value that will be 
+        injected.
+        </para>
+        <tgroup cols="3" rowsep="1" colsep="1">
+          <thead>
+            <row>
+              <entry>Element</entry>
+              <entry>Multiplicity</entry>
+              <entry>Description</entry>
+            </row>
+          </thead>
+          <tbody>
+            <row>
+              <entry><literal>string</literal></entry>
+              <entry>0..1</entry>
+              <entry>a java.lang.String</entry>
+            </row>
+            <row>
+              <entry><literal>int</literal></entry>
+              <entry>0..1</entry>
+              <entry>a java.lang.Integer</entry>
+            </row>
+            <row>
+              <entry><literal>long</literal></entry>
+              <entry>0..1</entry>
+              <entry>a java.lang.Long</entry>
+            </row>
+            <row>
+              <entry><literal>float</literal></entry>
+              <entry>0..1</entry>
+              <entry>a java.lang.Float</entry>
+            </row>
+            <row>
+              <entry><literal>double</literal></entry>
+              <entry>0..1</entry>
+              <entry>a java.lang.Double</entry>
+            </row>
+            <row>
+              <entry><literal>true</literal></entry>
+              <entry>0..1</entry>
+              <entry>Boolean.TRUE</entry>
+            </row>
+            <row>
+              <entry><literal>false</literal></entry>
+              <entry>0..1</entry>
+              <entry>Boolean.FALSE</entry>
+            </row>
+            <row>
+              <entry><literal>object</literal></entry>
+              <entry>0..1</entry>
+              <entry>a object that will be instantiated with reflection</entry>
+            </row>
+          </tbody>
+        </tgroup>
+      </table>
+      <table><title>Attribute for basic type <literal>string</literal>, <literal>int</literal>, <literal>long</literal>, <literal>float</literal>and <literal>double</literal>:</title>
+        <tgroup cols="5" rowsep="1" colsep="1">
+          <thead>
+            <row>
+              <entry>Attribute</entry>
+              <entry>Type</entry>
+              <entry>Default</entry>
+              <entry>Required?</entry>
+              <entry>Description</entry>
+            </row>
+          </thead>
+          <tbody>
+            <row>
+              <entry><literal>value</literal></entry>
+              <entry>text</entry>
+              <entry></entry>
+              <entry><emphasis role="bold">required</emphasis></entry>
+              <entry>text value that will be parsed to the respective type</entry>
+            </row>
+          </tbody>
+        </tgroup>
+      </table>
+    </section>
+    <section id="usercodeclassloading">
+      <title>User code classloading</title>
+      <para>Process definitions are cached.  By default, all user code objects are
+      cached as part of those process definitions.  
+        
+      For all objects that are referenced by a class name, will be  
+      instantiated during parsing time.  Which implies that the objects aren't
+      allowed to store non-stateless data (ie which can change).
+      This is typically OK since those objects are in practice almost always immutable. 
+      If you do need to use 'dynamic' data in your user code, you can always 
+      fall back to process variables (or Environment.get(xxx) calls).
+      </para>
+      <para>Objects that are referenced by an expression are calculated 
+      dynamically.
+      </para>
+    </section>
   </section>
 
 </chapter>



More information about the jbpm-commits mailing list