[jbpm-commits] JBoss JBPM SVN: r6274 - in jbpm3/branches/jbpm-3.2-soa/modules: core/src/main/java/org/jbpm/calendar and 27 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Fri Apr 23 03:13:54 EDT 2010


Author: alex.guizar at jboss.com
Date: 2010-04-23 03:13:49 -0400 (Fri, 23 Apr 2010)
New Revision: 6274

Added:
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/jbpm2852/
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/jbpm2852/JBPM2852Test.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/resources/org/jbpm/jbpm2852/
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/resources/org/jbpm/jbpm2852/gpd.xml
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/resources/org/jbpm/jbpm2852/jbpm.cfg.xml
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/resources/org/jbpm/jbpm2852/mail.templates.xml
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/resources/org/jbpm/jbpm2852/processdefinition.xml
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/resources/org/jbpm/jpdl/xml/.gpd.testSimpleSchemaReference.xml
   jbpm3/branches/jbpm-3.2-soa/modules/examples/src/test/resources/mail/gpd.xml
   jbpm3/branches/jbpm-3.2-soa/modules/examples/src/test/resources/mail/jbpm.cfg.xml
   jbpm3/branches/jbpm-3.2-soa/modules/examples/src/test/resources/mail/processdefinition.xml
   jbpm3/branches/jbpm-3.2-soa/modules/examples/src/test/resources/mail/processimage.jpg
Removed:
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/context/exe/CustomSessionFactoryFactory.java
   jbpm3/branches/jbpm-3.2-soa/modules/examples/src/test/resources/mail/mail.properties
Modified:
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/JbpmConfiguration.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/calendar/BusinessCalendar.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/BeanInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/CharacterInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ConstructorInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/DoubleInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/FieldInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/FloatInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/IntegerInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/JbpmContextInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/JbpmTypeObjectInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/LongInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ObjectFactoryImpl.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ObjectFactoryParser.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/PropertyInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/RefInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/context/exe/Converter.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/context/exe/JbpmType.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/db/hibernate/Converters.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/file/def/FileDefinition.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/action/ActionTypes.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/action/MailAction.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/ExceptionHandler.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/ProcessDefinition.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/node/MailNode.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/node/NodeTypes.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/instantiation/FieldInstantiator.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/jpdl/par/ProcessArchive.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/jpdl/xml/JpdlParser.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/jpdl/xml/JpdlXmlReader.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/mail/Mail.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/security/authentication/SubjectAuthenticationService.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/util/ClassLoaderUtil.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/util/XmlUtil.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/resources/jbpm.cfg.xml
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/resources/jbpm.mail.templates.xml
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/resources/org/jbpm/default.jbpm.cfg.xml
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/resources/org/jbpm/jpdl/xml/jpdl-3.2.xsd
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/SerializabilityTest.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/jbpm1707/JBPM1707Test.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/mail/MailTest.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/mail/TaskMailTest.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/resources/org/jbpm/mail/test.mail.properties
   jbpm3/branches/jbpm-3.2-soa/modules/examples/src/test/java/org/jbpm/examples/mail/MailTest.java
Log:
JBPM-2852: support cc recipients in mail node, action and template
make static caches aware of the cached resource (e.g. business calendar)

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/JbpmConfiguration.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/JbpmConfiguration.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/JbpmConfiguration.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -237,6 +237,7 @@
 public class JbpmConfiguration implements Serializable {
 
   private static final long serialVersionUID = 1L;
+  private static final String DEFAULT_RESOURCE = "jbpm.cfg.xml";
 
   private static ObjectFactory defaultObjectFactory;
   private static final Map instances = new HashMap();
@@ -276,9 +277,7 @@
   }
 
   public static JbpmConfiguration getInstance(String resource) {
-    if (resource == null) {
-      resource = "jbpm.cfg.xml";
-    }
+    if (resource == null) resource = DEFAULT_RESOURCE;
 
     JbpmConfiguration instance;
     synchronized (instances) {
@@ -298,7 +297,7 @@
            * otherwise, users who want to load custom stuff will not receive any feedback when
            * their resource cannot be found
            */
-          if (jbpmCfgXmlStream == null && !"jbpm.cfg.xml".equals(resource)) {
+          if (jbpmCfgXmlStream == null && !DEFAULT_RESOURCE.equals(resource)) {
             log.warn("configuration resource not found: " + resource);
           }
           ObjectFactory objectFactory = parseObjectFactory(jbpmCfgXmlStream);
@@ -312,7 +311,7 @@
   }
 
   public static boolean hasInstance(String resource) {
-    return instances.containsKey(resource != null ? resource : "jbpm.cfg.xml");
+    return instances.containsKey(resource != null ? resource : DEFAULT_RESOURCE);
   }
 
   protected static ObjectFactory parseObjectFactory(InputStream inputStream) {
@@ -389,10 +388,6 @@
     return jbpmContext;
   }
 
-  private void ensureOpen() {
-    if (isClosed) throw new JbpmException("jbpm configuration is closed");
-  }
-
   public ServiceFactory getServiceFactory(String serviceName) {
     return getServiceFactory(serviceName, JbpmContext.DEFAULT_JBPM_CONTEXT_NAME);
   }
@@ -407,6 +402,10 @@
     }
   }
 
+  private DbPersistenceServiceFactory getPersistenceServiceFactory(String jbpmContextName) {
+    return (DbPersistenceServiceFactory) getServiceFactory(Services.SERVICENAME_PERSISTENCE, jbpmContextName);
+  }
+
   public static ClassLoader getProcessClassLoader(ProcessDefinition processDefinition) {
     ProcessClassLoaderFactory factory;
     if (Configs.hasObject("process.class.loader.factory")) {
@@ -492,8 +491,8 @@
     getPersistenceServiceFactory(jbpmContextName).dropSchema();
   }
 
-  private DbPersistenceServiceFactory getPersistenceServiceFactory(String jbpmContextName) {
-    return (DbPersistenceServiceFactory) getServiceFactory(Services.SERVICENAME_PERSISTENCE, jbpmContextName);
+  private void ensureOpen() {
+    if (isClosed) throw new JbpmException(this + " is closed");
   }
 
   public boolean isClosed() {
@@ -602,12 +601,8 @@
   public JbpmContext getCurrentJbpmContext() {
     ensureOpen();
 
-    JbpmContext currentJbpmContext = null;
     List stack = getJbpmContextStack();
-    if (!stack.isEmpty()) {
-      currentJbpmContext = (JbpmContext) stack.get(stack.size() - 1);
-    }
-    return currentJbpmContext;
+    return stack.isEmpty() ? null : (JbpmContext) stack.get(stack.size() - 1);
   }
 
   private List getJbpmContextStack() {
@@ -656,5 +651,5 @@
         : '@' + Integer.toHexString(hashCode()));
   }
 
-  private static Log log = LogFactory.getLog(JbpmConfiguration.class);
+  private static final Log log = LogFactory.getLog(JbpmConfiguration.class);
 }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/calendar/BusinessCalendar.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/calendar/BusinessCalendar.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/calendar/BusinessCalendar.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -25,8 +25,10 @@
 import java.util.Calendar;
 import java.util.Date;
 import java.util.GregorianCalendar;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Properties;
 
 import org.jbpm.JbpmConfiguration;
@@ -39,17 +41,22 @@
 public class BusinessCalendar implements Serializable {
 
   private static final long serialVersionUID = 1L;
-  private static Properties businessCalendarProperties;
 
   private Day[] weekDays;
   private List holidays;
 
-  public static synchronized Properties getBusinessCalendarProperties() {
-    if (businessCalendarProperties == null) {
-      String resource = JbpmConfiguration.Configs.getString("resource.business.calendar");
-      businessCalendarProperties = ClassLoaderUtil.getProperties(resource);
+  private static final Map propertiesByResource = new HashMap();
+
+  public static Properties getBusinessCalendarProperties() {
+    String resource = JbpmConfiguration.Configs.getString("resource.business.calendar");
+    synchronized (propertiesByResource) {
+      Properties properties = (Properties) propertiesByResource.get(resource);
+      if (properties == null) {
+        properties = ClassLoaderUtil.getProperties(resource);
+        propertiesByResource.put(resource, properties);
+      }
+      return properties;
     }
-    return businessCalendarProperties;
   }
 
   public BusinessCalendar() {

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/BeanInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/BeanInfo.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/BeanInfo.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -34,9 +34,9 @@
 
   private static final long serialVersionUID = 1L;
 
-  String className = null;
-  ConstructorInfo constructorInfo = null;
-  PropertyInfo[] propertyInfos = null;
+  private String className;
+  private ConstructorInfo constructorInfo;
+  private PropertyInfo[] propertyInfos;
 
   public BeanInfo() {
   }
@@ -47,29 +47,27 @@
     // parse constructor or factory
     Element constructorElement = XmlUtil.element(beanElement, "constructor");
     if (constructorElement != null) {
+      if (beanElement.hasAttribute("class") && !constructorElement.hasAttribute("class")) {
+        constructorElement.setAttribute("class", beanElement.getAttribute("class"));
+      }
       constructorInfo = new ConstructorInfo(constructorElement, objectFactoryParser);
-      constructorInfo.beanInfo = this;
     }
-
-    if (beanElement.hasAttribute("class")) {
+    else if (beanElement.hasAttribute("class")) {
       className = beanElement.getAttribute("class");
     }
-    else if ((constructorInfo.factoryRefName == null) && (constructorInfo.factoryClassName == null)) {
-      throw new JbpmException("bean element must have a class attribute: "
-          + XmlUtil.toString(beanElement));
+    else {
+      throw new JbpmException("missing class attribute or constructor subelement in bean");
     }
 
     // parse fields
     List propertyInfoList = new ArrayList();
-    Iterator iter = XmlUtil.elementIterator(beanElement, "field");
-    while (iter.hasNext()) {
+    for (Iterator iter = XmlUtil.elementIterator(beanElement, "field"); iter.hasNext();) {
       Element fieldElement = (Element) iter.next();
       propertyInfoList.add(new FieldInfo(fieldElement, objectFactoryParser));
     }
 
     // parse properties
-    iter = XmlUtil.elementIterator(beanElement, "property");
-    while (iter.hasNext()) {
+    for (Iterator iter = XmlUtil.elementIterator(beanElement, "property"); iter.hasNext();) {
       Element propertyElement = (Element) iter.next();
       propertyInfoList.add(new PropertyInfo(propertyElement, objectFactoryParser));
     }
@@ -78,30 +76,36 @@
   }
 
   public Object createObject(ObjectFactoryImpl objectFactory) {
-    Object object = null;
+    Object object;
 
     if (constructorInfo == null) {
-      if (className == null)
-        throw new JbpmException("bean '"
-            + getName()
-            + "' doesn't have a class or constructor specified");
+      if (className == null) {
+        throw new JbpmException("bean '" + getName()
+          + "' does not specify a class or constructor");
+      }
       try {
         Class clazz = objectFactory.classForName(className);
-        object = clazz.newInstance();
+        try {
+          object = clazz.newInstance();
+        }
+        catch (InstantiationException e) {
+          throw new JbpmException("failed to instantiate " + clazz, e);
+        }
+        catch (IllegalAccessException e) {
+          throw new JbpmException(getClass() + " has no access to " + clazz, e);
+        }
       }
-      catch (Exception e) {
-        throw new JbpmException("couldn't instantiate bean '"
-            + getName()
-            + "' of type '"
-            + className
-            + "'", e);
+      catch (ClassNotFoundException e) {
+        throw new JbpmException("bean '" + getName() + "' specifies a missing class", e);
       }
     }
     else {
       object = constructorInfo.createObject(objectFactory);
     }
 
-    if (className == null) className = object.getClass().getName();
+    if (className == null) {
+      className = object.getClass().getName();
+    }
 
     if (propertyInfos != null) {
       for (int i = 0; i < propertyInfos.length; i++) {

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/CharacterInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/CharacterInfo.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/CharacterInfo.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -21,33 +21,27 @@
  */
 package org.jbpm.configuration;
 
-import org.jbpm.JbpmException;
-import org.jbpm.util.XmlUtil;
 import org.w3c.dom.Element;
 
+import org.jbpm.JbpmException;
+
 public class CharacterInfo extends AbstractObjectInfo {
 
   private static final long serialVersionUID = 1L;
 
-  Character c = null;
-  
+  private Character value;
+
   public CharacterInfo(Element charElement, ObjectFactoryParser configParser) {
     super(charElement, configParser);
-    
-    String s = getValueString(charElement);
-    if (s!=null) {
-      s = s.trim();
-      if (s.length()==1) {
-        c = new Character(s.charAt(0)); 
-      }
+    String valueString = getValueString(charElement);
+    if (valueString == null) {
+      throw new JbpmException("missing character value");
     }
-    if (c==null) {
-      throw new JbpmException("improper character format '"+XmlUtil.toString(charElement));
-    }
+    value = new Character(valueString.charAt(0));
   }
 
   public Object createObject(ObjectFactoryImpl objectFactory) {
-    return c;
+    return value;
   }
 
 }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ConstructorInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ConstructorInfo.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ConstructorInfo.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -23,12 +23,14 @@
 
 import java.io.Serializable;
 import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.List;
 
 import org.w3c.dom.Element;
 
 import org.jbpm.JbpmException;
+import org.jbpm.util.ArrayUtil;
 import org.jbpm.util.ClassLoaderUtil;
 import org.jbpm.util.XmlUtil;
 
@@ -36,123 +38,133 @@
 
   private static final long serialVersionUID = 1L;
 
-  BeanInfo beanInfo = null;
-  String className = null;
-  String factoryRefName = null;
-  String factoryClassName = null;
-  String factoryMethodName = null;
-  String[] parameterClassNames = null;
-  ObjectInfo[] parameterInfos = null;
+  private String className;
+  private String factoryRefName;
+  private String factoryClassName;
+  private String factoryMethodName;
+  private final String[] parameterClassNames;
+  private final ObjectInfo[] parameterInfos;
 
   public ConstructorInfo(Element constructorElement, ObjectFactoryParser configParser) {
-    // beanInfo is set by the beanInfo itself
-
-    // className
-    if (constructorElement.hasAttribute("class")) {
-      className = constructorElement.getAttribute("class");
-    }
-
-    // factoryInfo
+    // factory
     if (constructorElement.hasAttribute("factory")) {
       factoryRefName = constructorElement.getAttribute("factory");
       if (!constructorElement.hasAttribute("method")) {
-        throw new JbpmException(
-            "factory element in constructor requires method attribute in constructor: "
-                + XmlUtil.toString(constructorElement));
+        throw new JbpmException("missing method attribute in constructor");
       }
       factoryMethodName = constructorElement.getAttribute("method");
-
     }
+    // factory-class
     else if (constructorElement.hasAttribute("factory-class")) {
       factoryClassName = constructorElement.getAttribute("factory-class");
       if (!constructorElement.hasAttribute("method")) {
-        throw new JbpmException(
-            "factory-class element in constructor requires method attribute in constructor: "
-                + XmlUtil.toString(constructorElement));
+        throw new JbpmException("missing method attribute in constructor");
       }
       factoryMethodName = constructorElement.getAttribute("method");
-
     }
     else {
       if (constructorElement.hasAttribute("method")) {
-        throw new JbpmException(
-            "'method' element in constructor requires 'factory' of 'factory-class' attribute in constructor: "
-                + XmlUtil.toString(constructorElement));
+        throw new JbpmException("missing factory or factory-class attribute in constructor");
       }
+      // class
+      if (constructorElement.hasAttribute("class")) {
+        className = constructorElement.getAttribute("class");
+      }
+      else {
+        throw new JbpmException("missing class, factory or factory-class attribute in constructor");
+      }
     }
 
-    // parameterTypesNames and parameterInfos 
+    // parameterTypesNames and parameterInfos
     List parameterElements = XmlUtil.elements(constructorElement, "parameter");
     parameterClassNames = new String[parameterElements.size()];
     parameterInfos = new ObjectInfo[parameterElements.size()];
     for (int i = 0; i < parameterElements.size(); i++) {
       Element parameterElement = (Element) parameterElements.get(i);
       if (!parameterElement.hasAttribute("class")) {
-        throw new JbpmException("parameter element must have a class attribute: "
-            + XmlUtil.toString(parameterElement));
+        throw new JbpmException("missing class attribute in constructor parameter");
       }
       parameterClassNames[i] = parameterElement.getAttribute("class");
+
       Element parameterInfoElement = XmlUtil.element(parameterElement);
       if (parameterInfoElement == null) {
-        throw new JbpmException("parameter element must have exactly 1 child element: "
-            + XmlUtil.toString(parameterElement));
+        throw new JbpmException("missing subelement in constructor parameter");
       }
       parameterInfos[i] = configParser.parse(parameterInfoElement);
     }
   }
 
   public Object createObject(ObjectFactoryImpl objectFactory) {
-    Object newObject = null;
-
     Object[] args = getArgs(objectFactory);
     Class[] parameterTypes = getParameterTypes(objectFactory);
 
-    if ((factoryRefName != null) || (factoryClassName != null)) {
-      Object factory = null;
-      Class factoryClass = null;
+    if (factoryRefName != null || factoryClassName != null) {
+      Object factory;
+      Class factoryClass;
 
       if (factoryRefName != null) {
         factory = objectFactory.getObject(factoryRefName);
         factoryClass = factory.getClass();
       }
       else {
-        factoryClass = ClassLoaderUtil.classForName(factoryClassName);
+        factory = null;
+        try {
+          factoryClass = ClassLoaderUtil.classForName(factoryClassName);
+        }
+        catch (ClassNotFoundException e) {
+          throw new JbpmException("factory class not found: " + factoryClassName, e);
+        }
       }
 
+      Method factoryMethod = findMethod(factoryClass, parameterTypes);
       try {
-        Method factoryMethod = findMethod(factoryClass, parameterTypes);
-        newObject = factoryMethod.invoke(factory, args);
+        return factoryMethod.invoke(factory, args);
       }
-      catch (Exception e) {
-        throw new JbpmException("couldn't create new bean with factory method '"
-            + factoryClass.getName()
-            + "."
-            + factoryMethodName, e);
+      catch (IllegalAccessException e) {
+        throw new JbpmException(getClass() + " has no access to " + factoryMethod, e);
       }
-
+      catch (InvocationTargetException e) {
+        throw new JbpmException(factoryMethod + " threw exception", e.getCause());
+      }
     }
     else {
-      String className = (this.className != null ? this.className : beanInfo.getClassName());
-      Class clazz = objectFactory.classForName(className);
-
       try {
+        Class clazz = objectFactory.classForName(className);
         Constructor constructor = clazz.getDeclaredConstructor(parameterTypes);
-        newObject = constructor.newInstance(args);
+        try {
+          return constructor.newInstance(args);
+        }
+        catch (InstantiationException e) {
+          throw new JbpmException("failed to instantiate " + clazz, e);
+        }
+        catch (IllegalAccessException e) {
+          throw new JbpmException(getClass() + " has no access to " + constructor, e);
+        }
+        catch (InvocationTargetException e) {
+          throw new JbpmException(constructor + " threw exception", e.getCause());
+        }
       }
-      catch (Exception e) {
-        throw new JbpmException("couldn't instantiate new '" + className + "' with constructor", e);
+      catch (ClassNotFoundException e) {
+        throw new JbpmException("class not found: " + className, e);
       }
-
+      catch (NoSuchMethodException e) {
+        throw new JbpmException("constructor not found: " + className
+          + ArrayUtil.toString(parameterTypes), e);
+      }
     }
-
-    return newObject;
   }
 
   protected Class[] getParameterTypes(ObjectFactoryImpl objectFactory) {
-    int nbrOfParameters = (parameterClassNames != null ? parameterClassNames.length : 0);
+    int nbrOfParameters = parameterClassNames != null ? parameterClassNames.length : 0;
     Class[] parameterTypes = new Class[nbrOfParameters];
     for (int i = 0; i < nbrOfParameters; i++) {
-      parameterTypes[i] = objectFactory.classForName(parameterClassNames[i]);
+      String parameterClassName = parameterClassNames[i];
+      try {
+        parameterTypes[i] = objectFactory.classForName(parameterClassName);
+      }
+      catch (ClassNotFoundException e) {
+        throw new JbpmException("class not found: " + parameterClassName, e);
+      }
     }
     return parameterTypes;
   }
@@ -167,26 +179,22 @@
   }
 
   public Method findMethod(Class clazz, Class[] parameterTypes) {
-    Method method = null;
-
-    Class candidateClass = clazz;
-    while ((candidateClass != null) && (method == null)) {
-      try {
-        method = clazz.getDeclaredMethod(factoryMethodName, parameterTypes);
-      }
-      catch (NoSuchMethodException e1) {
-        candidateClass = candidateClass.getSuperclass();
-      }
+    try {
+      // look for public method
+      return clazz.getMethod(factoryMethodName, parameterTypes);
     }
-
-    if (method == null) {
-      throw new JbpmException("couldn't find factory method '"
-          + factoryMethodName
-          + "' in class '"
-          + clazz.getName()
-          + "'");
+    catch (NoSuchMethodException e) {
+      // look for any method up the class hierarchy
+      do {
+        try {
+          return clazz.getDeclaredMethod(factoryMethodName, parameterTypes);
+        }
+        catch (NoSuchMethodException e2) {
+          clazz = clazz.getSuperclass();
+        }
+      } while (clazz != null);
+      // give up
+      throw new JbpmException("no such method: " + factoryMethodName, e);
     }
-
-    return method;
   }
 }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/DoubleInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/DoubleInfo.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/DoubleInfo.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -21,29 +21,21 @@
  */
 package org.jbpm.configuration;
 
-import org.jbpm.JbpmException;
-import org.jbpm.util.XmlUtil;
 import org.w3c.dom.Element;
 
 public class DoubleInfo extends AbstractObjectInfo {
 
   private static final long serialVersionUID = 1L;
 
-  Double d = null;
-  
+  private Double value;
+
   public DoubleInfo(Element doubleElement, ObjectFactoryParser configParser) {
     super(doubleElement, configParser);
-    
-    String contentText = getValueString(doubleElement);
-    try {
-      d = (new Double(contentText));
-    } catch (Exception e) {
-      throw new JbpmException("content of "+XmlUtil.toString(doubleElement)+" could not be parsed as a double", e);
-    }
+    value = new Double(getValueString(doubleElement));
   }
 
   public Object createObject(ObjectFactoryImpl objectFactory) {
-    return d;
+    return value;
   }
 
 }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/FieldInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/FieldInfo.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/FieldInfo.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -23,11 +23,10 @@
 
 import java.lang.reflect.Field;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.jbpm.JbpmException;
 import org.w3c.dom.Element;
 
+import org.jbpm.JbpmException;
+
 public class FieldInfo extends PropertyInfo {
 
   private static final long serialVersionUID = 1L;
@@ -37,40 +36,29 @@
   }
 
   public void injectProperty(Object object, ObjectFactoryImpl objectFactory) {
-
-    Object propertyValue = objectFactory.getObject(propertyValueInfo);
-    Field propertyField = findField(object.getClass());
-    propertyField.setAccessible(true);
+    Field field = findField(object.getClass());
+    field.setAccessible(true);
+    Object value = objectFactory.getObject(getPropertyValueInfo());
     try {
-      propertyField.set(object, propertyValue);
-    } catch (Exception e) {
-      throw new JbpmException("couldn't set field '"+propertyName+"' on class '"+object.getClass()+"' to value '"+propertyValue+"'", e);
+      field.set(object, value);
     }
+    catch (IllegalAccessException e) {
+      throw new JbpmException(getClass() + " has no access to " + field, e);
+    }
   }
 
-  Field findField(Class clazz) {
-    Field field = null;
-    
-    Class candidateClass = clazz;
-    while ( (candidateClass!=null)
-            && (field==null)
-          ) {
+  private Field findField(Class clazz) {
+    String fieldName = getPropertyName();
 
+    for (Class currentClass = clazz; currentClass != Object.class; currentClass = currentClass.getSuperclass()) {
       try {
-        field = candidateClass.getDeclaredField(propertyName);
-      } catch (Exception e) {
-        candidateClass = candidateClass.getSuperclass();
+        return clazz.getDeclaredField(fieldName);
       }
+      catch (NoSuchFieldException e) {
+        clazz = clazz.getSuperclass();
+      }
     }
 
-    if (field==null) {
-      JbpmException e = new JbpmException("couldn't find field '"+propertyName+"' in class '"+clazz.getName()+"'");
-      log.error(e);
-      throw e;
-    }
-    
-    return field;
+    throw new JbpmException("missing field '" + "' in " + clazz);
   }
-
-  private static Log log = LogFactory.getLog(FieldInfo.class);
 }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/FloatInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/FloatInfo.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/FloatInfo.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -21,29 +21,21 @@
  */
 package org.jbpm.configuration;
 
-import org.jbpm.JbpmException;
-import org.jbpm.util.XmlUtil;
 import org.w3c.dom.Element;
 
 public class FloatInfo extends AbstractObjectInfo {
 
   private static final long serialVersionUID = 1L;
-  
-  Float f = null;
 
+  private Float value;
+
   public FloatInfo(Element floatElement, ObjectFactoryParser configParser) {
     super(floatElement, configParser);
-    
-    String contentText = getValueString(floatElement);
-    try {
-      f = (new Float(contentText));
-    } catch (Exception e) {
-      throw new JbpmException("content of "+XmlUtil.toString(floatElement)+" could not be parsed as a float", e);
-    }
+    value = new Float(getValueString(floatElement));
   }
 
   public Object createObject(ObjectFactoryImpl objectFactory) {
-    return f;
+    return value;
   }
 
 }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/IntegerInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/IntegerInfo.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/IntegerInfo.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -21,29 +21,21 @@
  */
 package org.jbpm.configuration;
 
-import org.jbpm.JbpmException;
-import org.jbpm.util.XmlUtil;
 import org.w3c.dom.Element;
 
 public class IntegerInfo extends AbstractObjectInfo {
-  
+
   private static final long serialVersionUID = 1L;
-  
-  Integer i = null;
 
+  private Integer value;
+
   public IntegerInfo(Element integerElement, ObjectFactoryParser configParser) {
     super(integerElement, configParser);
-    
-    String contentText = getValueString(integerElement);
-    try {
-      i = new Integer(contentText);
-    } catch (Exception e) {
-      throw new JbpmException("content of "+XmlUtil.toString(integerElement)+" could not be parsed as a integer", e);
-    }
+    value = new Integer(getValueString(integerElement));
   }
 
   public Object createObject(ObjectFactoryImpl objectFactory) {
-    return i;
+    return value;
   }
 
 }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/JbpmContextInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/JbpmContextInfo.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/JbpmContextInfo.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -46,8 +46,7 @@
   public JbpmContextInfo(Element jbpmContextElement, ObjectFactoryParser objectFactoryParser) {
     super(verifyDefaultName(jbpmContextElement), objectFactoryParser);
     if (jbpmContextElement.hasAttribute("singleton")) {
-      throw new ConfigurationException(
-        "attribute 'singleton' is not allowed in element 'jbpm-context'");
+      throw new ConfigurationException("attribute 'singleton' is not allowed in element 'jbpm-context'");
     }
 
     // parse the services
@@ -56,8 +55,7 @@
     for (Iterator iter = XmlUtil.elementIterator(jbpmContextElement, "service"); iter.hasNext();) {
       Element serviceElement = (Element) iter.next();
       if (!serviceElement.hasAttribute("name")) {
-        throw new ConfigurationException("name is required in service element "
-          + XmlUtil.toString(serviceElement));
+        throw new ConfigurationException("service has no name");
       }
       String serviceName = serviceElement.getAttribute("name");
       serviceNames.add(serviceName);
@@ -66,8 +64,7 @@
       if (factoryElement != null) {
         Element factoryBeanElement = XmlUtil.element(factoryElement);
         if (factoryBeanElement == null) {
-          throw new ConfigurationException(
-            "element 'factory' requires either a bean or ref element");
+          throw new ConfigurationException("element 'factory' requires either a bean or ref element");
         }
         serviceFactoryObjectInfo = objectFactoryParser.parse(factoryBeanElement);
       }
@@ -78,8 +75,7 @@
         serviceFactoryObjectInfo = beanInfo;
       }
       else {
-        throw new ConfigurationException(
-          "element 'service' requires either a factory attribute or a factory element");
+        throw new ConfigurationException("element 'service' requires either a factory attribute or a factory element");
       }
 
       serviceFactoryObjectInfos.put(serviceName, serviceFactoryObjectInfo);
@@ -102,8 +98,7 @@
         else {
           Element saveOperationBeanElement = XmlUtil.element(saveOperationElement);
           if (saveOperationBeanElement == null) {
-            throw new ConfigurationException(
-              "element 'save-operation' requires either a class attribute or an element of type 'bean' or 'ref'");
+            throw new ConfigurationException("element 'save-operation' requires either a class attribute or an element of type 'bean' or 'ref'");
           }
           saveOperationObjectInfos[i] = objectFactoryParser.parse(saveOperationBeanElement);
         }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/JbpmTypeObjectInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/JbpmTypeObjectInfo.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/JbpmTypeObjectInfo.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -37,59 +37,49 @@
 
   private static final long serialVersionUID = 1L;
 
-  ObjectInfo typeMatcherObjectInfo;
-  Converter converter;
-  Class variableInstanceClass;
+  private ObjectInfo typeMatcherObjectInfo;
+  private Converter converter;
+  private Class variableInstanceClass;
 
   public JbpmTypeObjectInfo(Element jbpmTypeElement, ObjectFactoryParser objectFactoryParser) {
     super(jbpmTypeElement, objectFactoryParser);
 
-    try {
-      Element typeMatcherElement = XmlUtil.element(jbpmTypeElement, "matcher");
-      if (typeMatcherElement == null) {
-        throw new ConfigurationException("matcher is a required element in a jbpm-type: "
-          + XmlUtil.toString(jbpmTypeElement));
-      }
-      Element typeMatcherBeanElement = XmlUtil.element(typeMatcherElement);
-      typeMatcherObjectInfo = objectFactoryParser.parse(typeMatcherBeanElement);
+    Element typeMatcherElement = XmlUtil.element(jbpmTypeElement, "matcher");
+    if (typeMatcherElement == null) {
+      throw new ConfigurationException("missing matcher element in jbpm-type");
+    }
+    Element typeMatcherBeanElement = XmlUtil.element(typeMatcherElement);
+    typeMatcherObjectInfo = objectFactoryParser.parse(typeMatcherBeanElement);
 
-      Element converterElement = XmlUtil.element(jbpmTypeElement, "converter");
-      if (converterElement != null) {
-        if (!converterElement.hasAttribute("class")) {
-          throw new ConfigurationException(
-            "class attribute is required in a converter element: "
-              + XmlUtil.toString(jbpmTypeElement));
-        }
-        String converterClassName = converterElement.getAttribute("class");
-        converter = Converters.getConverterByClassName(converterClassName);
+    Element converterElement = XmlUtil.element(jbpmTypeElement, "converter");
+    if (converterElement != null) {
+      if (!converterElement.hasAttribute("class")) {
+        throw new ConfigurationException("missing class attribute in converter");
       }
+      String converterClassName = converterElement.getAttribute("class");
+      converter = Converters.getConverterByClassName(converterClassName);
+    }
 
-      Element variableInstanceElement = XmlUtil.element(jbpmTypeElement, "variable-instance");
-      if (!variableInstanceElement.hasAttribute("class")) {
-        throw new ConfigurationException(
-          "class is a required attribute in element variable-instance: "
-            + XmlUtil.toString(jbpmTypeElement));
-      }
-      String variableInstanceClassName = variableInstanceElement.getAttribute("class");
+    Element variableInstanceElement = XmlUtil.element(jbpmTypeElement, "variable-instance");
+    if (!variableInstanceElement.hasAttribute("class")) {
+      throw new ConfigurationException("missing class attribute in variable-instance");
+    }
+
+    String variableInstanceClassName = variableInstanceElement.getAttribute("class");
+    try {
       variableInstanceClass = ClassLoaderUtil.classForName(variableInstanceClassName);
       if (!VariableInstance.class.isAssignableFrom(variableInstanceClass)) {
-        throw new ConfigurationException("variable instance class '"
-          + variableInstanceClassName + "' is not a VariableInstance");
+        throw new ConfigurationException(variableInstanceClassName
+          + " is not a variable instance");
       }
     }
-    catch (ConfigurationException e) {
-      throw e;
-    }
-    catch (Exception e) {
-      // NOTE that Error's are not caught because that might halt the JVM
-      // and mask the original Error
-      // Probably the user does not need support for this type and does not have a required
-      // library in the path. So let's log and ignore
+    catch (ClassNotFoundException e) {
+      // the library that provides this class might be absent because
+      // the user does need this type; just log and ignore
       if (log.isDebugEnabled()) {
-        log.debug("jbpm variables type " + XmlUtil.toString(jbpmTypeElement)
-          + " could not be instantiated", e);
+        log.debug("variable instance class not found: " + variableInstanceClassName);
       }
-      // make sure this JbpmType is ignored by always returning false in the JbpmTypeMatcher
+      // make sure this type is ignored by always returning false in the JbpmTypeMatcher
       typeMatcherObjectInfo = new ObjectInfo() {
         private static final long serialVersionUID = 1L;
 
@@ -107,7 +97,6 @@
 
         public Object createObject(ObjectFactoryImpl objectFactory) {
           return new JbpmTypeMatcher() {
-
             private static final long serialVersionUID = 1L;
 
             public boolean matches(Object value) {

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/LongInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/LongInfo.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/LongInfo.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -21,29 +21,21 @@
  */
 package org.jbpm.configuration;
 
-import org.jbpm.JbpmException;
-import org.jbpm.util.XmlUtil;
 import org.w3c.dom.Element;
 
 public class LongInfo extends AbstractObjectInfo {
 
   private static final long serialVersionUID = 1L;
-  
-  Long l = null;
 
+  private Long value;
+
   public LongInfo(Element longElement, ObjectFactoryParser configParser) {
     super(longElement, configParser);
-    
-    String contentText = getValueString(longElement);
-    try {
-      l = new Long(contentText);
-    } catch (Exception e) {
-      throw new JbpmException("content of "+XmlUtil.toString(longElement)+" could not be parsed as a long", e);
-    }
+    value = new Long(getValueString(longElement));
   }
 
   public Object createObject(ObjectFactoryImpl objectFactory) {
-    return l;
+    return value;
   }
 
 }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ObjectFactoryImpl.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ObjectFactoryImpl.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ObjectFactoryImpl.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -38,12 +38,12 @@
 
   private static final long serialVersionUID = 1L;
 
-  ClassLoader classLoader;
-  final List objectInfos;
-  final Map namedObjectInfos;
-  final Map singletons = new HashMap();
-  final Map objects = new HashMap();
-  final Collection objectsUnderConstruction = new HashSet();
+  private final List objectInfos;
+  private final Map namedObjectInfos;
+  private final Map singletons = new HashMap();
+  private final Map objects = new HashMap();
+  private final Collection objectsUnderConstruction = new HashSet();
+  private ClassLoader classLoader;
 
   public ObjectFactoryImpl() {
     objectInfos = new ArrayList();
@@ -158,19 +158,14 @@
     return object;
   }
 
-  Class classForName(String className) {
+  Class classForName(String className) throws ClassNotFoundException {
     if (classLoader == null) {
       classLoader = ClassLoaderUtil.getClassLoader();
     }
-    try {
-      return Class.forName(className, false, classLoader);
-    }
-    catch (ClassNotFoundException e) {
-      throw new JbpmException("couldn't load class '" + className + "'", e);
-    }
+    return Class.forName(className, false, classLoader);
   }
 
-  Object getRegistryKey(ObjectInfo objectInfo) {
+  private Object getRegistryKey(ObjectInfo objectInfo) {
     Object key = null;
     if (objectInfo.hasName()) {
       key = objectInfo.getName();
@@ -178,12 +173,12 @@
     return key;
   }
 
-  boolean isInRegistry(Object registryKey) {
+  private boolean isInRegistry(Object registryKey) {
     return registryKey != null
       && (objects.containsKey(registryKey) || singletons.containsKey(registryKey));
   }
 
-  void putInRegistry(ObjectInfo objectInfo, Object object, Object registryKey) {
+  private void putInRegistry(ObjectInfo objectInfo, Object object, Object registryKey) {
     if (objectInfo.isSingleton()) {
       singletons.put(registryKey, object);
     }
@@ -192,7 +187,7 @@
     }
   }
 
-  Object findInRegistry(Object registryKey) {
+  private Object findInRegistry(Object registryKey) {
     Object object = null;
     if (registryKey != null) {
       object = objects.get(registryKey);
@@ -201,5 +196,5 @@
     return object;
   }
 
-  private static Log log = LogFactory.getLog(ObjectFactoryImpl.class);
+  private static final Log log = LogFactory.getLog(ObjectFactoryImpl.class);
 }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ObjectFactoryParser.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ObjectFactoryParser.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ObjectFactoryParser.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -24,6 +24,7 @@
 import java.io.InputStream;
 import java.io.Serializable;
 import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -65,7 +66,7 @@
     return defaultMappings;
   }
 
-  private static final Class[] constructorParameterTypes = new Class[] {
+  private static final Class[] constructorParameterTypes = {
     Element.class, ObjectFactoryParser.class
   };
 
@@ -74,7 +75,7 @@
       Constructor constructor = objectInfoClass.getDeclaredConstructor(constructorParameterTypes);
       mappings.put(elementTagName, constructor);
     }
-    catch (Exception e) {
+    catch (NoSuchMethodException e) {
       throw new JbpmException("couldn't add mapping for element '" + elementTagName
         + "': constructor(" + Element.class.getName() + ","
         + ObjectFactoryParser.class.getName() + ") was missing for class '"
@@ -139,22 +140,23 @@
   }
 
   public ObjectInfo parse(Element element) {
-    ObjectInfo objectInfo;
     String tagName = element.getTagName().toLowerCase();
     Constructor constructor = (Constructor) mappings.get(tagName);
     if (constructor == null) {
       throw new JbpmException("no ObjectInfo class specified for element: " + tagName);
     }
     try {
-      objectInfo = (ObjectInfo) constructor.newInstance(new Object[] {
-        element, this
-      });
+      return (ObjectInfo) constructor.newInstance(new Object[] { element, this });
     }
-    catch (Exception e) {
-      throw new JbpmException("couldn't parse '" + tagName + "' into a '"
-        + constructor.getDeclaringClass().getName() + "': " + XmlUtil.toString(element), e);
+    catch (InstantiationException e) {
+      throw new JbpmException("failed to instantiate " + constructor.getDeclaringClass(), e);
     }
-    return objectInfo;
+    catch (IllegalAccessException e) {
+      throw new JbpmException(getClass() + " has no access to " + constructor, e);
+    }
+    catch (InvocationTargetException e) {
+      throw new JbpmException(constructor + " threw exception", e);
+    }
   }
 
   public void addNamedObjectInfo(String name, ObjectInfo objectInfo) {

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/PropertyInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/PropertyInfo.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/PropertyInfo.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -22,6 +22,7 @@
 package org.jbpm.configuration;
 
 import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 
 import org.jbpm.JbpmException;
@@ -31,77 +32,74 @@
 public class PropertyInfo implements Serializable {
 
   private static final long serialVersionUID = 1L;
- 
-  String propertyName = null;
-  String setterMethodName = null;
-  ObjectInfo propertyValueInfo = null;
 
+  private String propertyName;
+  private String setterMethodName;
+  private ObjectInfo propertyValueInfo;
+
   public PropertyInfo(Element propertyElement, ObjectFactoryParser configParser) {
-    // propertyName or setterMethodName
+    // property
     if (propertyElement.hasAttribute("name")) {
-      propertyName = propertyElement.getAttribute("name"); 
-    } else if (propertyElement.hasAttribute("setter")) {
-      setterMethodName = propertyElement.getAttribute("setter"); 
-    } else {
-      throw new JbpmException("property must have a 'name' or 'setter' attribute: "+XmlUtil.toString(propertyElement));
+      propertyName = propertyElement.getAttribute("name");
     }
-    
+    // setter method
+    else if (propertyElement.hasAttribute("setter")) {
+      setterMethodName = propertyElement.getAttribute("setter");
+    }
+    else {
+      throw new JbpmException("missing name or setter attribute in property");
+    }
+
     // propertyValueInfo
     Element propertyValueElement = XmlUtil.element(propertyElement);
     propertyValueInfo = configParser.parse(propertyValueElement);
   }
 
   public void injectProperty(Object object, ObjectFactoryImpl objectFactory) {
-    Object propertyValue = objectFactory.getObject(propertyValueInfo);
     Method setterMethod = findSetter(object.getClass());
     setterMethod.setAccessible(true);
+    Object value = objectFactory.getObject(propertyValueInfo);
     try {
-      setterMethod.invoke(object, new Object[]{propertyValue});
-    } catch (Exception e) {
-      throw new JbpmException("couldn't set property '"+propertyName+"' on class '"+object.getClass()+"' to value '"+propertyValue+"'", e);
+      setterMethod.invoke(object, new Object[] { value });
     }
+    catch (IllegalAccessException e) {
+      throw new JbpmException(getClass() + " has no access to " + setterMethod, e);
+    }
+    catch (InvocationTargetException e) {
+      throw new JbpmException(setterMethod + " threw exception", e.getCause());
+    }
   }
 
   public Method findSetter(Class clazz) {
-    Method method = null;
-
-    if (setterMethodName==null) {
-      if ( (propertyName.startsWith("is"))
-           && (propertyName.length()>3) 
-           && (Character.isUpperCase(propertyName.charAt(2)))
-         ) {
-        setterMethodName = "set"+propertyName.substring(2);
-      } else {
-        setterMethodName = "set"+propertyName.substring(0,1).toUpperCase()+propertyName.substring(1);
+    if (setterMethodName == null) {
+      if (propertyName.startsWith("is") && propertyName.length() > 3
+        && Character.isUpperCase(propertyName.charAt(2))) {
+        setterMethodName = "set" + propertyName.substring(2);
       }
+      else {
+        setterMethodName = "set" + Character.toUpperCase(propertyName.charAt(0))
+          + propertyName.substring(1);
+      }
     }
-    
-    Class candidateClass = clazz;
-    while ( (candidateClass!=null)
-            && (method==null)
-          ) {
 
+    for (Class candidateClass = clazz; candidateClass != Object.class; candidateClass = candidateClass.getSuperclass()) {
       Method[] methods = candidateClass.getDeclaredMethods();
-      if (methods!=null) {
-        for (int i=0; ( (i<methods.length) && (method==null) ); i++) {
-          if ( (methods[i].getName().equals(setterMethodName))
-               && (methods[i].getParameterTypes()!=null)
-               && (methods[i].getParameterTypes().length==1)
-             ) {
-            method = methods[i];
-          }
+      for (int i = 0; i < methods.length; i++) {
+        Method method = methods[i];
+        if (method.getName().equals(setterMethodName) && method.getParameterTypes().length == 1) {
+          return method;
         }
       }
-
-      if (method==null) {
-        candidateClass = candidateClass.getSuperclass();
-      }
     }
 
-    if (method==null) {
-      throw new JbpmException("couldn't find setter '"+setterMethodName+"' in class '"+clazz.getName()+"'");
-    }
-    
-    return method;
+    throw new JbpmException("missing setter '" + setterMethodName + "' in " + clazz);
   }
+
+  String getPropertyName() {
+    return propertyName;
+  }
+
+  ObjectInfo getPropertyValueInfo() {
+    return propertyValueInfo;
+  }
 }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/RefInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/RefInfo.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/RefInfo.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -21,24 +21,23 @@
  */
 package org.jbpm.configuration;
 
-import org.jbpm.JbpmException;
-import org.jbpm.util.XmlUtil;
 import org.w3c.dom.Element;
 
+import org.jbpm.JbpmException;
+
 public class RefInfo extends AbstractObjectInfo {
 
   private static final long serialVersionUID = 1L;
-  
-  String bean = null;
-  
+
+  private String bean;
+
   public RefInfo(Element refElement, ObjectFactoryParser configParser) {
     super(refElement, configParser);
 
-    if (refElement.hasAttribute("bean")) {
-      bean = refElement.getAttribute("bean");
-    } else {
-      throw new JbpmException("element ref must have a 'bean' attribute : "+XmlUtil.toString(refElement));
+    if (!refElement.hasAttribute("bean")) {
+      throw new JbpmException("missing bean attribute in ref");
     }
+    bean = refElement.getAttribute("bean");
   }
 
   public Object createObject(ObjectFactoryImpl objectFactory) {

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/context/exe/Converter.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/context/exe/Converter.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/context/exe/Converter.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -21,7 +21,7 @@
  */
 package org.jbpm.context.exe;
 
-import java.io.*;
+import java.io.Serializable;
 
 /**
  * converts plain objects to objects that are 

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/context/exe/JbpmType.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/context/exe/JbpmType.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/context/exe/JbpmType.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -33,58 +33,56 @@
 import org.jbpm.util.ClassLoaderUtil;
 
 /**
- * specifies for one java-type how jbpm is able to persist objects of that type in the database. 
+ * specifies how jbpm is able to persist objects of a given type in the database.
  */
 public class JbpmType {
-  
-  static Map jbpmTypesCache = new HashMap();
-  
-  JbpmTypeMatcher jbpmTypeMatcher = null;
-  Converter converter = null;
-  Class variableInstanceClass = null;
 
-  public JbpmType(JbpmTypeMatcher jbpmTypeMatcher, Converter converter, Class variableInstanceClass) {
+  private static Map typesByResource = new HashMap();
+
+  private JbpmTypeMatcher jbpmTypeMatcher;
+  private Converter converter;
+  private Class variableInstanceClass;
+
+  public JbpmType(JbpmTypeMatcher jbpmTypeMatcher, Converter converter,
+    Class variableInstanceClass) {
     this.jbpmTypeMatcher = jbpmTypeMatcher;
     this.converter = converter;
     this.variableInstanceClass = variableInstanceClass;
   }
-  
+
   public boolean matches(Object value) {
     return jbpmTypeMatcher.matches(value);
   }
-  
+
   public VariableInstance newVariableInstance() {
-    VariableInstance variableInstance = null;
     try {
-      variableInstance = (VariableInstance) variableInstanceClass.newInstance();
+      VariableInstance variableInstance = (VariableInstance) variableInstanceClass.newInstance();
       variableInstance.converter = converter;
-    } catch (Exception e) {
-      throw new JbpmException("couldn't instantiate variable instance class '"+variableInstanceClass.getName()+"'");
+      return variableInstance;
     }
-    return variableInstance;
+    catch (InstantiationException e) {
+      throw new JbpmException("failed to instantiate " + variableInstanceClass, e);
+    }
+    catch (IllegalAccessException e) {
+      throw new JbpmException(getClass() + " has no access to " + variableInstanceClass, e);
+    }
   }
 
   public static List getJbpmTypes() {
-    List jbpmTypes = null;
-    synchronized(jbpmTypesCache) {
-      ObjectFactory objectFactory = JbpmConfiguration.Configs.getObjectFactory();
-      jbpmTypes = (List) jbpmTypesCache.get(objectFactory);
-      if (jbpmTypes==null) {
-        if (JbpmConfiguration.Configs.hasObject("jbpm.types")) {
-          jbpmTypes = (List) JbpmConfiguration.Configs.getObject("jbpm.types");
-        } else {
-          jbpmTypes = getDefaultJbpmTypes();
-        }
-        jbpmTypesCache.put(objectFactory, jbpmTypes);
-      }
+    if (JbpmConfiguration.Configs.hasObject("jbpm.types")) {
+      return (List) JbpmConfiguration.Configs.getObject("jbpm.types");
     }
-    return jbpmTypes;
-  }
 
-  private static List getDefaultJbpmTypes() {
     String resource = JbpmConfiguration.Configs.getString("resource.varmapping");
-    InputStream is = ClassLoaderUtil.getStream(resource);
-    ObjectFactory objectFactory = ObjectFactoryParser.parseInputStream(is);
-    return (List) objectFactory.createObject("jbpm.types");
+    synchronized (typesByResource) {
+      List types = (List) typesByResource.get(resource);
+      if (types == null) {
+        InputStream resourceStream = ClassLoaderUtil.getStream(resource);
+        ObjectFactory objectFactory = ObjectFactoryParser.parseInputStream(resourceStream);
+        types = (List) objectFactory.createObject("jbpm.types");
+        typesByResource.put(resource, types);
+      }
+      return types;
+    }
   }
 }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/db/hibernate/Converters.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/db/hibernate/Converters.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/db/hibernate/Converters.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -31,7 +31,6 @@
 
 import org.jbpm.JbpmConfiguration;
 import org.jbpm.JbpmException;
-import org.jbpm.configuration.ObjectFactory;
 import org.jbpm.context.exe.Converter;
 import org.jbpm.util.ClassLoaderUtil;
 
@@ -40,12 +39,8 @@
  */
 public class Converters {
 
-  private static final int CONVERTERS_BY_CLASS_NAMES = 0;
-  private static final int CONVERTERS_BY_DATABASE_ID = 1;
-  private static final int CONVERTERS_IDS = 2;
+  private static final Map convertersByResource = new HashMap();
 
-  private static Map converterMapsMap = new HashMap();
-
   private Converters() {
     // prevent instantiation
   }
@@ -53,102 +48,70 @@
   // public methods
 
   public static Converter getConverterByClassName(String className) {
-    Converter converter = (Converter) getConvertersByClassNames().get(className);
-    if (converter == null) {
-      throw new JbpmException("converter '" + className
-        + "' is not declared in jbpm.converter.properties");
+    for (Iterator iter = getConverters().values().iterator(); iter.hasNext();) {
+      Converter converter = (Converter) iter.next();
+      if (className.equals(converter.getClass().getName())) return converter;
     }
-    return converter;
+    throw new JbpmException(className + " is not registered as a converter");
   }
 
-  public static Converter getConverterByDatabaseId(String converterDatabaseId) {
-    return (Converter) getConvertersByDatabaseId().get(converterDatabaseId);
+  public static Converter getConverterByDatabaseId(String converterId) {
+    return (Converter) getConverters().get(converterId);
   }
 
   public static String getConverterId(Converter converter) {
-    return (String) getConvertersIds().get(converter);
+    for (Iterator iter = getConverters().entrySet().iterator(); iter.hasNext();) {
+      Map.Entry entry = (Map.Entry) iter.next();
+      if (converter == entry.getValue()) return (String) entry.getKey();
+    }
+    return null;
   }
 
-  // maps class names to unique converter objects
-  private static Map getConvertersByClassNames() {
-    return getConverterMaps()[CONVERTERS_BY_CLASS_NAMES];
-  }
-
-  // maps converter database-id-strings to unique converter objects
-  private static Map getConvertersByDatabaseId() {
-    return getConverterMaps()[CONVERTERS_BY_DATABASE_ID];
-  }
-
-  // maps unique converter objects to their database-id-string
-  private static Map getConvertersIds() {
-    return getConverterMaps()[CONVERTERS_IDS];
-  }
-
-  private static Map[] getConverterMaps() {
-    Map[] converterMaps = null;
-    synchronized (converterMapsMap) {
-      ObjectFactory objectFactory = JbpmConfiguration.Configs.getObjectFactory();
-      converterMaps = (Map[]) converterMapsMap.get(objectFactory);
-      if (converterMaps == null) {
-        converterMaps = createConverterMaps(objectFactory);
-        converterMapsMap.put(objectFactory, converterMaps);
+  private static Map getConverters() {
+    String resource = JbpmConfiguration.Configs.getString("resource.converter");
+    synchronized (convertersByResource) {
+      Map converters = (Map) convertersByResource.get(resource);
+      if (converters == null) {
+        Properties properties = ClassLoaderUtil.getProperties(resource);
+        converters = createConverters(properties);
+        convertersByResource.put(resource, converters);
       }
+      return converters;
     }
-    return converterMaps;
   }
 
-  private static Map[] createConverterMaps(ObjectFactory objectFactory) {
-    Map[] converterMaps = new Map[3];
-    converterMaps[CONVERTERS_BY_CLASS_NAMES] = new HashMap();
-    converterMaps[CONVERTERS_BY_DATABASE_ID] = new HashMap();
-    converterMaps[CONVERTERS_IDS] = new HashMap();
-
-    Map convertersByClassNames = converterMaps[CONVERTERS_BY_CLASS_NAMES];
-    Map convertersByDatabaseId = converterMaps[CONVERTERS_BY_DATABASE_ID];
-    Map convertersIds = converterMaps[CONVERTERS_IDS];
-
-    Properties converterProperties = null;
-    if (objectFactory.hasObject("resource.converter")) {
-      String resource = (String) objectFactory.createObject("resource.converter");
-      converterProperties = ClassLoaderUtil.getProperties(resource);
-    }
-    else {
-      converterProperties = new Properties();
-    }
-
+  private static Map createConverters(Properties properties) {
+    Map converters = new HashMap();
     boolean debug = log.isDebugEnabled();
-    for (Iterator iter = converterProperties.keySet().iterator(); iter.hasNext();) {
-      String converterId = (String) iter.next();
+    for (Iterator iter = properties.entrySet().iterator(); iter.hasNext();) {
+      Map.Entry entry = (Map.Entry) iter.next();
+      // validate converter id
+      String converterId = (String) entry.getKey();
       if (converterId.length() != 1) {
         throw new JbpmException("converter-id must be a single char");
       }
-      if (convertersByDatabaseId.containsKey(converterId)) {
-        throw new JbpmException("duplicate converter-id: " + converterId);
-      }
-
-      String converterClassName = converterProperties.getProperty(converterId);
+      // load converter class
+      String converterClassName = (String) entry.getValue();
       try {
         Class converterClass = ClassLoaderUtil.classForName(converterClassName);
+        // instantiate converter
         try {
           Converter converter = (Converter) converterClass.newInstance();
-          convertersByClassNames.put(converterClassName, converter);
-          convertersByDatabaseId.put(converterId, converter);
-          convertersIds.put(converter, converterId);
-          if (debug) log.debug("registered converter: " + converterClassName);
+          converters.put(converterId, converter);
+          if (debug) log.debug("registered " + converterClassName);
         }
         catch (InstantiationException e) {
-          if (debug) log.debug("failed to instantiate: " + converterClass, e);
+          if (debug) log.debug("failed to instantiate " + converterClass, e);
         }
         catch (IllegalAccessException e) {
           if (debug) log.debug(Converters.class + " has no access to " + converterClass, e);
         }
       }
-      catch (JbpmException e) {
+      catch (ClassNotFoundException e) {
         if (debug) log.debug("converter class not found: " + converterClassName, e);
       }
     }
-
-    return converterMaps;
+    return converters;
   }
 
   private static final Log log = LogFactory.getLog(Converters.class);

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/file/def/FileDefinition.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/file/def/FileDefinition.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/file/def/FileDefinition.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -46,16 +46,15 @@
 
   private static final long serialVersionUID = 1L;
 
-  static String getRootDir() {
-    String rootDir = null;
+  private static String getRootDir() {
     if (JbpmConfiguration.Configs.hasObject("jbpm.files.dir")) {
-      rootDir = JbpmConfiguration.Configs.getString("jbpm.files.dir");
+      return JbpmConfiguration.Configs.getString("jbpm.files.dir");
     }
-    return rootDir;
+    return null;
   }
 
-  String dir;
-  Map processFiles;
+  private String dir;
+  private Map processFiles;
 
   public ModuleInstance createInstance() {
     return null;
@@ -81,7 +80,7 @@
     }
   }
 
-  void storeFileInFileSystem(String name, byte[] bytes) throws IOException {
+  private void storeFileInFileSystem(String name, byte[] bytes) throws IOException {
     File filePath = getFilePath(name);
     log.trace("storing '" + name + "' to file '" + filePath + "'");
 
@@ -90,7 +89,7 @@
     fos.close();
   }
 
-  void storeFileInDb(String name, byte[] bytes) {
+  private void storeFileInDb(String name, byte[] bytes) {
     if (processFiles == null) {
       processFiles = new HashMap();
     }
@@ -116,7 +115,7 @@
     }
   }
 
-  void storeFileInFileSystem(String name, InputStream is) throws IOException {
+  private void storeFileInFileSystem(String name, InputStream is) throws IOException {
     File filePath = getFilePath(name);
     log.trace("storing '" + name + "' to file '" + filePath + "'");
 
@@ -125,7 +124,7 @@
     fos.close();
   }
 
-  void storeFileInDb(String name, InputStream is) throws IOException {
+  private void storeFileInDb(String name, InputStream is) throws IOException {
     if (processFiles == null) {
       processFiles = new HashMap();
     }
@@ -182,8 +181,9 @@
   private InputStream getInputStreamFromFileSystem(String name) {
     try {
       File filePath = getFilePath(name);
-      if (log.isTraceEnabled())
-        log.trace("loading '" + name + "' from file '" + filePath + "'");
+      if (log.isDebugEnabled()) {
+        log.debug("loading '" + name + "' from file '" + filePath + "'");
+      }
       return filePath.canRead() ? new FileInputStream(filePath) : null;
     }
     catch (FileNotFoundException e) {
@@ -192,7 +192,7 @@
   }
 
   private InputStream getInputStreamFromDb(String name) {
-    if (log.isTraceEnabled()) log.trace("loading '" + name + "' from database");
+    if (log.isDebugEnabled()) log.debug("loading '" + name + "' from database");
     byte[] bytes = getBytesFromDb(name);
     return bytes != null ? new ByteArrayInputStream(bytes) : null;
   }
@@ -212,7 +212,7 @@
     return bytes;
   }
 
-  byte[] getBytesFromFileSystem(String name) {
+  private byte[] getBytesFromFileSystem(String name) {
     InputStream in = getInputStreamFromFileSystem(name);
     if (in == null) return null;
 
@@ -232,7 +232,7 @@
     }
   }
 
-  byte[] getBytesFromDb(String name) {
+  private byte[] getBytesFromDb(String name) {
     if (processFiles != null) {
       ByteArray byteArray = (ByteArray) processFiles.get(name);
       if (byteArray != null) return byteArray.getBytes();
@@ -240,7 +240,7 @@
     return null;
   }
 
-  boolean isStoredOnFileSystem() {
+  private boolean isStoredOnFileSystem() {
     String rootDir = getRootDir();
     boolean isStoredOnFileSystem = (rootDir != null);
     // if files should be stored on the file system
@@ -253,7 +253,7 @@
     return isStoredOnFileSystem;
   }
 
-  String findNewDirName() {
+  private String findNewDirName() {
     String dirName = "files-1";
 
     File parentFile = new File(getRootDir());
@@ -274,12 +274,8 @@
     return dirName;
   }
 
-  File getFilePath(String name) {
-    File filePath = new File(getRootDir()
-      + File.separatorChar
-      + dir
-      + File.separatorChar
-      + name);
+  private File getFilePath(String name) {
+    File filePath = new File(getRootDir(), dir + File.separatorChar + name);
     filePath.getParentFile().mkdirs();
     return filePath;
   }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/action/ActionTypes.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/action/ActionTypes.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/action/ActionTypes.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -22,6 +22,7 @@
 package org.jbpm.graph.action;
 
 import java.io.InputStream;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
@@ -32,41 +33,53 @@
 import org.w3c.dom.Element;
 
 import org.jbpm.JbpmConfiguration;
-import org.jbpm.JbpmException;
-import org.jbpm.graph.node.NodeTypes;
 import org.jbpm.util.ClassLoaderUtil;
 import org.jbpm.util.XmlUtil;
 
 public class ActionTypes {
 
-  public static Set getActionTypes() {
-    return actionNames.keySet();
+  private static Map typesByResource = new HashMap();
+  private static final Log log = LogFactory.getLog(ActionTypes.class);
+
+  public static Collection getActionTypes() {
+    return getTypes().values();
   }
 
   public static Set getActionNames() {
-    return actionTypes.keySet();
+    return getTypes().keySet();
   }
 
   public static Class getActionType(String name) {
-    return (Class) actionTypes.get(name);
+    return (Class) getTypes().get(name);
   }
 
   public static String getActionName(Class type) {
-    return (String) actionNames.get(type);
+    for (Iterator iter = getTypes().entrySet().iterator(); iter.hasNext();) {
+      Map.Entry entry = (Map.Entry) iter.next();
+      if (type == entry.getValue()) return (String) entry.getKey();
+    }
+    return null;
   }
 
   public static boolean hasActionName(String name) {
-    return actionTypes.containsKey(name);
+    return getTypes().containsKey(name);
   }
 
-  private static final Log log = LogFactory.getLog(ActionTypes.class);
-  private static Map actionTypes = initialiseActionTypes();
-  private static Map actionNames = NodeTypes.createInverseMapping(actionTypes);
+  private static Map getTypes() {
+    String resource = JbpmConfiguration.Configs.getString("resource.action.types");
+    synchronized (typesByResource) {
+      Map types = (Map) typesByResource.get(resource);
+      if (types == null) {
+        types = initialiseActionTypes(resource);
+        typesByResource.put(resource, types);
+      }
+      return types;
+    }
+  }
 
-  private static Map initialiseActionTypes() {
+  private static Map initialiseActionTypes(String resource) {
     Map types = new HashMap();
 
-    String resource = JbpmConfiguration.Configs.getString("resource.action.types");
     InputStream actionTypesStream = ClassLoaderUtil.getStream(resource);
     Element actionTypesElement = XmlUtil.parseXmlInputStream(actionTypesStream)
       .getDocumentElement();
@@ -80,7 +93,7 @@
         Class actionClass = ClassLoaderUtil.classForName(className);
         types.put(elementTag, actionClass);
       }
-      catch (JbpmException e) {
+      catch (ClassNotFoundException e) {
         if (log.isDebugEnabled()) {
           log.debug("action '" + elementTag + "' will not be available, class not found: "
             + className);

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/action/MailAction.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/action/MailAction.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/action/MailAction.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -9,12 +9,7 @@
   private static final long serialVersionUID = 1L;
 
   public void read(Element element, JpdlXmlReader jpdlReader) {
-    String template = element.attributeValue("template");
-    String actors = element.attributeValue("actors");
-    String to = element.attributeValue("to");
-    String subject = jpdlReader.getProperty("subject", element);
-    String text = jpdlReader.getProperty("text", element);
-    actionDelegation = jpdlReader.createMailDelegation(template, actors, to, subject, text);
+    actionDelegation = jpdlReader.readMailDelegation(element);
   }
 
   public String toString() {

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/ExceptionHandler.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/ExceptionHandler.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/ExceptionHandler.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -26,6 +26,7 @@
 import java.util.Iterator;
 import java.util.List;
 
+import org.jbpm.JbpmException;
 import org.jbpm.graph.exe.ExecutionContext;
 import org.jbpm.util.ClassLoaderUtil;
 
@@ -34,26 +35,33 @@
   private static final long serialVersionUID = 1L;
 
   long id = 0;
-  protected String exceptionClassName = null;
-  protected GraphElement graphElement = null;
-  protected List actions = null;
+  protected String exceptionClassName;
+  protected GraphElement graphElement;
+  protected List actions;
 
+  private transient Class exceptionClass;
+
   public ExceptionHandler() {
   }
 
   public boolean matches(Throwable exception) {
-    boolean matches = true;
-    if (exceptionClassName != null) {
-      Class clazz = ClassLoaderUtil.classForName(exceptionClassName);
-      if (!clazz.isAssignableFrom(exception.getClass())) {
-        matches = false;
+    return exceptionClassName != null ? getExceptionClass().isInstance(exception) : true;
+  }
+
+  private Class getExceptionClass() {
+    if (exceptionClass == null) {
+      try {
+        exceptionClass = ClassLoaderUtil.classForName(exceptionClassName);
       }
+      catch (ClassNotFoundException e) {
+        throw new JbpmException("exception class not found: " + exceptionClassName, e);
+      }
     }
-    return matches;
+    return exceptionClass;
   }
 
   public void handleException(GraphElement graphElement, ExecutionContext executionContext)
-      throws Exception {
+    throws Exception {
     if (actions != null) {
       for (Iterator iter = actions.iterator(); iter.hasNext();) {
         Action action = (Action) iter.next();
@@ -63,7 +71,7 @@
   }
 
   // actions
-  /////////////////////////////////////////////////////////////////////////////
+  // ///////////////////////////////////////////////////////////////////////////
   public List getActions() {
     return actions;
   }
@@ -74,19 +82,15 @@
   }
 
   public void removeAction(Action action) {
-    if (actions != null) {
-      actions.remove(action);
-    }
+    if (actions != null) actions.remove(action);
   }
 
   public void reorderAction(int oldIndex, int newIndex) {
-    if (actions != null) {
-      actions.add(newIndex, actions.remove(oldIndex));
-    }
+    if (actions != null) actions.add(newIndex, actions.remove(oldIndex));
   }
 
   // getters and setters
-  /////////////////////////////////////////////////////////////////////////////
+  // ///////////////////////////////////////////////////////////////////////////
 
   public String getExceptionClassName() {
     return exceptionClassName;

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/ProcessDefinition.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/ProcessDefinition.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/ProcessDefinition.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -34,6 +34,8 @@
 import java.util.Properties;
 import java.util.zip.ZipInputStream;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.xml.sax.InputSource;
 
 import org.jbpm.JbpmConfiguration;
@@ -58,24 +60,36 @@
   protected boolean isTerminationImplicit;
   protected Node startState;
   protected List nodes;
-  transient Map nodesMap;
+  private transient Map nodesMap;
   protected Map actions;
   protected Map definitions;
 
+  private static final Map moduleClassesByResource = new HashMap();
+
   // event types //////////////////////////////////////////////////////////////
 
   private static final String[] EVENT_TYPES = {
-    Event.EVENTTYPE_PROCESS_START, Event.EVENTTYPE_PROCESS_END, Event.EVENTTYPE_NODE_ENTER,
-    Event.EVENTTYPE_NODE_LEAVE, Event.EVENTTYPE_TASK_CREATE, Event.EVENTTYPE_TASK_ASSIGN,
-    Event.EVENTTYPE_TASK_START, Event.EVENTTYPE_TASK_END, Event.EVENTTYPE_TRANSITION,
-    Event.EVENTTYPE_BEFORE_SIGNAL, Event.EVENTTYPE_AFTER_SIGNAL,
-    Event.EVENTTYPE_SUPERSTATE_ENTER, Event.EVENTTYPE_SUPERSTATE_LEAVE,
-    Event.EVENTTYPE_SUBPROCESS_CREATED, Event.EVENTTYPE_SUBPROCESS_END, Event.EVENTTYPE_TIMER
+    Event.EVENTTYPE_PROCESS_START,
+    Event.EVENTTYPE_PROCESS_END,
+    Event.EVENTTYPE_NODE_ENTER,
+    Event.EVENTTYPE_NODE_LEAVE,
+    Event.EVENTTYPE_TASK_CREATE,
+    Event.EVENTTYPE_TASK_ASSIGN,
+    Event.EVENTTYPE_TASK_START,
+    Event.EVENTTYPE_TASK_END,
+    Event.EVENTTYPE_TRANSITION,
+    Event.EVENTTYPE_BEFORE_SIGNAL,
+    Event.EVENTTYPE_AFTER_SIGNAL,
+    Event.EVENTTYPE_SUPERSTATE_ENTER,
+    Event.EVENTTYPE_SUPERSTATE_LEAVE,
+    Event.EVENTTYPE_SUBPROCESS_CREATED,
+    Event.EVENTTYPE_SUBPROCESS_END,
+    Event.EVENTTYPE_TIMER
   };
 
   /**
-   * @deprecated arrays are mutable and thus vulnerable to external
-   * manipulation. use {@link #getSupportedEventTypes()} instead
+   * @deprecated arrays are mutable and thus vulnerable to external manipulation. use
+   * {@link #getSupportedEventTypes()} instead
    */
   public static final String[] supportedEventTypes = (String[]) EVENT_TYPES.clone();
 
@@ -92,12 +106,10 @@
   public static ProcessDefinition createNewProcessDefinition() {
     ProcessDefinition processDefinition = new ProcessDefinition();
 
-    // add all default modules from file jbpm.default.modules
-    String resource = JbpmConfiguration.Configs.getString("resource.default.modules");
-    Properties defaultModulesProperties = ClassLoaderUtil.getProperties(resource);
-    for (Iterator iter = defaultModulesProperties.keySet().iterator(); iter.hasNext();) {
-      String moduleClassName = (String) iter.next();
-      Class moduleClass = ClassLoaderUtil.classForName(moduleClassName);
+    // instantiate default modules
+    List moduleClasses = getModuleClasses();
+    for (Iterator iter = moduleClasses.iterator(); iter.hasNext();) {
+      Class moduleClass = (Class) iter.next();
       try {
         ModuleDefinition moduleDefinition = (ModuleDefinition) moduleClass.newInstance();
         processDefinition.addDefinition(moduleDefinition);
@@ -109,9 +121,43 @@
         throw new JbpmException(ProcessDefinition.class + " has no access to " + moduleClass, e);
       }
     }
+
     return processDefinition;
   }
 
+  private static List getModuleClasses() {
+    String resource = JbpmConfiguration.Configs.getString("resource.default.modules");
+    synchronized (moduleClassesByResource) {
+      List moduleClasses = (List) moduleClassesByResource.get(resource);
+      if (moduleClasses == null) {
+        moduleClasses = loadModuleClasses(resource);
+        moduleClassesByResource.put(resource, moduleClasses);
+      }
+      return moduleClasses;
+    }
+  }
+
+  private static List loadModuleClasses(String resource) {
+    Properties properties = ClassLoaderUtil.getProperties(resource);
+    List moduleClasses = new ArrayList();
+
+    Log log = LogFactory.getLog(ProcessDefinition.class);
+    boolean debug = log.isDebugEnabled();
+
+    for (Iterator iter = properties.keySet().iterator(); iter.hasNext();) {
+      String moduleClassName = (String) iter.next();
+      try {
+        Class moduleClass = ClassLoaderUtil.classForName(moduleClassName);
+        moduleClasses.add(moduleClass);
+        if (debug) log.debug("loaded module " + moduleClassName);
+      }
+      catch (ClassNotFoundException e) {
+        if (debug) log.debug("module class not found: " + moduleClassName, e);
+      }
+    }
+    return moduleClasses;
+  }
+
   public ProcessDefinition(String name) {
     this();
     this.name = name;
@@ -136,8 +182,7 @@
 
   public void setProcessDefinition(ProcessDefinition processDefinition) {
     if (!equals(processDefinition)) {
-      throw new IllegalArgumentException(
-        "process definition cannot reference another process definition");
+      throw new IllegalArgumentException("process definition cannot reference another process definition");
     }
   }
 
@@ -333,7 +378,7 @@
     return name;
   }
 
-  static boolean containsName(List nodes, String name) {
+  private static boolean containsName(List nodes, String name) {
     for (Iterator iter = nodes.iterator(); iter.hasNext();) {
       Node node = (Node) iter.next();
       if (name.equals(node.getName())) return true;
@@ -393,11 +438,9 @@
   // actions //////////////////////////////////////////////////////////////////
 
   /**
-   * creates a bidirectional relation between this process definition and the
-   * given action.
+   * creates a bidirectional relation between this process definition and the given action.
    * 
-   * @throws IllegalArgumentException if action is null or if action.getName()
-   * is null.
+   * @throws IllegalArgumentException if action is null or if action.getName() is null.
    */
   public Action addAction(Action action) {
     if (action == null) {
@@ -413,11 +456,10 @@
   }
 
   /**
-   * removes the bidirectional relation between this process definition and the
-   * given action.
+   * removes the bidirectional relation between this process definition and the given action.
    * 
-   * @throws IllegalArgumentException if action is null or if the action was not
-   * present in the actions of this process definition.
+   * @throws IllegalArgumentException if action is null or if the action was not present in the
+   * actions of this process definition.
    */
   public void removeAction(Action action) {
     if (action == null) {

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/node/MailNode.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/node/MailNode.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/node/MailNode.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -14,12 +14,7 @@
   // xml //////////////////////////////////////////////////////////////////////
 
   public void read(Element element, JpdlXmlReader jpdlReader) {
-    String template = element.attributeValue("template");
-    String actors = element.attributeValue("actors");
-    String to = element.attributeValue("to");
-    String subject = jpdlReader.getProperty("subject", element);
-    String text = jpdlReader.getProperty("text", element);
-    Delegation delegation = jpdlReader.createMailDelegation(template, actors, to, subject, text);
+    Delegation delegation = jpdlReader.readMailDelegation(element);
     this.action = new Action(delegation);
   }
 
@@ -29,5 +24,4 @@
     // leave the node over the default transition
     leave(executionContext);
   }
-
 }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/node/NodeTypes.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/node/NodeTypes.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/node/NodeTypes.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -22,6 +22,7 @@
 package org.jbpm.graph.node;
 
 import java.io.InputStream;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
@@ -32,37 +33,49 @@
 import org.w3c.dom.Element;
 
 import org.jbpm.JbpmConfiguration;
-import org.jbpm.JbpmException;
 import org.jbpm.util.ClassLoaderUtil;
 import org.jbpm.util.XmlUtil;
 
 public class NodeTypes {
 
-  public static Set getNodeTypes() {
-    return nodeTypes.keySet();
+  private static Map typesByResource = new HashMap();
+  private static final Log log = LogFactory.getLog(NodeTypes.class);
+
+  public static Collection getNodeTypes() {
+    return getTypes().values();
   }
 
   public static Set getNodeNames() {
-    return nodeNames.keySet();
+    return getTypes().keySet();
   }
 
   public static Class getNodeType(String name) {
-    return (Class) nodeTypes.get(name);
+    return (Class) getTypes().get(name);
   }
 
   public static String getNodeName(Class type) {
-    return (String) nodeNames.get(type);
+    for (Iterator iter = getTypes().entrySet().iterator(); iter.hasNext();) {
+      Map.Entry entry = (Map.Entry) iter.next();
+      if (type == entry.getValue()) return (String) entry.getKey();
+    }
+    return null;
   }
 
-  private static final Log log = LogFactory.getLog(NodeTypes.class);
+  private static Map getTypes() {
+    String resource = JbpmConfiguration.Configs.getString("resource.node.types");
+    synchronized (typesByResource) {
+      Map types = (Map) typesByResource.get(resource);
+      if (types == null) {
+        types = initialiseNodeTypes(resource);
+        typesByResource.put(resource, types);
+      }
+      return types;
+    }
+  }
 
-  private static Map nodeTypes = initialiseNodeTypes();
-  private static Map nodeNames = createInverseMapping(nodeTypes);
-
-  private static Map initialiseNodeTypes() {
+  private static Map initialiseNodeTypes(String resource) {
     Map types = new HashMap();
 
-    String resource = JbpmConfiguration.Configs.getString("resource.node.types");
     InputStream nodeTypesStream = ClassLoaderUtil.getStream(resource);
     Element nodeTypesElement = XmlUtil.parseXmlInputStream(nodeTypesStream)
       .getDocumentElement();
@@ -76,7 +89,7 @@
         Class nodeClass = ClassLoaderUtil.classForName(className);
         types.put(elementTag, nodeClass);
       }
-      catch (JbpmException e) {
+      catch (ClassNotFoundException e) {
         if (log.isDebugEnabled()) {
           log.debug("node '" + elementTag + "' will not be available, class not found: "
             + className);

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/instantiation/FieldInstantiator.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/instantiation/FieldInstantiator.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/instantiation/FieldInstantiator.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -181,9 +181,13 @@
           value = getMap(propertyElement, (Map) type.newInstance());
         }
         else if (propertyElement.isTextOnly()) {
-          Constructor constructor = type.getConstructor(new Class[] { String.class });
+          Constructor constructor = type.getConstructor(new Class[] {
+            String.class
+          });
           try {
-            value = constructor.newInstance(new Object[] { propertyElement.getTextTrim() });
+            value = constructor.newInstance(new Object[] {
+              propertyElement.getTextTrim()
+            });
           }
           catch (IllegalAccessException e) {
             log.error(FieldInstantiator.class + " has no access to " + constructor);
@@ -234,16 +238,20 @@
   }
 
   /**
-   * Returns the <code>Class</code> associated with the value for the attribute
-   * with the given name.
+   * Returns the <code>Class</code> associated with the value for the attribute with the given
+   * name.
    */
   private static Class classForAttributeValue(Element element, String attributeName) {
-    Class type = String.class;
-    String attributeValue = element.attributeValue(attributeName);
-    if (attributeValue != null) {
-      type = ClassLoaderUtil.classForName(attributeValue);
+    String className = element.attributeValue(attributeName);
+    if (className != null) {
+      try {
+        return ClassLoaderUtil.classForName(className);
+      }
+      catch (ClassNotFoundException e) {
+        throw new JbpmException("no such class " + className, e);
+      }
     }
-    return type;
+    return String.class;
   }
 
   private static final Log log = LogFactory.getLog(FieldInstantiator.class);

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/jpdl/par/ProcessArchive.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/jpdl/par/ProcessArchive.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/jpdl/par/ProcessArchive.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -33,11 +33,11 @@
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
 
-import org.w3c.dom.Document;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.w3c.dom.Element;
 
 import org.jbpm.JbpmConfiguration;
-import org.jbpm.JbpmException;
 import org.jbpm.graph.def.ProcessDefinition;
 import org.jbpm.jpdl.JpdlException;
 import org.jbpm.jpdl.xml.Problem;
@@ -50,26 +50,22 @@
 
   private static final long serialVersionUID = 1L;
 
-  static List processArchiveParsers = getProcessArchiveParsers();
+  private static final Map parsersByResource = new HashMap();
 
   // fields ///////////////////////////////////////////////////////////////////
 
-  String name = "";
+  private String name = "";
   // maps entry-names (String) to byte-arrays (byte[])
-  Map entries = new HashMap();
-  List problems = new ArrayList();
+  private Map entries = new HashMap();
+  private List problems = new ArrayList();
 
   // constructors /////////////////////////////////////////////////////////////
 
   public ProcessArchive(ZipInputStream zipInputStream) throws IOException {
-    ZipEntry zipEntry = zipInputStream.getNextEntry();
-    while (zipEntry != null) {
+    for (ZipEntry zipEntry = zipInputStream.getNextEntry(); zipEntry != null; zipEntry = zipInputStream.getNextEntry()) {
       String entryName = zipEntry.getName();
       byte[] bytes = IoUtil.readBytes(zipInputStream);
-      if (bytes != null) {
-        entries.put(entryName, bytes);
-      }
-      zipEntry = zipInputStream.getNextEntry();
+      entries.put(entryName, bytes);
     }
   }
 
@@ -77,8 +73,7 @@
 
   public ProcessDefinition parseProcessDefinition() {
     ProcessDefinition processDefinition = ProcessDefinition.createNewProcessDefinition();
-    Iterator iter = processArchiveParsers.iterator();
-    while (iter.hasNext()) {
+    for (Iterator iter = getParsers().iterator(); iter.hasNext();) {
       ProcessArchiveParser processArchiveParser = (ProcessArchiveParser) iter.next();
       processDefinition = processArchiveParser.readFromArchive(this, processDefinition);
     }
@@ -126,28 +121,53 @@
     problems = new ArrayList();
   }
 
-  static List getProcessArchiveParsers() {
-    List processArchiveParsers = new ArrayList();
-    try {
-      String resource = JbpmConfiguration.Configs.getString("resource.parsers");
-      InputStream parsersStream = ClassLoaderUtil.getStream(resource);
-      Document document = XmlUtil.parseXmlInputStream(parsersStream);
-      Iterator iter = XmlUtil.elementIterator(document.getDocumentElement(), "parser");
-      while (iter.hasNext()) {
-        Element element = (Element) iter.next();
-        String className = element.getAttribute("class");
-        ProcessArchiveParser processArchiveParser = (ProcessArchiveParser) ClassLoaderUtil.classForName(className)
-            .newInstance();
-        if (processArchiveParser instanceof ConfigurableParser) {
-          ((ConfigurableParser) processArchiveParser).configure(element);
+  private static List getParsers() {
+    String resource = JbpmConfiguration.Configs.getString("resource.parsers");
+    synchronized (parsersByResource) {
+      List parsers = (List) parsersByResource.get(resource);
+      if (parsers == null) {
+        parsers = createParsers(resource);
+        parsersByResource.put(resource, parsers);
+      }
+      return parsers;
+    }
+  }
+
+  private static List createParsers(String resource) {
+    // read parsers resource
+    InputStream resourceStream = ClassLoaderUtil.getStream(resource);
+    Element parsersElement = XmlUtil.parseXmlInputStream(resourceStream).getDocumentElement();
+    List parsers = new ArrayList();
+
+    Log log = LogFactory.getLog(ProcessArchive.class);
+    boolean debug = log.isDebugEnabled();
+
+    for (Iterator iter = XmlUtil.elementIterator(parsersElement, "parser"); iter.hasNext();) {
+      Element parserElement = (Element) iter.next();
+      String parserClassName = parserElement.getAttribute("class");
+      // load parser class
+      try {
+        Class parserClass = ClassLoaderUtil.classForName(parserClassName);
+        // instantiate parser
+        try {
+          ProcessArchiveParser parser = (ProcessArchiveParser) parserClass.newInstance();
+          if (parser instanceof ConfigurableParser) {
+            ((ConfigurableParser) parser).configure(parserElement);
+          }
+          parsers.add(parser);
+          if (debug) log.debug("loaded " + parserClass);
         }
-        processArchiveParsers.add(processArchiveParser);
+        catch (InstantiationException e) {
+          if (debug) log.debug("failed to instantiate " + parserClass, e);
+        }
+        catch (IllegalAccessException e) {
+          if (debug) log.debug(ProcessArchive.class + " has no access to " + parserClass, e);
+        }
       }
+      catch (ClassNotFoundException e) {
+        if (debug) log.debug("parser not found: " + parserClassName, e);
+      }
     }
-    catch (Exception e) {
-      throw new JbpmException("couldn't parse process archive parsers (jbpm.parsers.xml)", e);
-    }
-    return processArchiveParsers;
+    return parsers;
   }
-
 }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/jpdl/xml/JpdlParser.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/jpdl/xml/JpdlParser.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/jpdl/xml/JpdlParser.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -57,6 +57,10 @@
 
   private static final long serialVersionUID = 1L;
 
+  private static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
+  private static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
+  private static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";
+
   private static SAXParserFactory saxParserFactory = createSaxParserFactory();
   private static Set schemaResources = getDefaultSchemaResources();
   private static Object schemaSource;
@@ -94,7 +98,7 @@
     }
 
     try {
-      saxParser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");
+      saxParser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
     }
     catch (SAXException e) {
       log.warn("failed to set schema language to xml schema", e);
@@ -102,7 +106,7 @@
 
     Object schemaSource = getSchemaSource();
     try {
-      saxParser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaSource", schemaSource);
+      saxParser.setProperty(JAXP_SCHEMA_SOURCE, schemaSource);
     }
     catch (SAXException e) {
       log.warn("failed to set schema source to " + schemaSource, e);

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/jpdl/xml/JpdlXmlReader.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/jpdl/xml/JpdlXmlReader.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/jpdl/xml/JpdlXmlReader.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -713,9 +713,8 @@
   /**
    * creates the transition object and configures it by the read attributes
    * 
-   * @return the created <code>org.jbpm.graph.def.Transition</code> object
-   * (useful, if you want to override this method to read additional
-   * configuration properties)
+   * @return the created <code>org.jbpm.graph.def.Transition</code> object (useful, if you want
+   * to override this method to read additional configuration properties)
    */
   public Transition resolveTransitionDestination(Element transitionElement, Node node) {
     Transition transition = new Transition();
@@ -802,6 +801,7 @@
 
   // mail delegations /////////////////////////////////////////////////////////
 
+  /** @deprecated call {@link #readMailDelegation(Element)} instead */
   public Delegation createMailDelegation(String template, String actors, String to,
     String subject, String text) {
     StringBuffer config = new StringBuffer();
@@ -845,6 +845,54 @@
     return delegation;
   }
 
+  public Delegation readMailDelegation(Element element) {
+    StringBuffer config = new StringBuffer();
+    // template
+    String template = element.attributeValue("template");
+    if (template != null) {
+      config.append("<template>").append(template).append("</template>");
+    }
+    // to - addresses
+    String to = element.attributeValue("to");
+    if (to != null) {
+      config.append("<to>").append(to).append("</to>");
+    }
+    // to - actors
+    String actors = element.attributeValue("actors");
+    if (actors != null) {
+      config.append("<actors>").append(actors).append("</actors>");
+    }
+    // cc - addresses
+    String cc = element.attributeValue("cc");
+    if (cc != null) {
+      config.append("<cc>").append(cc).append("</cc>");
+    }
+    // cc - actors
+    // subject
+    String subject = getProperty("subject", element);
+    if (subject != null) {
+      config.append("<subject>").append(subject).append("</subject>");
+    }
+    // text
+    String text = getProperty("text", element);
+    if (text != null) {
+      config.append("<text>").append(text).append("</text>");
+    }
+
+    String mailClassName;
+    if (JbpmConfiguration.Configs.hasObject("jbpm.mail.class.name")) {
+      mailClassName = JbpmConfiguration.Configs.getString("jbpm.mail.class.name");
+    }
+    else {
+      mailClassName = Mail.class.getName();
+    }
+
+    Delegation delegation = new Delegation(mailClassName);
+    delegation.setProcessDefinition(processDefinition);
+    delegation.setConfiguration(config.toString());
+    return delegation;
+  }
+
   public String getProperty(String property, Element element) {
     String value = element.attributeValue(property);
     if (value == null) {

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/mail/Mail.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/mail/Mail.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/mail/Mail.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -1,11 +1,10 @@
 package org.jbpm.mail;
 
-import java.io.IOException;
-import java.io.InputStream;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -36,8 +35,10 @@
 public class Mail implements ActionHandler {
 
   private String template;
+  private String to;
   private String actors;
-  private String to;
+  private String cc;
+  private String ccActors;
   private String bcc;
   private String bccActors;
   private String subject;
@@ -45,7 +46,7 @@
 
   private ExecutionContext executionContext;
 
-  private static final long serialVersionUID = 1L;
+  private static final long serialVersionUID = 2L;
 
   public Mail() {
   }
@@ -81,6 +82,13 @@
     return recipients;
   }
 
+  public List getCcRecipients() {
+    List recipients = new ArrayList();
+    if (ccActors != null) recipients.addAll(evaluateActors(ccActors));
+    if (cc != null) recipients.addAll(evaluateAddresses(cc));
+    return recipients;
+  }
+
   public List getBccRecipients() {
     List recipients = new ArrayList();
     if (bccActors != null) recipients.addAll(evaluateActors(bccActors));
@@ -113,8 +121,7 @@
   }
 
   protected Collection resolveAddresses(List actorIds) {
-    AddressResolver addressResolver = (AddressResolver) JbpmConfiguration.Configs
-      .getObject("jbpm.mail.address.resolver");
+    AddressResolver addressResolver = (AddressResolver) JbpmConfiguration.Configs.getObject("jbpm.mail.address.resolver");
 
     List addresses = new ArrayList();
     for (Iterator iter = actorIds.iterator(); iter.hasNext();) {
@@ -146,20 +153,18 @@
     if (value instanceof String) return tokenize((String) value);
     if (value instanceof String[]) return Arrays.asList((String[]) value);
     if (value instanceof Collection) return (Collection) value;
+    // give up
     throw new JbpmException(expression + " returned " + value
       + " instead of comma-separated string, string array or collection");
   }
 
   protected List tokenize(String text) {
-    return text != null ? Arrays.asList(text.split("[;:]+")) : null;
+    return text != null ? Arrays.asList(text.split("[,;:]+")) : null;
   }
 
   private Object evaluate(String expression, Class expectedType) {
-    VariableResolver variableResolver = new MailVariableResolver(templateVariables, JbpmExpressionEvaluator
-      .getVariableResolver());
-    return JbpmExpressionEvaluator
-      .evaluate(expression, executionContext, expectedType, variableResolver, JbpmExpressionEvaluator
-        .getFunctionMapper());
+    VariableResolver variableResolver = new MailVariableResolver(getTemplateVariables(), JbpmExpressionEvaluator.getVariableResolver());
+    return JbpmExpressionEvaluator.evaluate(expression, executionContext, expectedType, variableResolver, JbpmExpressionEvaluator.getFunctionMapper());
   }
 
   public String getSubject() {
@@ -174,76 +179,98 @@
     if (JbpmConfiguration.Configs.hasObject("jbpm.mail.from.address")) {
       return JbpmConfiguration.Configs.getString("jbpm.mail.from.address");
     }
-    return "jbpm at noreply";
+    return "no-reply at jbpm.org";
   }
 
   public void send() {
     if (template != null) {
-      Properties properties = getMailTemplateProperties(template);
+      Properties templateProperties = getTemplateProperties(template);
 
-      if (actors == null) actors = properties.getProperty("actors");
-      if (to == null) to = properties.getProperty("to");
-      if (subject == null) subject = properties.getProperty("subject");
-      if (text == null) text = properties.getProperty("text");
-      if (bcc == null) bcc = properties.getProperty("bcc");
-      if (bccActors == null) bccActors = properties.getProperty("bccActors");
+      if (actors == null) actors = templateProperties.getProperty("actors");
+      if (to == null) to = templateProperties.getProperty("to");
+      if (cc == null) cc = templateProperties.getProperty("cc");
+      if (ccActors == null) ccActors = templateProperties.getProperty("cc-actors");
+      if (bcc == null) bcc = templateProperties.getProperty("bcc");
+      if (bccActors == null) bccActors = templateProperties.getProperty("bcc-actors");
+      if (subject == null) subject = templateProperties.getProperty("subject");
+      if (text == null) text = templateProperties.getProperty("text");
     }
 
-    send(getMailServerProperties(), getFromAddress(), getRecipients(), getBccRecipients(), getSubject(), getText());
+    List recipients = getRecipients();
+    List ccRecipients = getCcRecipients();
+    List bccRecipients = getBccRecipients();
+    if (recipients.isEmpty() && ccRecipients.isEmpty() && bccRecipients.isEmpty()) return;
+
+    String subject = getSubject();
+    String text = getText();
+
+    if (log.isDebugEnabled()) {
+      StringBuffer detail = new StringBuffer("sending email to ");
+      detail.append(recipients);
+      if (!ccRecipients.isEmpty()) detail.append(" cc ").append(ccRecipients);
+      if (!bccRecipients.isEmpty()) detail.append(" bcc ").append(bccRecipients);
+      if (subject != null) detail.append(" about '").append(subject).append('\'');
+      log.debug(detail.toString());
+    }
+
+    Session session = Session.getInstance(getServerProperties());
+    for (int retries = 3; retries >= 0; retries--) {
+      try {
+        sendMailInternal(session, recipients, ccRecipients, bccRecipients, subject, text);
+        break;
+      }
+      catch (MessagingException me) {
+        if (retries == 0) throw new JbpmException("cannot send email", me);
+        log.warn("cannot send mail (" + retries + " retries left): " + me.getMessage());
+      }
+    }
   }
 
-  public static void send(Properties mailServerProperties, String fromAddress, List recipients,
+  public static void send(Properties serverProperties, String fromAddress, List recipients,
     String subject, String text) {
-    send(mailServerProperties, fromAddress, recipients, null, subject, text);
+    send(serverProperties, fromAddress, recipients, Collections.EMPTY_LIST, subject, text);
   }
 
-  public static void send(Properties mailServerProperties, String fromAddress, List recipients,
+  public static void send(Properties serverProperties, String fromAddress, List recipients,
     List bccRecipients, String subject, String text) {
-    // if there are no recipients, skip mail sending
-    if ((recipients == null || recipients.isEmpty())
-      && (bccRecipients == null || bccRecipients.isEmpty())) return;
+    if (recipients.isEmpty() && bccRecipients.isEmpty()) return;
 
-    for (int retries = 5; retries >= 0; retries--) {
+    if (log.isDebugEnabled()) {
+      StringBuffer detail = new StringBuffer("sending email to ");
+      detail.append(recipients);
+      if (bccRecipients != null) detail.append(" bcc ").append(bccRecipients);
+      if (subject != null) detail.append(" about '").append(subject).append('\'');
+      log.debug(detail.toString());
+    }
+
+    Session session = Session.getInstance(serverProperties);
+    for (int retries = 3; retries >= 0; retries--) {
       try {
-        sendMailInternal(mailServerProperties, fromAddress, recipients, bccRecipients, subject, text);
+        sendMailInternal(session, recipients, null, bccRecipients, subject, text);
         break;
       }
       catch (MessagingException me) {
         if (retries == 0) throw new JbpmException("cannot send email", me);
-
         log.warn("cannot send mail (" + retries + " retries left): " + me.getMessage());
-        try {
-          Thread.sleep(1000);
-        }
-        catch (InterruptedException ie) {
-          // reassert interruption
-          Thread.currentThread().interrupt();
-          throw new JbpmException("cannot send email", me);
-        }
       }
     }
   }
 
-  private static void sendMailInternal(Properties mailServerProperties, String fromAddress,
-    List recipients, List bccRecipients, String subject, String text) throws MessagingException {
-    if (log.isDebugEnabled()) {
-      StringBuffer message = new StringBuffer("sending email ");
-      if (recipients != null) message.append(recipients);
-      if (bccRecipients != null) message.append(" bcc ").append(bccRecipients);
-      if (fromAddress != null) message.append(" from '").append(fromAddress).append(')');
-      if (subject != null) message.append(" about '").append(subject).append(')');
-      log.debug(message.toString());
-    }
-
-    Session session = Session.getDefaultInstance(mailServerProperties, null);
+  private static void sendMailInternal(Session session, List recipients, List ccRecipients,
+    List bccRecipients, String subject, String text) throws MessagingException {
     MimeMessage message = new MimeMessage(session);
-    // from
-    if (fromAddress != null) message.setFrom(new InternetAddress(fromAddress));
     // to
     for (Iterator iter = recipients.iterator(); iter.hasNext();) {
       InternetAddress recipient = new InternetAddress((String) iter.next());
       message.addRecipient(Message.RecipientType.TO, recipient);
     }
+    // cc
+    if (ccRecipients != null) {
+      for (Iterator iter = ccRecipients.iterator(); iter.hasNext();) {
+        InternetAddress recipient = new InternetAddress((String) iter.next());
+        message.addRecipient(Message.RecipientType.CC, recipient);
+      }
+    }
     // bcc
     if (bccRecipients != null) {
       for (Iterator iter = bccRecipients.iterator(); iter.hasNext();) {
@@ -255,90 +282,129 @@
     if (subject != null) message.setSubject(subject);
     // text
     if (text != null) message.setText(text);
-
+    // send the message
     Transport.send(message);
   }
 
-  private Properties getMailServerProperties() {
-    Properties mailServerProperties = new Properties();
+  private static final Map serverPropertiesByResource = new HashMap();
 
+  private Properties getServerProperties() {
+    Properties serverProperties;
+
     if (JbpmConfiguration.Configs.hasObject("resource.mail.properties")) {
-      String mailServerPropertiesResource = JbpmConfiguration.Configs
-        .getString("resource.mail.properties");
-      try {
-        InputStream mailServerStream = ClassLoaderUtil.getStream(mailServerPropertiesResource);
-        mailServerProperties.load(mailServerStream);
+      String resource = JbpmConfiguration.Configs.getString("resource.mail.properties");
+      synchronized (serverPropertiesByResource) {
+        serverProperties = (Properties) serverPropertiesByResource.get(resource);
+        if (serverProperties == null) {
+          // load mail properties
+          serverProperties = ClassLoaderUtil.getProperties(resource);
+          serverPropertiesByResource.put(resource, serverProperties);
+        }
       }
-      catch (IOException e) {
-        throw new JbpmException("could not load mail server properties from resource: "
-          + mailServerPropertiesResource, e);
-      }
     }
-    else if (JbpmConfiguration.Configs.hasObject("jbpm.mail.smtp.host")) {
-      String smtpServer = JbpmConfiguration.Configs.getString("jbpm.mail.smtp.host");
-      mailServerProperties.put("mail.smtp.host", smtpServer);
-    }
     else {
-      log.error("could not get mail properties");
+      serverProperties = new Properties();
+      // host
+      if (JbpmConfiguration.Configs.hasObject("jbpm.mail.smtp.host")) {
+        String smtpHost = JbpmConfiguration.Configs.getString("jbpm.mail.smtp.host");
+        serverProperties.setProperty("mail.smtp.host", smtpHost);
+      }
+      // port
+      if (JbpmConfiguration.Configs.hasObject("jbpm.mail.smtp.port")) {
+        int port = JbpmConfiguration.Configs.getInt("jbpm.mail.smtp.port");
+        serverProperties.setProperty("mail.smtp.port", Integer.toString(port));
+      }
+      // from
+      String from = getFromAddress();
+      serverProperties.setProperty("mail.from", from);
     }
+    return serverProperties;
+  }
 
-    return mailServerProperties;
+  private static final Map templatePropertiesByResource = new HashMap();
+  private static final Map templateVariablesByResource = new HashMap();
+
+  private static Properties getTemplateProperties(String templateName) {
+    String resource = JbpmConfiguration.Configs.getString("resource.mail.templates");
+    synchronized (templatePropertiesByResource) {
+      Map templateProperties = (Map) templatePropertiesByResource.get(resource);
+      if (templateProperties == null) {
+        loadTemplates(resource);
+        templateProperties = (Map) templatePropertiesByResource.get(resource);
+      }
+      return (Properties) templateProperties.get(templateName);
+    }
   }
 
-  private static Map templates;
-  private static Map templateVariables;
+  private static Map getTemplateVariables() {
+    String resource = JbpmConfiguration.Configs.getString("resource.mail.templates");
+    synchronized (templateVariablesByResource) {
+      Map templateVariables = (Map) templateVariablesByResource.get(resource);
+      if (templateVariables == null) {
+        loadTemplates(resource);
+        templateVariables = (Map) templateVariablesByResource.get(resource);
+      }
+      return templateVariables;
+    }
+  }
 
-  private synchronized Properties getMailTemplateProperties(String templateName) {
-    if (templates == null) {
-      templates = new HashMap();
-      String mailTemplatesResource = JbpmConfiguration.Configs
-        .getString("resource.mail.templates");
+  private static void loadTemplates(String resource) {
+    Element templatesElement = XmlUtil.parseXmlResource(resource, true).getDocumentElement();
 
-      Element mailTemplatesElement = XmlUtil
-        .parseXmlResource(mailTemplatesResource, true)
-        .getDocumentElement();
-      for (Iterator iter = XmlUtil.elementIterator(mailTemplatesElement, "mail-template"); iter
-        .hasNext();) {
-        Element mailTemplateElement = (Element) iter.next();
+    Map templatePropertiesMap = new HashMap();
+    for (Iterator iter = XmlUtil.elementIterator(templatesElement, "mail-template"); iter.hasNext();) {
+      Element templateElement = (Element) iter.next();
 
-        Properties templateProperties = new Properties();
-        addTemplateProperty(mailTemplateElement, "actors", templateProperties);
-        addTemplateProperty(mailTemplateElement, "to", templateProperties);
-        addTemplateProperty(mailTemplateElement, "subject", templateProperties);
-        addTemplateProperty(mailTemplateElement, "text", templateProperties);
-        addTemplateProperty(mailTemplateElement, "bcc", templateProperties);
-        addTemplateProperty(mailTemplateElement, "bccActors", templateProperties);
-
-        templates.put(mailTemplateElement.getAttribute("name"), templateProperties);
+      Properties templateProperties = new Properties();
+      addTemplateProperty(templateElement, "to", templateProperties);
+      addTemplateProperty(templateElement, "actors", templateProperties);
+      addTemplateProperty(templateElement, "subject", templateProperties);
+      addTemplateProperty(templateElement, "text", templateProperties);
+      addTemplateProperty(templateElement, "cc", templateProperties);
+      addTemplateProperty(templateElement, "cc-actors", templateProperties);
+      addTemplateProperty(templateElement, "bcc", templateProperties);
+      addTemplateProperty(templateElement, "bcc-actors", templateProperties);
+      // preserve backwards compatibility with bccActors element
+      Element bccActorsElement = XmlUtil.element(templateElement, "bccActors");
+      if (bccActorsElement != null) {
+        String bccActors = templateProperties.getProperty("bcc-actors");
+        if (bccActors != null) {
+          bccActors += ';' + XmlUtil.getContentText(bccActorsElement);
+        }
+        else {
+          bccActors = XmlUtil.getContentText(bccActorsElement);
+        }
+        templateProperties.setProperty("bcc-actors", bccActors);
       }
 
-      templateVariables = new HashMap();
-      for (Iterator iter = XmlUtil.elementIterator(mailTemplatesElement, "variable"); iter
-        .hasNext();) {
-        Element variableElement = (Element) iter.next();
-        templateVariables.put(variableElement.getAttribute("name"), variableElement
-          .getAttribute("value"));
-      }
+      templatePropertiesMap.put(templateElement.getAttribute("name"), templateProperties);
     }
-    return (Properties) templates.get(templateName);
+    templatePropertiesByResource.put(resource, templatePropertiesMap);
+
+    Map templateVariables = new HashMap();
+    for (Iterator iter = XmlUtil.elementIterator(templatesElement, "variable"); iter.hasNext();) {
+      Element variableElement = (Element) iter.next();
+      templateVariables.put(variableElement.getAttribute("name"), variableElement.getAttribute("value"));
+    }
+    templateVariablesByResource.put(resource, templateVariables);
   }
 
-  private void addTemplateProperty(Element mailTemplateElement, String property,
+  private static void addTemplateProperty(Element templateElement, String property,
     Properties templateProperties) {
-    Element element = XmlUtil.element(mailTemplateElement, property);
+    Element element = XmlUtil.element(templateElement, property);
     if (element != null) {
-      templateProperties.put(property, XmlUtil.getContentText(element));
+      templateProperties.setProperty(property, XmlUtil.getContentText(element));
     }
   }
 
-  private static class MailVariableResolver implements VariableResolver, Serializable {
+  static class MailVariableResolver implements VariableResolver, Serializable {
 
     private Map templateVariables;
     private VariableResolver variableResolver;
 
     private static final long serialVersionUID = 1L;
 
-    public MailVariableResolver(Map templateVariables, VariableResolver variableResolver) {
+    MailVariableResolver(Map templateVariables, VariableResolver variableResolver) {
       this.templateVariables = templateVariables;
       this.variableResolver = variableResolver;
     }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/security/authentication/SubjectAuthenticationService.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/security/authentication/SubjectAuthenticationService.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/security/authentication/SubjectAuthenticationService.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -32,33 +32,32 @@
 
 import org.jbpm.JbpmConfiguration;
 import org.jbpm.JbpmContext;
+import org.jbpm.JbpmException;
 import org.jbpm.security.AuthenticationService;
 import org.jbpm.util.ClassLoaderUtil;
 
 /**
- * gets the authenticated actor id from the current Subject. This Authenticator is either configured
- * via the {@link SubjectAuthenticationServiceFactory} or it requires the two other configuration
- * parameter 'jbpm.authenticator.principal.classname' and
- * 'jbpm.authenticator.principal.allow.overwrite' This configuration property specifies the class
- * name of the principal that should be used from the current subject. This could be for example
- * org.jboss.security.CallerIdentity in an JBoss AS. If not actorId is set, the name of that
- * principal is used as the currently authenticated actorId. If an actorId!=null is set (via
- * setActorId) this one overwrites the principal. This behavior is configurable via the
- * 'jbpm.authenticator.principal.allow.overwrite' attribute. If this is set to false, setActorId is
- * simply ignored.
+ * gets the authenticated actor id from the current Subject. This Authenticator is either
+ * configured via the {@link SubjectAuthenticationServiceFactory} or it requires the two other
+ * configuration parameter 'jbpm.authenticator.principal.classname' and
+ * 'jbpm.authenticator.principal.allow.overwrite' This configuration property specifies the
+ * class name of the principal that should be used from the current subject. This could be for
+ * example org.jboss.security.CallerIdentity in an JBoss AS. If not actorId is set, the name of
+ * that principal is used as the currently authenticated actorId. If an actorId!=null is set
+ * (via setActorId) this one overwrites the principal. This behavior is configurable via the
+ * 'jbpm.authenticator.principal.allow.overwrite' attribute. If this is set to false, setActorId
+ * is simply ignored.
  */
 public class SubjectAuthenticationService implements AuthenticationService {
 
   private static final long serialVersionUID = 1L;
 
-  private static Log log = LogFactory.getLog(JbpmContext.class);
+  private static final Log log = LogFactory.getLog(JbpmContext.class);
 
   private Class principalClass;
-
+  private String actorId;
   private boolean allowActorIdOverwrite;
 
-  private String actorId;
-
   public SubjectAuthenticationService(String principalClassName, Boolean allowActorIdOverwrite) {
     if (principalClassName != null) {
       initPrincipalClass(principalClassName);
@@ -80,20 +79,24 @@
   }
 
   protected void initPrincipalClass(String principalClassName) {
-    this.principalClass = ClassLoaderUtil.classForName(principalClassName);
+    try {
+      principalClass = ClassLoaderUtil.classForName(principalClassName);
+    }
+    catch (ClassNotFoundException e) {
+      throw new JbpmException("principal class not found: " + principalClassName, e);
+    }
   }
 
   public String getActorId() {
     if (actorId == null) {
-
       Subject subject = Subject.getSubject(AccessController.getContext());
       if (subject == null) {
-        log.warn("no javax.security.auth.Subject exists! Cannot set jbpm actorId");
+        log.warn("no subject exists! cannot get actorId");
         return null;
       }
 
       Set principals = subject.getPrincipals(principalClass);
-      if ((principals != null) && (!principals.isEmpty())) {
+      if (principals != null && !principals.isEmpty()) {
         // always use the first one (so be patient what Principal classes are used)
         Principal principal = (Principal) principals.iterator().next();
         actorId = principal.getName();
@@ -110,5 +113,4 @@
 
   public void close() {
   }
-
 }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/util/ClassLoaderUtil.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/util/ClassLoaderUtil.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/util/ClassLoaderUtil.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -29,6 +29,7 @@
 
 import org.jbpm.JbpmConfiguration;
 import org.jbpm.JbpmException;
+import org.jbpm.configuration.ObjectFactory;
 
 /**
  * provides centralized classloader lookup.
@@ -54,16 +55,12 @@
     }
   }
 
-  public static Class classForName(String className) {
-    try {
-      return Class.forName(className, false, getClassLoader());
-    }
-    catch (ClassNotFoundException e) {
-      throw new JbpmException("class not found: " + className, e);
-    }
+  public static Class classForName(String className) throws ClassNotFoundException {
+    return Class.forName(className, false, getClassLoader());
   }
 
-  public static Class classForName(String className, boolean useConfiguredLoader) {
+  public static Class classForName(String className, boolean useConfiguredLoader)
+    throws ClassNotFoundException {
     if (useConfiguredLoader) return classForName(className);
 
     // try context class loader first, so that applications can override provided classes
@@ -72,13 +69,7 @@
     }
     catch (ClassNotFoundException e) {
       // try the class loader of the current class
-      try {
-        return Class.forName(className, false, ClassLoaderUtil.class.getClassLoader());
-      }
-      catch (ClassNotFoundException e2) {
-        // give up
-        throw new JbpmException("class not found: " + className, e2);
-      }
+      return Class.forName(className, false, ClassLoaderUtil.class.getClassLoader());
     }
   }
 
@@ -97,25 +88,22 @@
    * </ul>
    */
   public static ClassLoader getClassLoader() {
-    if (JbpmConfiguration.Configs.hasObject("jbpm.class.loader")) {
-      String jbpmClassLoader = JbpmConfiguration.Configs.getString("jbpm.class.loader");
-
-      if (jbpmClassLoader.equals("jbpm")) {
+    ObjectFactory objectFactory = JbpmConfiguration.Configs.getObjectFactory();
+    if (objectFactory.hasObject("jbpm.class.loader")) {
+      String classLoader = (String) objectFactory.createObject("jbpm.class.loader");
+    
+      if ("jbpm".equals(classLoader)) {
         // use class loader that loaded the jbpm classes
         return ClassLoaderUtil.class.getClassLoader();
       }
-
-      if (jbpmClassLoader.equals("context")) {
+    
+      if (classLoader.equals("context")) {
         // use the context class loader
         return Thread.currentThread().getContextClassLoader();
       }
-
+    
       // interpret value as a reference to a class loader bean
-      Object bean = JbpmConfiguration.Configs.getObject(jbpmClassLoader);
-      if (!(bean instanceof ClassLoader)) {
-        throw new JbpmException("bean '" + jbpmClassLoader + "' is not a class loader");
-      }
-      return (ClassLoader) bean;
+      return (ClassLoader) objectFactory.createObject(classLoader);
     }
     else {
       // behave like before JBPM-1148

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/util/XmlUtil.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/util/XmlUtil.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/util/XmlUtil.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -42,6 +42,7 @@
 
 import org.apache.commons.collections.IteratorUtils;
 import org.apache.commons.collections.Predicate;
+import org.w3c.dom.Attr;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
@@ -101,6 +102,11 @@
     return factory.newDocumentBuilder();
   }
 
+  public static String attribute(Element element, String attrName) {
+    Attr attr = element.getAttributeNode(attrName);
+    return attr != null ? attr.getValue() : null;
+  }
+
   public static Iterator elementIterator(Element element, final String tagName) {
     return IteratorUtils.filteredIterator(new NodeIterator(element), new Predicate() {
       public boolean evaluate(Object arg) {

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/resources/jbpm.cfg.xml
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/resources/jbpm.cfg.xml	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/resources/jbpm.cfg.xml	2010-04-23 07:13:49 UTC (rev 6274)
@@ -1,9 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
 <jbpm-configuration>
-
   <!-- 
     The default configurations can be found in org/jbpm/default.jbpm.cfg.xml 
     Those configurations can be overwritten by putting this file called 
     jbpm.cfg.xml on the root of the classpath and put in the customized values.
   -->
-
 </jbpm-configuration>

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/resources/jbpm.mail.templates.xml
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/resources/jbpm.mail.templates.xml	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/resources/jbpm.mail.templates.xml	2010-04-23 07:13:49 UTC (rev 6274)
@@ -1,5 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
 <mail-templates>
-
   <variable name="BaseTaskListURL" value="http://localhost:8080/jbpm/home?taskId=" />
 
   <mail-template name='task-assign'>
@@ -20,5 +20,4 @@
 Get going !
 ---powered by JBoss jBPM---]]></text>
   </mail-template>
-
 </mail-templates>

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/resources/org/jbpm/default.jbpm.cfg.xml
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/resources/org/jbpm/default.jbpm.cfg.xml	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/resources/org/jbpm/default.jbpm.cfg.xml	2010-04-23 07:13:49 UTC (rev 6274)
@@ -1,5 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
 <jbpm-configuration>
-
   <!--
     This file provides the default jBPM configuration. All available services
     are enabled. Objects described in custom configuration files add to the
@@ -69,9 +69,11 @@
   <bean name="jbpm.date.generator" class="org.example.DateGeneratorImpl" />
   -->
 
-  <!-- email sending properties -->
+  <!-- outgoing mail properties
   <string name="jbpm.mail.smtp.host" value="localhost" />
-  <string name="jbpm.mail.from.address" value="jbpm at noreply" />
+  <int name="jbpm.mail.smtp.port" value="25" />
+  <string name="jbpm.mail.from.address" value="no-reply at jbpm.org" />
+   -->
   <bean name="jbpm.mail.address.resolver" class="org.jbpm.identity.mail.IdentityAddressResolver"
     singleton="true" />
 
@@ -106,5 +108,4 @@
       <int value="60000" />
     </property>
   </bean>
-
 </jbpm-configuration>

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/resources/org/jbpm/jpdl/xml/jpdl-3.2.xsd
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/resources/org/jbpm/jpdl/xml/jpdl-3.2.xsd	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/resources/org/jbpm/jpdl/xml/jpdl-3.2.xsd	2010-04-23 07:13:49 UTC (rev 6274)
@@ -186,8 +186,12 @@
       <xs:attribute name="name" type="xs:string" use="required" />
       <xs:attribute name="async" type="asyncType" default="false" />
       <xs:attribute name="template" type="xs:string" />
+      <xs:attribute name="to" type="xs:string" />
       <xs:attribute name="actors" type="xs:string" />
-      <xs:attribute name="to" type="xs:string" />
+      <xs:attribute name="cc" type="xs:string"></xs:attribute>
+      <xs:attribute name="cc-actors" type="xs:string"></xs:attribute>
+      <xs:attribute name="bcc" type="xs:string"></xs:attribute>
+      <xs:attribute name="bcc-actors" type="xs:string"></xs:attribute>
       <xs:attribute name="subject" type="xs:string" />
       <xs:attribute name="text" type="xs:string" />
     </xs:complexType>
@@ -270,11 +274,15 @@
         <xs:element ref="subject" />
         <xs:element ref="text" />
       </xs:choice>
-      <xs:attribute name="name" type="xs:string" use="required" />
+      <xs:attribute name="name" type="xs:string" />
       <xs:attribute name="async" type="asyncType" default="false" />
       <xs:attribute name="template" type="xs:string" />
+      <xs:attribute name="to" type="xs:string" />
       <xs:attribute name="actors" type="xs:string" />
-      <xs:attribute name="to" type="xs:string" />
+      <xs:attribute name="cc" type="xs:string"></xs:attribute>
+      <xs:attribute name="cc-actors" type="xs:string"></xs:attribute>
+      <xs:attribute name="bcc" type="xs:string"></xs:attribute>
+      <xs:attribute name="bcc-actors" type="xs:string"></xs:attribute>
       <xs:attribute name="subject" type="xs:string" />
       <xs:attribute name="text" type="xs:string" />
       <xs:attribute name="accept-propagated-events" type="booleanType" default="true" />
@@ -400,11 +408,8 @@
 
   <!--  MAIL  -->
   <!--  #### -->
-  <xs:element name="to" type="xs:string" />
-  <xs:element name="recipients" type="xs:string" />
   <xs:element name="subject" type="xs:string" />
   <xs:element name="text" type="xs:string" />
-  <xs:element name="template" type="xs:string" />
 
   <!-- TYPES AND GROUPS -->
   <!-- ################ -->

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/SerializabilityTest.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/SerializabilityTest.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/SerializabilityTest.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -107,20 +107,24 @@
       }
       else if (fileName.endsWith(".class")) {
         String className = packageName + '.' + fileName.substring(0, fileName.length() - 6);
-        assertSerializabilityOfClass(className);
+        assertClassIsSerializable(className);
       }
     }
   }
 
-  private static void assertSerializabilityOfClass(String className) {
-    Class clazz = ClassLoaderUtil.classForName(className);
+  private static void assertClassIsSerializable(String className) {
+    try {
+      Class clazz = Class.forName(className);
 
-    if (!(Serializable.class.isAssignableFrom(clazz)
-      || Modifier.isAbstract(clazz.getModifiers())
-      || isAnonymous(clazz)
-      || isUtility(clazz) || isExcused(className))) {
-      fail(className + " is NOT Serializable");
+      if (!Serializable.class.isAssignableFrom(clazz)
+        && !Modifier.isAbstract(clazz.getModifiers()) && !isAnonymous(clazz)
+        && !isUtility(clazz) && !isExcused(className)) {
+        fail(className + " is NOT Serializable");
+      }
     }
+    catch (ClassNotFoundException e) {
+      fail("no such class: " + className);
+    }
   }
 
   private static boolean isAnonymous(Class clazz) {
@@ -128,8 +132,8 @@
   }
 
   /**
-   * Tells whether the given class consists exclusively of static methods and
-   * has no public constructors.
+   * Tells whether the given class consists exclusively of static methods and has no public
+   * constructors.
    */
   private static boolean isUtility(Class clazz) {
     Method[] methods = clazz.getMethods();

Deleted: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/context/exe/CustomSessionFactoryFactory.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/context/exe/CustomSessionFactoryFactory.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/context/exe/CustomSessionFactoryFactory.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -1,40 +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.context.exe;
-
-import org.hibernate.SessionFactory;
-import org.hibernate.cfg.Configuration;
-
-import org.jbpm.db.hibernate.HibernateHelper;
-import org.jbpm.util.ClassLoaderUtil;
-
-public abstract class CustomSessionFactoryFactory {
-
-  String extraClassMapping = null;
-
-  public static SessionFactory createSessionFactory(String extraClassMapping) {
-    Configuration configuration = HibernateHelper.createConfiguration(null, null);
-    Class clazz = ClassLoaderUtil.classForName(extraClassMapping);
-    configuration.addClass(clazz);
-    return HibernateHelper.createSessionFactory(configuration, false);
-  }
-}

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/jbpm1707/JBPM1707Test.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/jbpm1707/JBPM1707Test.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/jbpm1707/JBPM1707Test.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -32,8 +32,7 @@
 /**
  * Pageflow parsing is slow.
  * 
- * https://jira.jboss.org/jira/browse/JBPM-1707
- * 
+ * @see <a href="https://jira.jboss.org/jira/browse/JBPM-1707">JBPM-1707</a>
  * @author Alejandro Guizar
  */
 public class JBPM1707Test extends AbstractJbpmTestCase {

Added: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/jbpm2852/JBPM2852Test.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/jbpm2852/JBPM2852Test.java	                        (rev 0)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/jbpm2852/JBPM2852Test.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -0,0 +1,90 @@
+/*
+ * 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.jbpm2852;
+
+import org.jbpm.AbstractJbpmTestCase;
+import org.jbpm.JbpmConfiguration;
+import org.jbpm.JbpmContext;
+import org.jbpm.context.exe.ContextInstance;
+import org.jbpm.graph.def.ProcessDefinition;
+import org.jbpm.graph.exe.ProcessInstance;
+import org.jbpm.mail.MailTest;
+
+import com.dumbster.smtp.SimpleSmtpServer;
+import com.dumbster.smtp.SmtpMessage;
+
+/**
+ * CC support in mail nodes and mail templates.
+ * 
+ * @author Alejandro Guizar
+ */
+public class JBPM2852Test extends AbstractJbpmTestCase {
+
+  private JbpmContext jbpmContext;
+  private SimpleSmtpServer smtpServer;
+  private ProcessInstance processInstance;
+
+  private static JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseResource("org/jbpm/jbpm2852/jbpm.cfg.xml");
+
+  protected void setUp() throws Exception {
+    super.setUp();
+    jbpmContext = jbpmConfiguration.createJbpmContext();
+
+    ProcessDefinition processDefinition = ProcessDefinition.parseXmlResource("org/jbpm/jbpm2852/processdefinition.xml");
+    processInstance = new ProcessInstance(processDefinition);
+
+    ContextInstance contextInstance = processInstance.getContextInstance();
+    contextInstance.setVariable("technician", "technician at example.com");
+    contextInstance.setVariable("supervisor", "supervisor at example.com");
+    processInstance.signal();
+
+    smtpServer = MailTest.startSmtpServer(2525);
+  }
+
+  protected void tearDown() throws Exception {
+    smtpServer.stop();
+    jbpmContext.close();
+    super.tearDown();
+  }
+
+  public void testMailNodeInlineCC() {
+    processInstance.signal("high");
+    assertEquals("alert", processInstance.getRootToken().getNode().getName());
+
+    assertEquals(1, smtpServer.getReceivedEmailSize());
+    SmtpMessage message = (SmtpMessage) smtpServer.getReceivedEmail().next();
+    assertEquals("Reactor temperature exceeded threshold", message.getHeaderValue("Subject"));
+    assertEquals("technician at example.com", message.getHeaderValue("To"));
+    assertEquals("supervisor at example.com", message.getHeaderValue("Cc"));
+  }
+
+  public void testMailActionTemplateCC() {
+    processInstance.signal("normal");
+    assertEquals("ok", processInstance.getRootToken().getNode().getName());
+
+    assertEquals(1, smtpServer.getReceivedEmailSize());
+    SmtpMessage message = (SmtpMessage) smtpServer.getReceivedEmail().next();
+    assertEquals("Reactor temperature normal", message.getHeaderValue("Subject"));
+    assertEquals("technician at example.com", message.getHeaderValue("To"));
+    assertEquals("supervisor at example.com", message.getHeaderValue("Cc"));
+  }
+}


Property changes on: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/jbpm2852/JBPM2852Test.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + native

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/mail/MailTest.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/mail/MailTest.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/mail/MailTest.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -3,12 +3,9 @@
 import java.util.Arrays;
 import java.util.Iterator;
 
-import junit.extensions.TestSetup;
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
+import org.jbpm.AbstractJbpmTestCase;
 import org.jbpm.JbpmConfiguration;
-import org.jbpm.db.AbstractDbTestCase;
+import org.jbpm.JbpmContext;
 import org.jbpm.graph.def.ProcessDefinition;
 import org.jbpm.graph.exe.ProcessInstance;
 import org.jbpm.taskmgmt.def.Swimlane;
@@ -17,32 +14,29 @@
 import com.dumbster.smtp.SimpleSmtpServer;
 import com.dumbster.smtp.SmtpMessage;
 
-public class MailTest extends AbstractDbTestCase {
+public class MailTest extends AbstractJbpmTestCase {
 
-  static SimpleSmtpServer server;
-
+  private SimpleSmtpServer smtpServer;
+  private JbpmContext jbpmContext;
   private static final String XML_DECL = "<?xml version='1.0'?>";
 
-  public static Test suite() {
-    return new TestSetup(new TestSuite(MailTest.class)) {
-      protected void setUp() throws Exception {
-        server = startSmtpServer(23583);
-      }
+  private static JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString(XML_DECL
+    + "<jbpm-configuration>"
+    + "  <jbpm-context />"
+    + "  <string name='resource.mail.properties' value='org/jbpm/mail/test.mail.properties' />"
+    + "  <bean name='jbpm.mail.address.resolver' class='"
+    + TestAddressResolver.class.getName()
+    + "' singleton='true' />"
+    + "</jbpm-configuration>");
 
-      protected void tearDown() throws Exception {
-        server.stop();
-      }
-    };
-  }
-
-  static SimpleSmtpServer startSmtpServer(int port) {
+  public static SimpleSmtpServer startSmtpServer(int port) {
     /*
-     * SimpleSmtpServer.start(int) blocks the calling thread until the server socket is created. If
-     * the socket is created too quickly (seems to happen on Linux and Mac) then the notification is
-     * sent too early and the calling thread blocks forever.
+     * SimpleSmtpServer.start(int) blocks the calling thread until the server socket is created.
+     * If the socket is created too quickly (seems to happen on Linux and Mac) then the
+     * notification is sent too early and the calling thread blocks forever.
      * 
-     * The code below corresponds to SimpleSmtpServer.start(int) except that the thread is started
-     * inside of the synchronized block.
+     * The code below corresponds to SimpleSmtpServer.start(int) except that the thread is
+     * started inside of the synchronized block.
      */
     SimpleSmtpServer server = new SimpleSmtpServer(port);
     Thread serverThread = new Thread(server);
@@ -60,20 +54,18 @@
     return server;
   }
 
-  protected JbpmConfiguration getJbpmConfiguration() {
-    if (jbpmConfiguration == null) {
-      jbpmConfiguration = JbpmConfiguration.parseXmlString(XML_DECL +
-          "<jbpm-configuration>" +
-          "  <jbpm-context />" +
-          "  <string name='resource.mail.properties' value='org/jbpm/mail/test.mail.properties' />" +
-          "  <bean name='jbpm.mail.address.resolver' class='" +
-          TestAddressResolver.class.getName() +
-          "' singleton='true' />" +
-          "</jbpm-configuration>");
-    }
-    return jbpmConfiguration;
+  protected void setUp() throws Exception {
+    super.setUp();
+    jbpmContext = jbpmConfiguration.createJbpmContext();
+    smtpServer = startSmtpServer(2525);
   }
 
+  protected void tearDown() throws Exception {
+    smtpServer.stop();
+    jbpmContext.close();
+    super.tearDown();
+  }
+
   public void testWithoutAddressResolving() {
     String to = "sample.shipper at example.domain";
     String subject = "latest news";
@@ -82,11 +74,10 @@
     Mail mail = new Mail(null, null, to, subject, text);
     mail.send();
 
-    assertEquals(1, server.getReceivedEmailSize());
-    Iterator emailIter = server.getReceivedEmail();
-    SmtpMessage email = (SmtpMessage) emailIter.next();
-    emailIter.remove();
+    assertEquals(1, smtpServer.getReceivedEmailSize());
+    Iterator emailIter = smtpServer.getReceivedEmail();
 
+    SmtpMessage email = (SmtpMessage) emailIter.next();
     assertEquals("latest news", email.getHeaderValue("Subject"));
     assertEquals("roy is assurancetourix", email.getBody());
     assertEquals("sample.shipper at example.domain", email.getHeaderValue("To"));
@@ -100,11 +91,10 @@
     Mail mail = new Mail(null, actors, null, subject, text);
     mail.send();
 
-    assertEquals(1, server.getReceivedEmailSize());
-    Iterator emailIter = server.getReceivedEmail();
-    SmtpMessage email = (SmtpMessage) emailIter.next();
-    emailIter.remove();
+    assertEquals(1, smtpServer.getReceivedEmailSize());
+    Iterator emailIter = smtpServer.getReceivedEmail();
 
+    SmtpMessage email = (SmtpMessage) emailIter.next();
     assertEquals("latest news", email.getHeaderValue("Subject"));
     assertEquals("roy is assurancetourix", email.getBody());
     assertEquals("manager at example.domain", email.getHeaderValue("To"));
@@ -118,177 +108,173 @@
     Mail mail = new Mail(null, null, null, null, bcc, subject, text);
     mail.send();
 
-    assertEquals(1, server.getReceivedEmailSize());
-    Iterator emailIter = server.getReceivedEmail();
-    SmtpMessage email = (SmtpMessage) emailIter.next();
-    emailIter.remove();
+    assertEquals(1, smtpServer.getReceivedEmailSize());
+    Iterator emailIter = smtpServer.getReceivedEmail();
 
+    SmtpMessage email = (SmtpMessage) emailIter.next();
     assertEquals("latest news", email.getHeaderValue("Subject"));
     assertEquals("roy is assurancetourix", email.getBody());
     assertNull(email.getHeaderValue("To"));
   }
 
   public void testMailNodeAttributes() {
-    ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(XML_DECL +
-        "<process-definition>" +
-        "  <start-state>" +
-        "    <transition to='send email' />" +
-        "  </start-state>" +
-        "  <mail-node name='send email' actors='george' subject='readmylips' text='nomoretaxes'>" +
-        "    <transition to='end' />" +
-        "  </mail-node>" +
-        "  <end-state name='end' />" +
-        "</process-definition>");
+    ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(XML_DECL
+      + "<process-definition>"
+      + "  <start-state>"
+      + "    <transition to='send email' />"
+      + "  </start-state>"
+      + "  <mail-node name='send email' actors='george' subject='readmylips' text='nomoretaxes'>"
+      + "    <transition to='end' />"
+      + "  </mail-node>"
+      + "  <end-state name='end' />"
+      + "</process-definition>");
     ProcessInstance processInstance = new ProcessInstance(processDefinition);
     processInstance.signal();
 
-    assertEquals(1, server.getReceivedEmailSize());
-    Iterator emailIter = server.getReceivedEmail();
-    SmtpMessage email = (SmtpMessage) emailIter.next();
-    emailIter.remove();
+    assertEquals(1, smtpServer.getReceivedEmailSize());
+    Iterator emailIter = smtpServer.getReceivedEmail();
 
+    SmtpMessage email = (SmtpMessage) emailIter.next();
     assertEquals("readmylips", email.getHeaderValue("Subject"));
     assertEquals("nomoretaxes", email.getBody());
     assertEquals("george at example.domain", email.getHeaderValue("To"));
   }
 
   public void testMailNodeElements() {
-    ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(XML_DECL +
-        "<process-definition>" +
-        "  <start-state>" +
-        "    <transition to='send email' />" +
-        "  </start-state>" +
-        "  <mail-node name='send email' actors='george'>" +
-        "    <subject>readmylips</subject>" +
-        "    <text>nomoretaxes</text>" +
-        "    <transition to='end' />" +
-        "  </mail-node>" +
-        "  <end-state name='end' />" +
-        "</process-definition>");
+    ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(XML_DECL
+      + "<process-definition>"
+      + "  <start-state>"
+      + "    <transition to='send email' />"
+      + "  </start-state>"
+      + "  <mail-node name='send email' actors='george'>"
+      + "    <subject>readmylips</subject>"
+      + "    <text>nomoretaxes</text>"
+      + "    <transition to='end' />"
+      + "  </mail-node>"
+      + "  <end-state name='end' />"
+      + "</process-definition>");
     ProcessInstance processInstance = new ProcessInstance(processDefinition);
     processInstance.signal();
 
-    assertEquals(1, server.getReceivedEmailSize());
-    Iterator emailIter = server.getReceivedEmail();
-    SmtpMessage email = (SmtpMessage) emailIter.next();
-    emailIter.remove();
+    assertEquals(1, smtpServer.getReceivedEmailSize());
+    Iterator emailIter = smtpServer.getReceivedEmail();
 
+    SmtpMessage email = (SmtpMessage) emailIter.next();
     assertEquals("readmylips", email.getHeaderValue("Subject"));
     assertEquals("nomoretaxes", email.getBody());
     assertEquals("george at example.domain", email.getHeaderValue("To"));
   }
 
   public void testMailActionAttributes() {
-    ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(XML_DECL +
-        "<process-definition>" +
-        "  <start-state>" +
-        "    <transition to='end'>" +
-        "      <mail name='send email' actors='george' subject='readmylips' text='nomoretaxes' />" +
-        "    </transition>" +
-        "  </start-state>" +
-        "  <end-state name='end' />" +
-        "</process-definition>");
+    ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(XML_DECL
+      + "<process-definition>"
+      + "  <start-state>"
+      + "    <transition to='end'>"
+      + "      <mail name='send email' actors='george' subject='readmylips' text='nomoretaxes' />"
+      + "    </transition>"
+      + "  </start-state>"
+      + "  <end-state name='end' />"
+      + "</process-definition>");
     ProcessInstance processInstance = new ProcessInstance(processDefinition);
     processInstance.signal();
 
-    assertEquals(1, server.getReceivedEmailSize());
-    Iterator emailIter = server.getReceivedEmail();
-    SmtpMessage email = (SmtpMessage) emailIter.next();
-    emailIter.remove();
+    assertEquals(1, smtpServer.getReceivedEmailSize());
+    Iterator emailIter = smtpServer.getReceivedEmail();
 
+    SmtpMessage email = (SmtpMessage) emailIter.next();
     assertEquals("readmylips", email.getHeaderValue("Subject"));
     assertEquals("nomoretaxes", email.getBody());
     assertEquals("george at example.domain", email.getHeaderValue("To"));
   }
 
   public void testMailActionElements() {
-    ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(XML_DECL +
-        "<process-definition>" +
-        "  <start-state>" +
-        "    <transition to='end'>" +
-        "      <mail actors='george'>" +
-        "        <subject>readmylips</subject>" +
-        "        <text>nomoretaxes</text>" +
-        "      </mail>" +
-        "    <transition to='end' />" +
-        "    </transition>" +
-        "  </start-state>" +
-        "  <end-state name='end' />" +
-        "</process-definition>");
+    ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(XML_DECL
+      + "<process-definition>"
+      + "  <start-state>"
+      + "    <transition to='end'>"
+      + "      <mail actors='george'>"
+      + "        <subject>readmylips</subject>"
+      + "        <text>nomoretaxes</text>"
+      + "      </mail>"
+      + "    <transition to='end' />"
+      + "    </transition>"
+      + "  </start-state>"
+      + "  <end-state name='end' />"
+      + "</process-definition>");
     ProcessInstance processInstance = new ProcessInstance(processDefinition);
     processInstance.signal();
 
-    assertEquals(1, server.getReceivedEmailSize());
-    Iterator emailIter = server.getReceivedEmail();
-    SmtpMessage email = (SmtpMessage) emailIter.next();
-    emailIter.remove();
+    assertEquals(1, smtpServer.getReceivedEmailSize());
+    Iterator emailIter = smtpServer.getReceivedEmail();
 
+    SmtpMessage email = (SmtpMessage) emailIter.next();
     assertEquals("readmylips", email.getHeaderValue("Subject"));
     assertEquals("nomoretaxes", email.getBody());
     assertEquals("george at example.domain", email.getHeaderValue("To"));
   }
 
   public void testMultipleRecipients() {
-    ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(XML_DECL +
-        "<process-definition>" +
-        "  <start-state>" +
-        "    <transition to='end'>" +
-        "      <mail name='send email' actors='george; barbara; suzy'" +
-        " subject='readmylips' text='nomoretaxes' />" +
-        "    </transition>" +
-        "  </start-state>" +
-        "  <end-state name='end' />" +
-        "</process-definition>");
+    ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(XML_DECL
+      + "<process-definition>"
+      + "  <start-state>"
+      + "    <transition to='end'>"
+      + "      <mail name='send email' actors='george; barbara; suzy'"
+      + " subject='readmylips' text='nomoretaxes' />"
+      + "    </transition>"
+      + "  </start-state>"
+      + "  <end-state name='end' />"
+      + "</process-definition>");
     ProcessInstance processInstance = new ProcessInstance(processDefinition);
     processInstance.signal();
 
-    assertEquals(1, server.getReceivedEmailSize());
-    Iterator emailIter = server.getReceivedEmail();
-    SmtpMessage email = (SmtpMessage) emailIter.next();
-    emailIter.remove();
+    assertEquals(1, smtpServer.getReceivedEmailSize());
+    Iterator emailIter = smtpServer.getReceivedEmail();
 
+    SmtpMessage email = (SmtpMessage) emailIter.next();
     assertEquals("readmylips", email.getHeaderValue("Subject"));
     assertEquals("nomoretaxes", email.getBody());
-    String[] expectedTo = { "george at example.domain", "barbara at example.domain",
-        "suzy at example.domain" };
+    String[] expectedTo = {
+      "george at example.domain", "barbara at example.domain", "suzy at example.domain"
+    };
     String[] to = email.getHeaderValues("To");
     assert Arrays.equals(expectedTo, to) : Arrays.asList(to);
   }
 
   public void testMailWithoutAddressResolving() {
-    ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(XML_DECL +
-        "<process-definition>" +
-        "  <start-state>" +
-        "    <transition to='end'>" +
-        "      <mail name='send email' to='george at humpydumpy.gov: spiderman at hollywood.ca.us'" +
-        " subject='readmylips' text='nomoretaxes' />" +
-        "    </transition>" +
-        "  </start-state>" +
-        "  <end-state name='end' />" +
-        "</process-definition>");
+    ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(XML_DECL
+      + "<process-definition>"
+      + "  <start-state>"
+      + "    <transition to='end'>"
+      + "      <mail name='send email' to='george at humpydumpy.gov: spiderman at hollywood.ca.us'"
+      + " subject='readmylips' text='nomoretaxes' />"
+      + "    </transition>"
+      + "  </start-state>"
+      + "  <end-state name='end' />"
+      + "</process-definition>");
     ProcessInstance processInstance = new ProcessInstance(processDefinition);
     processInstance.signal();
 
-    assertEquals(1, server.getReceivedEmailSize());
-    Iterator emailIter = server.getReceivedEmail();
-    SmtpMessage email = (SmtpMessage) emailIter.next();
-    emailIter.remove();
+    assertEquals(1, smtpServer.getReceivedEmailSize());
+    Iterator emailIter = smtpServer.getReceivedEmail();
 
-    String[] expectedTo = { "george at humpydumpy.gov", "spiderman at hollywood.ca.us" };
+    SmtpMessage email = (SmtpMessage) emailIter.next();
+    String[] expectedTo = {
+      "george at humpydumpy.gov", "spiderman at hollywood.ca.us"
+    };
     String[] to = email.getHeaderValues("To");
     assert Arrays.equals(expectedTo, to) : Arrays.asList(to);
   }
 
   public void testToVariableExpression() {
-    ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(XML_DECL +
-        "<process-definition>" +
-        "  <start-state>" +
-        "    <transition to='end'>" +
-        "      <mail name='send email' to='#{user.email}' subject='s' text='t' />" +
-        "    </transition>" +
-        "  </start-state>" +
-        "  <end-state name='end' />" +
-        "</process-definition>");
+    ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(XML_DECL
+      + "<process-definition>"
+      + "  <start-state>"
+      + "    <transition to='end'>"
+      + "      <mail name='send email' to='#{user.email}' subject='s' text='t' />"
+      + "    </transition>"
+      + "  </start-state>"
+      + "  <end-state name='end' />"
+      + "</process-definition>");
 
     User mrNobody = new User("hucklebuck at example.domain");
 
@@ -296,24 +282,23 @@
     processInstance.getContextInstance().setVariable("user", mrNobody);
     processInstance.signal();
 
-    assertEquals(1, server.getReceivedEmailSize());
-    Iterator emailIter = server.getReceivedEmail();
-    SmtpMessage email = (SmtpMessage) emailIter.next();
-    emailIter.remove();
+    assertEquals(1, smtpServer.getReceivedEmailSize());
+    Iterator emailIter = smtpServer.getReceivedEmail();
 
+    SmtpMessage email = (SmtpMessage) emailIter.next();
     assertEquals("hucklebuck at example.domain", email.getHeaderValue("To"));
   }
 
   public void testToSwimlaneExpression() {
-    ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(XML_DECL +
-        "<process-definition>" +
-        "  <start-state>" +
-        "    <transition to='end'>" +
-        "      <mail name='send email' actors='#{initiator}' subject='s' text='t' />" +
-        "    </transition>" +
-        "  </start-state>" +
-        "  <end-state name='end' />" +
-        "</process-definition>");
+    ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(XML_DECL
+      + "<process-definition>"
+      + "  <start-state>"
+      + "    <transition to='end'>"
+      + "      <mail name='send email' actors='#{initiator}' subject='s' text='t' />"
+      + "    </transition>"
+      + "  </start-state>"
+      + "  <end-state name='end' />"
+      + "</process-definition>");
 
     ProcessInstance processInstance = new ProcessInstance(processDefinition);
     Swimlane initiator = new Swimlane("initiator");
@@ -322,57 +307,54 @@
     processInstance.getTaskMgmtInstance().addSwimlaneInstance(initiatorInstance);
     processInstance.signal();
 
-    assertEquals(1, server.getReceivedEmailSize());
-    Iterator emailIter = server.getReceivedEmail();
-    SmtpMessage email = (SmtpMessage) emailIter.next();
-    emailIter.remove();
+    assertEquals(1, smtpServer.getReceivedEmailSize());
+    Iterator emailIter = smtpServer.getReceivedEmail();
 
+    SmtpMessage email = (SmtpMessage) emailIter.next();
     assertEquals("huckelberry at example.domain", email.getHeaderValue("To"));
   }
 
   public void testSubjectExpression() {
-    ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(XML_DECL +
-        "<process-definition>" +
-        "  <start-state>" +
-        "    <transition to='end'>" +
-        "      <mail name='send email' actors='me' subject='your ${item} order' text='t' />" +
-        "    </transition>" +
-        "  </start-state>" +
-        "  <end-state name='end' />" +
-        "</process-definition>");
+    ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(XML_DECL
+      + "<process-definition>"
+      + "  <start-state>"
+      + "    <transition to='end'>"
+      + "      <mail name='send email' actors='me' subject='your ${item} order' text='t' />"
+      + "    </transition>"
+      + "  </start-state>"
+      + "  <end-state name='end' />"
+      + "</process-definition>");
 
     ProcessInstance processInstance = new ProcessInstance(processDefinition);
     processInstance.getContextInstance().setVariable("item", "cookies");
     processInstance.signal();
 
-    assertEquals(1, server.getReceivedEmailSize());
-    Iterator emailIter = server.getReceivedEmail();
-    SmtpMessage email = (SmtpMessage) emailIter.next();
-    emailIter.remove();
+    assertEquals(1, smtpServer.getReceivedEmailSize());
+    Iterator emailIter = smtpServer.getReceivedEmail();
 
+    SmtpMessage email = (SmtpMessage) emailIter.next();
     assertEquals("your cookies order", email.getHeaderValue("Subject"));
   }
 
   public void testTextExpression() {
-    ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(XML_DECL +
-        "<process-definition>" +
-        "  <start-state>" +
-        "    <transition to='end'>" +
-        "      <mail name='send email' actors='me' text='your ${item} order' />" +
-        "    </transition>" +
-        "  </start-state>" +
-        "  <end-state name='end' />" +
-        "</process-definition>");
+    ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(XML_DECL
+      + "<process-definition>"
+      + "  <start-state>"
+      + "    <transition to='end'>"
+      + "      <mail name='send email' actors='me' text='your ${item} order' />"
+      + "    </transition>"
+      + "  </start-state>"
+      + "  <end-state name='end' />"
+      + "</process-definition>");
 
     ProcessInstance processInstance = new ProcessInstance(processDefinition);
     processInstance.getContextInstance().setVariable("item", "cookies");
     processInstance.signal();
 
-    assertEquals(1, server.getReceivedEmailSize());
-    Iterator emailIter = server.getReceivedEmail();
-    SmtpMessage email = (SmtpMessage) emailIter.next();
-    emailIter.remove();
+    assertEquals(1, smtpServer.getReceivedEmailSize());
+    Iterator emailIter = smtpServer.getReceivedEmail();
 
+    SmtpMessage email = (SmtpMessage) emailIter.next();
     assertEquals("your cookies order", email.getBody());
   }
 

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/mail/TaskMailTest.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/mail/TaskMailTest.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/mail/TaskMailTest.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -4,10 +4,6 @@
 import java.util.Iterator;
 import java.util.List;
 
-import junit.extensions.TestSetup;
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
 import org.jbpm.AbstractJbpmTestCase;
 import org.jbpm.JbpmConfiguration;
 import org.jbpm.JbpmContext;
@@ -20,6 +16,7 @@
 import org.jbpm.scheduler.SchedulerService;
 import org.jbpm.svc.Service;
 import org.jbpm.svc.ServiceFactory;
+import org.jbpm.svc.Services;
 import org.jbpm.taskmgmt.def.AssignmentHandler;
 import org.jbpm.taskmgmt.exe.Assignable;
 import org.jbpm.taskmgmt.exe.TaskInstance;
@@ -29,40 +26,35 @@
 import com.dumbster.smtp.SmtpMessage;
 
 public class TaskMailTest extends AbstractJbpmTestCase {
-  private static final int SMTP_PORT = 23583;
 
-  static JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString("<jbpm-configuration>"
+  private JbpmContext jbpmContext;
+  private SimpleSmtpServer smtpServer;
+
+  private static JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString("<jbpm-configuration>"
     + "  <jbpm-context>"
-    + "    <service name='scheduler' factory='org.jbpm.mail.TaskMailTest$TestSchedulerService' />"
+    + "    <service name='scheduler' factory='"
+    + TestSchedulerService.class.getName()
+    + "' />"
     + "  </jbpm-context>"
     + "  <string name='resource.mail.properties' value='org/jbpm/mail/test.mail.properties' />"
-    + "  <bean name='jbpm.mail.address.resolver' class='org.jbpm.mail.MailTest$TestAddressResolver' singleton='true' />"
+    + "  <bean name='jbpm.mail.address.resolver' class='"
+    + MailTest.TestAddressResolver.class.getName()
+    + "' singleton='true' />"
     + "</jbpm-configuration>");
 
-  static SimpleSmtpServer server;
-  private JbpmContext jbpmContext;
-
-  public static Test suite() {
-    return new TestSetup(new TestSuite(TaskMailTest.class)) {
-      protected void setUp() throws Exception {
-        server = MailTest.startSmtpServer(SMTP_PORT);
-      }
-
-      protected void tearDown() throws Exception {
-        server.stop();
-      }
-    };
-  }
-
   protected void setUp() throws Exception {
     super.setUp();
-    TestSchedulerService testSchedulerService = (TestSchedulerService) jbpmConfiguration.getServiceFactory("scheduler");
-    testSchedulerService.reset();
     jbpmContext = jbpmConfiguration.createJbpmContext();
+    smtpServer = MailTest.startSmtpServer(2525);
   }
 
   protected void tearDown() throws Exception {
+    smtpServer.stop();
+
+    TestSchedulerService testSchedulerService = (TestSchedulerService) jbpmContext.getServiceFactory(Services.SERVICENAME_SCHEDULER);
+    testSchedulerService.reset();
     jbpmContext.close();
+
     super.tearDown();
   }
 
@@ -82,7 +74,9 @@
       + "  </start-state>"
       + "  <task-node name='a'>"
       + "    <task name='laundry' notify='yes'>"
-      + "      <assignment class='org.jbpm.mail.TaskMailTest$RoundRobinAssigner' />"
+      + "      <assignment class='"
+      + RoundRobinAssigner.class.getName()
+      + "' />"
       + "    </task>"
       + "    <transition to='b' />"
       + "  </task-node>"
@@ -91,31 +85,27 @@
     ProcessInstance processInstance = new ProcessInstance(processDefinition);
     processInstance.signal();
 
-    assertTrue(server.getReceivedEmailSize() == 1);
-    Iterator emailIter = server.getReceivedEmail();
+    assertTrue(smtpServer.getReceivedEmailSize() == 1);
+    Iterator emailIter = smtpServer.getReceivedEmail();
     SmtpMessage email = (SmtpMessage) emailIter.next();
     emailIter.remove();
 
     assertEquals("you at example.domain", email.getHeaderValue("To"));
     assertEquals("Task 'laundry'", email.getHeaderValue("Subject"));
-    assertEquals(-1, email.getBody().indexOf("#{")); // just to make sure that
-                                                     // all expressions were
-                                                     // resolved
+    // just to make sure that all expressions were resolved
+    assertEquals(-1, email.getBody().indexOf("#{"));
     assertTrue(-1 != email.getBody().indexOf("http://localhost:8080/jbpm/home?taskId=0"));
   }
 
   public static class TestSchedulerService implements SchedulerService, ServiceFactory {
     private static final long serialVersionUID = 1L;
-    List createdTimers = null;
-    List cancelledTimers = null;
 
-    public TestSchedulerService() {
-      reset();
-    }
+    List createdTimers = new ArrayList();
+    List cancelledTimers = new ArrayList();
 
     public void reset() {
-      createdTimers = new ArrayList();
-      cancelledTimers = new ArrayList();
+      createdTimers.clear();
+      cancelledTimers.clear();
     }
 
     public void createTimer(Timer timer) {
@@ -148,7 +138,9 @@
       + "  </start-state>"
       + "  <task-node name='a'>"
       + "    <task name='laundry'>"
-      + "      <assignment class='org.jbpm.mail.TaskMailTest$RoundRobinAssigner' />"
+      + "      <assignment class='"
+      + RoundRobinAssigner.class.getName()
+      + "' />"
       + "      <reminder duedate='0 seconds' repeat='60 seconds' />"
       + "    </task>"
       + "    <transition to='b' />"
@@ -158,7 +150,7 @@
     ProcessInstance processInstance = new ProcessInstance(processDefinition);
     processInstance.signal();
 
-    assertTrue(server.getReceivedEmailSize() == 0);
+    assertTrue(smtpServer.getReceivedEmailSize() == 0);
 
     TestSchedulerService testSchedulerService = (TestSchedulerService) jbpmContext.getServices()
       .getService("scheduler");
@@ -170,16 +162,15 @@
 
     createdTimer.execute(jbpmContext);
 
-    assertTrue(server.getReceivedEmailSize() == 1);
-    Iterator emailIter = server.getReceivedEmail();
+    assertTrue(smtpServer.getReceivedEmailSize() == 1);
+    Iterator emailIter = smtpServer.getReceivedEmail();
     SmtpMessage email = (SmtpMessage) emailIter.next();
     emailIter.remove();
 
     assertEquals("you at example.domain", email.getHeaderValue("To"));
     assertEquals("Task 'laundry' !", email.getHeaderValue("Subject"));
-    assertEquals(-1, email.getBody().indexOf("#{")); // just to make sure that
-                                                     // all expressions were
-                                                     // resolved
+    // just to make sure that all expressions were resolved
+    assertEquals(-1, email.getBody().indexOf("#{"));
     assertTrue(-1 != email.getBody().indexOf("http://localhost:8080/jbpm/home?taskId=0"));
 
     TaskMgmtInstance taskMgmtInstance = processInstance.getTaskMgmtInstance();
@@ -207,7 +198,9 @@
       + "  </start-state>"
       + "  <task-node name='a'>"
       + "    <task name='laundry' notify='true'>"
-      + "      <assignment class='org.jbpm.mail.TaskMailTest$GhostAssigner' />"
+      + "      <assignment class='"
+      + GhostAssigner.class.getName()
+      + "' />"
       + "    </task>"
       + "    <transition to='b' />"
       + "  </task-node>"
@@ -216,7 +209,7 @@
     ProcessInstance processInstance = new ProcessInstance(processDefinition);
     processInstance.signal();
 
-    assertEquals(0, server.getReceivedEmailSize());
+    assertEquals(0, smtpServer.getReceivedEmailSize());
 
     TaskMgmtInstance taskMgmtInstance = processInstance.getTaskMgmtInstance();
     TaskInstance taskInstance = (TaskInstance) taskMgmtInstance.getTaskInstances()
@@ -228,6 +221,6 @@
     assertEquals("ghost", taskInstance.getActorId());
 
     taskInstance.end();
-    assertEquals(0, server.getReceivedEmailSize());
+    assertEquals(0, smtpServer.getReceivedEmailSize());
   }
 }

Added: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/resources/org/jbpm/jbpm2852/gpd.xml
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/resources/org/jbpm/jbpm2852/gpd.xml	                        (rev 0)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/resources/org/jbpm/jbpm2852/gpd.xml	2010-04-23 07:13:49 UTC (rev 6274)
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<root-container name="jbpm2852" width="788" height="568">
+  <node name="start" x="36" y="36" width="121" height="37">
+    <edge>
+      <label x="5" y="-10"/>
+    </edge>
+  </node>
+  <node name="read sensor" x="36" y="120" width="121" height="37">
+    <edge>
+      <label x="-12" y="-22"/>
+    </edge>
+    <edge>
+      <label x="5" y="-10"/>
+    </edge>
+  </node>
+  <node name="contact technician" x="216" y="120" width="133" height="37">
+    <edge>
+      <label x="5" y="-10"/>
+    </edge>
+  </node>
+  <node name="ok" x="36" y="204" width="121" height="37"/>
+  <node name="alert" x="216" y="204" width="133" height="37"/>
+  <deployment serverName="" serverPort="" serverDeployer="">
+    <classesAndResources/>
+    <filesAndFolders>
+      <element value="/jbpm-jpdl/src/test/resources/org/jbpm/jbpm2852/gpd.xml"/>
+      <element value="/jbpm-jpdl/src/test/resources/org/jbpm/jbpm2852/processdefinition.xml"/>
+    </filesAndFolders>
+  </deployment>
+</root-container>


Property changes on: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/resources/org/jbpm/jbpm2852/gpd.xml
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + native

Added: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/resources/org/jbpm/jbpm2852/jbpm.cfg.xml
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/resources/org/jbpm/jbpm2852/jbpm.cfg.xml	                        (rev 0)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/resources/org/jbpm/jbpm2852/jbpm.cfg.xml	2010-04-23 07:13:49 UTC (rev 6274)
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<jbpm-configuration>
+  <jbpm-context />
+  <string name="resource.mail.templates" value="org/jbpm/jbpm2852/mail.templates.xml" />
+  <int name="jbpm.mail.smtp.port" value="2525" />
+</jbpm-configuration>


Property changes on: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/resources/org/jbpm/jbpm2852/jbpm.cfg.xml
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + native

Added: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/resources/org/jbpm/jbpm2852/mail.templates.xml
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/resources/org/jbpm/jbpm2852/mail.templates.xml	                        (rev 0)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/resources/org/jbpm/jbpm2852/mail.templates.xml	2010-04-23 07:13:49 UTC (rev 6274)
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<mail-templates>
+  <mail-template name='a-ok'>
+    <to>${technician}</to>
+    <cc>${supervisor}</cc>
+    <subject>Reactor temperature normal</subject>
+    <text><![CDATA[Keep up the good work!]]></text>
+  </mail-template>
+</mail-templates>


Property changes on: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/resources/org/jbpm/jbpm2852/mail.templates.xml
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + native

Added: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/resources/org/jbpm/jbpm2852/processdefinition.xml
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/resources/org/jbpm/jbpm2852/processdefinition.xml	                        (rev 0)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/resources/org/jbpm/jbpm2852/processdefinition.xml	2010-04-23 07:13:49 UTC (rev 6274)
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<process-definition xmlns="urn:jbpm.org:jpdl-3.2" name="jbpm2852">
+
+  <start-state name="start">
+    <transition to="read sensor" />
+  </start-state>
+
+  <state name="read sensor">
+    <transition to="contact technician" name="high" />
+    <transition to="ok" name="normal">
+      <mail name="reassure supervisor" template="a-ok" />
+    </transition>
+  </state>
+
+  <mail-node name="contact technician" to="${technician}" cc="${supervisor}">
+    <subject>Reactor temperature exceeded threshold</subject>
+    <text>Act fast! We do not want another Chernobyl.</text>
+    <transition to="alert" />
+  </mail-node>
+
+  <end-state name="ok" />
+
+  <end-state name="alert" />
+
+</process-definition>
\ No newline at end of file


Property changes on: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/resources/org/jbpm/jbpm2852/processdefinition.xml
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + native

Added: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/resources/org/jbpm/jpdl/xml/.gpd.testSimpleSchemaReference.xml
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/resources/org/jbpm/jpdl/xml/.gpd.testSimpleSchemaReference.xml	                        (rev 0)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/resources/org/jbpm/jpdl/xml/.gpd.testSimpleSchemaReference.xml	2010-04-23 07:13:49 UTC (rev 6274)
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<root-container/>
\ No newline at end of file


Property changes on: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/resources/org/jbpm/jpdl/xml/.gpd.testSimpleSchemaReference.xml
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + native

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/resources/org/jbpm/mail/test.mail.properties
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/resources/org/jbpm/mail/test.mail.properties	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/resources/org/jbpm/mail/test.mail.properties	2010-04-23 07:13:49 UTC (rev 6274)
@@ -1,2 +1,2 @@
 mail.smtp.host = localhost
-mail.smtp.port = 23583
\ No newline at end of file
+mail.smtp.port = 2525
\ No newline at end of file

Modified: jbpm3/branches/jbpm-3.2-soa/modules/examples/src/test/java/org/jbpm/examples/mail/MailTest.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/examples/src/test/java/org/jbpm/examples/mail/MailTest.java	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/examples/src/test/java/org/jbpm/examples/mail/MailTest.java	2010-04-23 07:13:49 UTC (rev 6274)
@@ -21,10 +21,6 @@
  */
 package org.jbpm.examples.mail;
 
-import junit.extensions.TestSetup;
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
 import org.jbpm.AbstractJbpmTestCase;
 import org.jbpm.JbpmConfiguration;
 import org.jbpm.JbpmContext;
@@ -33,68 +29,45 @@
 import org.jbpm.mail.AddressResolver;
 
 import com.dumbster.smtp.SimpleSmtpServer;
+import com.dumbster.smtp.SmtpMessage;
 
 public class MailTest extends AbstractJbpmTestCase {
 
-  static SimpleSmtpServer server;
-  private static final String XML_DECL = "<?xml version='1.0'?>";
+  private JbpmContext jbpmContext;
+  private SimpleSmtpServer smtpServer;
 
-  public static Test suite() {
-    return new TestSetup(new TestSuite(MailTest.class)) {
-      protected void setUp() throws Exception {
-        server = startSmtpServer(23583);
-      }
+  private static JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseResource("mail/jbpm.cfg.xml");
 
-      protected void tearDown() throws Exception {
-        server.stop();
-      }
-    };
+  protected void setUp() throws Exception {
+    super.setUp();
+    jbpmContext = jbpmConfiguration.createJbpmContext();
+    smtpServer = startSmtpServer(2525);
   }
 
+  protected void tearDown() throws Exception {
+    smtpServer.stop();
+    jbpmContext.close();
+    super.tearDown();
+  }
+
   public void testSimpleProcess() throws Exception {
-    JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString(XML_DECL +
-        "<jbpm-configuration>" +
-        "  <jbpm-context />" +
-        "  <string name='resource.mail.properties' value='mail/mail.properties' />" +
-        "  <bean name='jbpm.mail.address.resolver' class='" +
-        MyAddressResolver.class.getName() +
-        "' singleton='true' />" +
-        "</jbpm-configuration>");
+    ProcessDefinition processDefinition = ProcessDefinition.parseXmlResource("mail/processdefinition.xml");
+    ProcessInstance processInstance = new ProcessInstance(processDefinition);
+    processInstance.signal();
 
-    JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
-    try {
-      ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(XML_DECL +
-          "<process-definition name='mailtest'>" +
-          "  <start-state name='start'>" +
-          "    <transition to='start toothpick line' />" +
-          "  </start-state>" +
-          "  <task-node name='start toothpick line'>" +
-          "    <task notify='yes'>" +
-          "      <assignment actor-id='grandma' />" +
-          "    </task>" +
-          "    <transition to='end' />" +
-          "  </task-node>" +
-          "  <end-state name='end' />" +
-          "</process-definition>");
-      ProcessInstance processInstance = new ProcessInstance(processDefinition);
-      processInstance.signal();
-      jbpmContext.save(processInstance);
-    }
-    finally {
-      jbpmContext.close();
-    }
-
-    assertEquals(1, server.getReceivedEmailSize());
+    assertEquals(1, smtpServer.getReceivedEmailSize());
+    SmtpMessage smtpMessage = (SmtpMessage) smtpServer.getReceivedEmail().next();
+    assertEquals("grandma at dalton.com", smtpMessage.getHeaderValue("To"));
   }
 
   static SimpleSmtpServer startSmtpServer(int port) {
     /*
-     * SimpleSmtpServer.start(int) blocks the calling thread until the server socket is created. If
-     * the socket is created too quickly (happens on Linux and Mac) then the notification is sent
-     * too early and the calling thread blocks forever.
+     * SimpleSmtpServer.start(int) blocks the calling thread until the server socket is created.
+     * If the socket is created too quickly (happens on Linux and Mac) then the notification is
+     * sent too early and the calling thread blocks forever.
      * 
-     * The code below corresponds to SimpleSmtpServer.start(int) except that the thread is started
-     * inside of the synchronized block.
+     * The code below corresponds to SimpleSmtpServer.start(int) except that the thread is
+     * started inside of the synchronized block.
      */
     SimpleSmtpServer server = new SimpleSmtpServer(port);
     Thread serverThread = new Thread(server);

Added: jbpm3/branches/jbpm-3.2-soa/modules/examples/src/test/resources/mail/gpd.xml
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/examples/src/test/resources/mail/gpd.xml	                        (rev 0)
+++ jbpm3/branches/jbpm-3.2-soa/modules/examples/src/test/resources/mail/gpd.xml	2010-04-23 07:13:49 UTC (rev 6274)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<root-container name="mail" width="788" height="568">
+  <node name="start" x="36" y="24" width="133" height="37">
+    <edge>
+      <label x="5" y="-10"/>
+    </edge>
+  </node>
+  <node name="start toothpick line" x="36" y="96" width="133" height="37">
+    <edge>
+      <label x="5" y="-10"/>
+    </edge>
+  </node>
+  <node name="end" x="36" y="168" width="133" height="37"/>
+  <deployment serverName="" serverPort="" serverDeployer="">
+    <classesAndResources/>
+    <filesAndFolders>
+      <element value="/jbpm-examples/src/test/resources/mail/gpd.xml"/>
+      <element value="/jbpm-examples/src/test/resources/mail/mail.properties"/>
+      <element value="/jbpm-examples/src/test/resources/mail/processdefinition.xml"/>
+    </filesAndFolders>
+  </deployment>
+</root-container>


Property changes on: jbpm3/branches/jbpm-3.2-soa/modules/examples/src/test/resources/mail/gpd.xml
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + native

Added: jbpm3/branches/jbpm-3.2-soa/modules/examples/src/test/resources/mail/jbpm.cfg.xml
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/examples/src/test/resources/mail/jbpm.cfg.xml	                        (rev 0)
+++ jbpm3/branches/jbpm-3.2-soa/modules/examples/src/test/resources/mail/jbpm.cfg.xml	2010-04-23 07:13:49 UTC (rev 6274)
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<jbpm-configuration>
+  <jbpm-context />
+  <int name="jbpm.mail.smtp.port" value="2525" />
+  <bean name="jbpm.mail.address.resolver" class="org.jbpm.examples.mail.MailTest$MyAddressResolver"
+    singleton="true" />
+</jbpm-configuration>
\ No newline at end of file


Property changes on: jbpm3/branches/jbpm-3.2-soa/modules/examples/src/test/resources/mail/jbpm.cfg.xml
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + native

Deleted: jbpm3/branches/jbpm-3.2-soa/modules/examples/src/test/resources/mail/mail.properties
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/examples/src/test/resources/mail/mail.properties	2010-04-21 19:12:33 UTC (rev 6273)
+++ jbpm3/branches/jbpm-3.2-soa/modules/examples/src/test/resources/mail/mail.properties	2010-04-23 07:13:49 UTC (rev 6274)
@@ -1,2 +0,0 @@
-mail.smtp.host	localhost
-mail.smtp.port	23583
\ No newline at end of file

Added: jbpm3/branches/jbpm-3.2-soa/modules/examples/src/test/resources/mail/processdefinition.xml
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/examples/src/test/resources/mail/processdefinition.xml	                        (rev 0)
+++ jbpm3/branches/jbpm-3.2-soa/modules/examples/src/test/resources/mail/processdefinition.xml	2010-04-23 07:13:49 UTC (rev 6274)
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<process-definition name='mail'>
+  <start-state name='start'>
+    <transition to='start toothpick line' />
+  </start-state>
+  <task-node name='start toothpick line'>
+    <task notify='yes'>
+      <assignment actor-id='grandma' />
+    </task>
+    <transition to='end' />
+  </task-node>
+  <end-state name='end' />
+</process-definition>


Property changes on: jbpm3/branches/jbpm-3.2-soa/modules/examples/src/test/resources/mail/processdefinition.xml
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + native

Added: jbpm3/branches/jbpm-3.2-soa/modules/examples/src/test/resources/mail/processimage.jpg
===================================================================
(Binary files differ)


Property changes on: jbpm3/branches/jbpm-3.2-soa/modules/examples/src/test/resources/mail/processimage.jpg
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream



More information about the jbpm-commits mailing list