[jboss-svn-commits] JBL Code SVN: r23714 - in labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product: services/jbrules/lib/ext and 14 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Wed Nov 5 08:39:41 EST 2008


Author: beve
Date: 2008-11-05 08:39:40 -0500 (Wed, 05 Nov 2008)
New Revision: 23714

Added:
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/lib/ext/mvel-1.3.1-java1.4.jar
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/lib/ext/drools-compiler-4.0.7.jar
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/lib/ext/drools-core-4.0.7.jar
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/lib/ext/drools-decisiontables-4.0.7.jar
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/lib/ext/drools-jsr94-4.0.7.jar
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/lib/ext/stax-api-1.0.1.jar
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/lib/ext/xstream-1.2.2.jar
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleBaseHelper.java
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleService.java
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleServiceBuilderException.java
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleServiceCallHelper.java
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleServiceException.java
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleServiceFactory.java
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/soa/esb/services/
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/soa/esb/services/rules/
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/soa/esb/services/rules/RuleService.java
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/soa/esb/services/rules/RuleServicePropertiesNames.java
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/routing/cbr/DslHelperUnitTest.java
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/rules/
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleBaseHelperUnitTest.java
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleServiceUnitTest.java
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/BusinessRulesProcessorUnitTest.java
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/CBRConfigTreeBuilder.java
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/ContentBasedRouterUnitTest.java
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/ContentBasedRouterUnitTest.xml
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/ContentBasedWiretapUnitTest.java
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/ContentBasedWiretapUnitTest.xml
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/Counter.java
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/MessageFilterUnitTest.java
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/MessageFilterUnitTest.xml
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/5KBNS_message.xml
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/5KB_message.xml
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/JBossESBPricingRulesStateful.drl
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/RuleBaseHelper.drl
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/RuleBaseHelper.properties
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/RuleBaseHelper.xls
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/RulesWithDsl.drl
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/RulesWithDslNS.drl
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/testrules.pkg
Removed:
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/lib/ext/mvel14-1.2rc4rv908.jar
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/lib/ext/drools-compiler-4.0.2.jar
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/lib/ext/drools-core-4.0.2.jar
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/lib/ext/drools-decisiontables-4.0.2.jar
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/lib/ext/drools-jsr94-4.0.2.jar
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/jbrules/
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/routing/cbr/BusinessProcessorRoutingUnitTest.java
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/routing/cbr/BusinessProcessorUnitTest.java
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/services/
Modified:
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/routing/cbr/DslHelper.java
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/routing/cbr/JBRulesCounter.java
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/routing/cbr/JBossRulesRouter.java
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/soa/esb/actions/BusinessRulesProcessor.java
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/soa/esb/actions/ContentBasedWiretap.java
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/resources/XPathLanguage.dsl
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/routing/cbr/JBossRulesRouterUnitTest.java
   labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/JBossESBRules.drl
Log:
Work for https://jira.jboss.org/jira/browse/JBESB-2152 "CBR using rules has poor performance".


Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/lib/ext/mvel-1.3.1-java1.4.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/lib/ext/mvel-1.3.1-java1.4.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Deleted: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/lib/ext/mvel14-1.2rc4rv908.jar
===================================================================
(Binary files differ)

Deleted: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/lib/ext/drools-compiler-4.0.2.jar
===================================================================
(Binary files differ)

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/lib/ext/drools-compiler-4.0.7.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/lib/ext/drools-compiler-4.0.7.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Deleted: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/lib/ext/drools-core-4.0.2.jar
===================================================================
(Binary files differ)

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/lib/ext/drools-core-4.0.7.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/lib/ext/drools-core-4.0.7.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Deleted: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/lib/ext/drools-decisiontables-4.0.2.jar
===================================================================
(Binary files differ)

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/lib/ext/drools-decisiontables-4.0.7.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/lib/ext/drools-decisiontables-4.0.7.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Deleted: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/lib/ext/drools-jsr94-4.0.2.jar
===================================================================
(Binary files differ)

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/lib/ext/drools-jsr94-4.0.7.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/lib/ext/drools-jsr94-4.0.7.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/lib/ext/stax-api-1.0.1.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/lib/ext/stax-api-1.0.1.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/lib/ext/xstream-1.2.2.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/lib/ext/xstream-1.2.2.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Modified: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/routing/cbr/DslHelper.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/routing/cbr/DslHelper.java	2008-11-05 12:54:27 UTC (rev 23713)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/routing/cbr/DslHelper.java	2008-11-05 13:39:40 UTC (rev 23714)
@@ -23,6 +23,11 @@
 
 import java.io.ByteArrayInputStream;
 import java.io.StringReader;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.WeakHashMap;
+import java.util.Map.Entry;
 
 import javax.xml.xpath.XPath;
 import javax.xml.xpath.XPathConstants;
@@ -30,178 +35,638 @@
 import javax.xml.xpath.XPathFactory;
 
 import org.apache.log4j.Logger;
+import org.jboss.internal.soa.esb.assertion.AssertArgument;
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.listeners.message.MessageDeliverException;
 import org.jboss.soa.esb.message.Message;
 import org.jboss.soa.esb.message.MessagePayloadProxy;
 import org.jboss.soa.esb.message.body.content.BytesBody;
-import org.jboss.soa.esb.helpers.ConfigTree;
-import org.jboss.soa.esb.listeners.message.MessageDeliverException;
+import org.jboss.soa.esb.util.XPathNamespaceContext;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
 import org.xml.sax.InputSource;
 
 /**
  * Domain Specific Language helper. Right now this supports the use of XPath, but this class can
  * be beefed up upo to use other technologies as well.
+ * <p/>
  * 
  * @author kstam at redhat.com
+ * @author <a href="mailto:dbevenius at redhat.com">Daniel Bevenius</a>
  *
  */
 public class DslHelper 
 {
 	private static Logger log = Logger.getLogger(DslHelper.class);
+	
 	/** XPath instance */
 	private static XPathFactory xpf = XPathFactory.newInstance();
     private static MessagePayloadProxy payloadProxy;
+    
+    /* 
+     * Maps that contain cached XPath results.
+     * K = XPath expression String
+     * V = {@link XPathCacheObject}
+     */
+	private static Map<String,XPathCacheObject<Boolean>> xpathBooleanResults = Collections.synchronizedMap( new WeakHashMap<String,XPathCacheObject<Boolean>>() );
+	private static Map<String,XPathCacheObject<Number>> xpathNumberResults = Collections.synchronizedMap( new WeakHashMap<String,XPathCacheObject<Number>>() );
+	private static Map<String,XPathCacheObject<String>> xpathStringResults = Collections.synchronizedMap( new WeakHashMap<String,XPathCacheObject<String>>() );
+	private static Map<String,XPathCacheObject<Node>> xpathNodeResults = Collections.synchronizedMap( new WeakHashMap<String,XPathCacheObject<Node>>() );
+	private static Map<String,XPathCacheObject<NodeList>> xpathNodeListResults = Collections.synchronizedMap( new WeakHashMap<String,XPathCacheObject<NodeList>>() );
 
     static {
-        payloadProxy = new MessagePayloadProxy(new ConfigTree("config"),
-                      new String[] {BytesBody.BYTES_LOCATION},
-                      new String[] {BytesBody.BYTES_LOCATION});
+        payloadProxy = new MessagePayloadProxy(new ConfigTree("config"), new String[] {BytesBody.BYTES_LOCATION}, new String[] {BytesBody.BYTES_LOCATION});
     }
-
+    
     /**
+	 * Uses XPath to evalutate if the XPath expression is true or false. 
+	 * This is the equivalent of calling selectAsBoolean( message, xpathExp, null). 
+	 * 
+	 * @param message -
+	 * 				the ESB Message which body content will be used
+	 * @param xpathExp -
+	 * 				XPath expression 
+	 * @return Boolean 
+	 * 				true if the XPath expression evalutes to true
+	 * @throws XPathExpressionException
+	 * 				represents an error in an XPath expression
+	 */
+    public static Boolean selectAsBoolean(final Message message, final String xpathExp ) throws XPathExpressionException
+    {
+    	return selectAsBoolean( message, xpathExp, null );
+    }
+    
+    /**
+	 * Uses XPath to evalutate if the XPath expression is true or false. 
+	 * 
+	 * @param message -
+	 * 				the ESB Message which body content will be used
+	 * @param xpathExp -
+	 * 				XPath expression 
+	 * @return Boolean 
+	 * 				true if the XPath expression evalutes to true
+	 * @param namespaces -
+	 * 				Map of namespaces to be used in the xpath expression. Key=prefix,value = uri
+	 * @throws XPathExpressionException
+	 * 				represents an error in an XPath expression
+	 */
+    public static Boolean selectAsBoolean(final Message message, final String xpathExp, final Map<String,String> namespaces ) throws XPathExpressionException
+	{
+		XPathCacheObject<Boolean> cachedObject = xpathBooleanResults.get( xpathExp );
+		if ( cacheHit( cachedObject, message ) )
+			return cachedObject.getResult();
+		
+		XPath xpath = getXPath( namespaces );
+		Boolean value = (Boolean) xpath.evaluate( xpathExp, getInputSource(message), XPathConstants.BOOLEAN);
+		xpathBooleanResults.put( xpathExp, new XPathCacheObject<Boolean>( message.hashCode(), value ) );
+		return value;
+	}
+    
+    /**
+	 * Uses XPath to select the Number matched by the XPath expression. 
+	 * <p/>
+	 * This is the equivalent of calling selectAsNumber( message, xpathExp, null). 
+	 * 
+	 * @param message -
+	 * 				the ESB Message which body content will be used
+	 * @param xpathExp -
+	 * 				XPath expression 
+     * @return Number -
+     * 				the Number if XPath found a match, or null if no match was found.
+     * @throws XPathExpressionException
+	 * 				represents an error in an XPath expression
+     */
+    public static Number selectAsNumber(final Message message, final String xpathExp ) throws XPathExpressionException
+    {
+    	return selectAsNumber( message, xpathExp, null );
+    }
+    
+    /**
+	 * Uses XPath to select the Number matched by the XPath expression. 
+	 * 
+	 * @param message -
+	 * 				the ESB Message which body content will be used
+	 * @param xpathExp -
+	 * 				XPath expression 
+	 * @param namespaces -
+	 * 				Map of namespaces to be used in the xpath expression. Key=prefix,value = uri
+     * @return Number -
+     * 				the Number if XPath found a match, or null if no match was found.
+     * @throws XPathExpressionException
+	 * 				represents an error in an XPath expression
+     */
+    public static Number selectAsNumber(final Message message, final String xpathExp, final Map<String,String> namespaces ) throws XPathExpressionException
+	{
+		final XPathCacheObject<Number> cachedObject = xpathNumberResults.get( xpathExp );
+		if ( cacheHit( cachedObject, message ) )
+			return cachedObject.getResult();
+		
+		final XPath xpath = getXPath( namespaces );
+		final Number number = (Number) xpath.evaluate( xpathExp, getInputSource(message), XPathConstants.NUMBER);
+		xpathNumberResults.put( xpathExp, new XPathCacheObject<Number>( message.hashCode(), number ) );
+		return number;
+	}
+    
+    /**
+	 * Uses XPath to select the String matched by the XPath expression. 
+	 * <p/>
+	 * This is the equivalen of calling selectAsString( message, xpathExp, null). 
+	 * 
+	 * @param message -
+	 * 				the ESB Message which body content will be used
+	 * @param xpathExp -
+	 * 				XPath expression 
+     * @return String -
+     * 				the String if XPath found a match, or null if no match was found.
+     * @throws XPathExpressionException
+	 * 				represents an error in an XPath expression
+     */
+    public static String selectAsString(final Message message, final String xpathExp ) throws XPathExpressionException
+    {
+    	return selectAsString( message, xpathExp, null );
+    }
+    
+    /**
+	 * Uses XPath to select the String matched by the XPath expression. 
+	 * 
+	 * @param message -
+	 * 				the ESB Message which body content will be used
+	 * @param xpathExp -
+	 * 				XPath expression 
+	 * @param namespaces -
+	 * 				Map of namespaces to be used in the xpath expression. Key=prefix,value = uri
+     * @return String -
+     * 				the String if XPath found a match, or null if no match was found.
+     * @throws XPathExpressionException
+	 * 				represents an error in an XPath expression
+     */
+    public static String selectAsString(final Message message, final String xpathExp, final Map<String,String> namespaces ) throws XPathExpressionException
+    {
+		final XPathCacheObject<String> cachedObject = xpathStringResults.get( xpathExp );
+		if ( cacheHit( cachedObject, message ) )
+			return cachedObject.getResult();
+		
+		final XPath xpath = getXPath( namespaces );
+		final String string = (String) xpath.evaluate( xpathExp, getInputSource(message), XPathConstants.STRING);
+		xpathStringResults.put( xpathExp, new XPathCacheObject<String>( message.hashCode(), string ) );
+		return string;
+	}
+    
+    
+    /**
+	 * Uses XPath to select the Node matched by the XPath expression. 
+	 * <p/>
+	 * This is the equivalent of calling selectAsNode( message, xpathExp null). 
+	 * 
+	 * @param message -
+	 * 				the ESB Message which body content will be used
+	 * @param xpathExp -
+	 * 				XPath expression 
+     * @return Node -
+     * 				the Node if XPath found a match, or null if no match was found.
+     * @throws XPathExpressionException
+	 * 				represents an error in an XPath expression
+     */
+    public static Node selectAsNode(final Message message, final String xpathExp ) throws XPathExpressionException
+    {
+    	return selectAsNode( message, xpathExp, null );
+    }
+    
+    /**
+	 * Uses XPath to select the Node matched by the XPath expression. 
+	 * <p/>
+	 * 
+	 * @param message -
+	 * 				the ESB Message which body content will be used
+	 * @param xpathExp -
+	 * 				XPath expression 
+	 * @param namespaces -
+	 * 				Map of namespaces to be used in the xpath expression. Key=prefix,value = uri
+     * @return Node -
+     * 				the Node if XPath found a match, or null if no match was found.
+     * @throws XPathExpressionException
+	 * 				represents an error in an XPath expression
+     */
+    public static Node selectAsNode(final Message message, final String xpathExp, final Map<String,String> namespaces ) throws XPathExpressionException
+	{
+		final XPathCacheObject<Node> cachedObject = xpathNodeResults.get( xpathExp );
+		if ( cacheHit( cachedObject, message ) )
+			return cachedObject.getResult();
+		
+		final XPath xpath = getXPath( namespaces );
+		final Node node = (Node) xpath.evaluate( xpathExp, getInputSource(message), XPathConstants.NODE);
+		xpathNodeResults.put( xpathExp, new XPathCacheObject<Node>( message.hashCode(), node ) );
+		return node;
+	}
+    
+    /**
+	 * Uses XPath to select the NodeList matched by the XPath expression. 
+	 * <p/>
+	 * This is the equivalent of calling selectAsNodeList( message, xpathExp null). 
+	 * 
+	 * @param message -
+	 * 				the ESB Message which body content will be used
+	 * @param xpathExp -
+	 * 				XPath expression 
+     * @return NodeList -
+     * 				the NodeList if XPath found a match, or null if no match was found.
+     * @throws XPathExpressionException
+	 * 				represents an error in an XPath expression
+     */
+    public static NodeList selectAsNodeList( final Message message, final String xpathExp ) throws XPathExpressionException
+    {
+    	return selectAsNodeList( message, xpathExp, null );
+    }
+    
+    /**
+	 * Uses XPath to select the NodeList matched by the XPath expression. 
+	 * <p/>
+	 * 
+	 * @param message -
+	 * 				the ESB Message which body content will be used
+	 * @param xpathExp -
+	 * 				XPath expression 
+	 * @param namespaces -
+	 * 				Map of namespaces to be used in the xpath expression. Key=prefix,value = uri
+     * @return NodeList -
+     * 				the NodeList if XPath found a match, or null if no match was found.
+     * @throws XPathExpressionException
+	 * 				represents an error in an XPath expression
+     */
+    public static NodeList selectAsNodeList( final Message message, final String xpathExp, Map<String,String> namespaces ) throws XPathExpressionException
+	{
+		final XPathCacheObject<NodeList> cachedObject = xpathNodeListResults.get( xpathExp );
+		if ( cacheHit( cachedObject, message ) )
+			return cachedObject.getResult();
+		
+		final XPath xpath = getXPath( namespaces );
+		final NodeList nodeList = (NodeList) xpath.evaluate(xpathExp, getInputSource(message), XPathConstants.NODESET);
+		log.info("XPath [" + xpathExp + "], nr of matches : " + nodeList.getLength());
+		xpathNodeListResults.put( xpathExp, new XPathCacheObject<NodeList>( message.hashCode(), nodeList ) );
+		return nodeList;
+	}
+    
+    /**
+	 * Uses XPath to look for the occurence of a certain node, specified in the XPath expression.
+	 * This can be used to find out if the Message object contains the node specified by the XPath
+	 * expression. 
+	 * <p/>
+	 * This is the equivalent of calling xmlContentMatches( message, xpathExp, null). 
+	 * 
+	 * @param message - 
+	 * 				the ESB Message which body content will be used.
+	 * @param xpathExp -
+	 * 				XPath expression to find a node.
+	 * @return true 
+	 * 				if the node is found and false in all other cases.
+	 * @throws XPathExpressionException
+	 * 				represents an error in an XPath expression
+	 */
+	public static boolean xmlContentMatches(final Message message, final String xpathExp) throws XPathExpressionException 
+	{
+		return xmlContentMatches( message, xpathExp, null );
+	}
+	
+    /**
+	 * Uses XPath to look for the occurence of a certain node, specified in the XPath expression.
+	 * This can be used to find out if the Message object contains the node specified by the XPath
+	 * expression. 
+	 * 
+	 * @param message - 
+	 * 				the ESB Message which body content will be used.
+	 * @param xpathExp -
+	 * 				XPath expression to find a node.
+	 * @param namespaces -
+	 * 				Map of namespaces to be used in the xpath expression. Key=prefix,value = uri
+	 * @return true 
+	 * 				if the node is found and false in all other cases.
+	 * @throws XPathExpressionException
+	 * 				represents an error in an XPath expression
+	 */
+	public static boolean xmlContentMatches(final Message message, final String xpathExp, final Map<String,String> namespaces ) throws XPathExpressionException 
+	{
+        return selectAsNode( message, xpathExp, namespaces ) != null ;
+	}
+	
+	/**
+	 * Uses XPath to look for any occurence of a certain tag, specific in the xpath expression.
+	 * This can be used to find out if the Message object contains the node specified by the XPath
+	 * Note, that this method cannot be used with a boolean expression, use {@link #selectAsBoolean(Message, String)}
+	 * for that.
+	 * <p/>
+	 * This is the equivalent of calling xmlContentExists( message, xpathExp, null). 
+	 *
+	 * @param message - 
+	 * 				the ESB Message which body content will be used.
+	 * @param xpathExp -
+	 * 				XPath expression to find a node.
+	 * @return true 
+	 * 				if one or more nodes are found and false in all other cases.
+	 * @throws XPathExpressionException
+	 * 				represents an error in an XPath expression
+	 */
+	public static boolean xmlContentExists(final Message message, final String xpathExp) throws XPathExpressionException
+	{
+		return xmlContentExists( message, xpathExp, null );
+	}
+	
+    /**
+	 * Uses XPath to look for any occurence of a certain tag, specific in the xpath expression.
+	 * This can be used to find out if the Message object contains the node specified by the XPath
+	 * Note, that this method cannot be used with a boolean expression, use {@link #selectAsBoolean(Message, String)}
+	 * for that.
+	 *
+	 * @param message - 
+	 * 				the ESB Message which body content will be used.
+	 * @param xpathExp -
+	 * 				XPath expression to find a node.
+	 * @param namespaces -
+	 * 				Map of namespaces to be used in the xpath expression. Key=prefix,value = uri
+	 * @return true 
+	 * 				if one or more nodes are found and false in all other cases.
+	 * @throws XPathExpressionException
+	 * 				represents an error in an XPath expression
+	 */
+	public static boolean xmlContentExists(final Message message, final String xpathExp, final Map<String,String> namespaces ) throws XPathExpressionException
+	{
+		final NodeList nodeList = selectAsNodeList( message, xpathExp, namespaces );
+		return nodeList == null ? false : nodeList.getLength() > 0 ;
+	}
+	
+	/**
 	 * Uses XPath to look for the occurence of a certain tag, specific in the xpath expression.
+	 * </p>
+	 * Note that {@link #selectAsBoolean(Message, String)} can be used instead of this method
+	 * and the XPath equality operator can be used in the XPath expression:
+	 * <br> 
+	 * <pre>{@code
+	 * String xpathExp = "/Order/OrderLines/OrderLine/Product/@productId = 364";
+	 * }</pre>
+	 * <br> 
+	 * <p/>
+	 * This is the equivalent of calling xmlContentEquals( message, xpathExp, null). 
 	 * 
-	 * @param message - the ESB Message which body content will be used.
-	 * @param xpathExp - XPath expression to find a node.
-	 * @return true if the node is found and false in all other cases.
+	 * @param message - 
+	 * 			the ESB Message which body content will be used.
+	 * @param xpathExp -
+	 * 			XPath expression to find a node.
+	 * @return true -
+	 * 			if the node is found and false in all other cases.
 	 * @throws XPathExpressionException
+	 * 			represents an error in an XPath expression
 	 */
-	public static boolean xmlContentMatches(Message message, String xpathExp) throws XPathExpressionException 
+	public static boolean xmlContentEquals(final Message message, final String xpathExp, final String value ) throws XPathExpressionException
 	{
-		if (log.isDebugEnabled()) {
-			log.debug("Trying to match xpath: '" + xpathExp +  "' in message=" + message);
-		}
-		XPath xpath = xpf.newXPath();
-        InputSource inputSource = getInputSource(message);
-        Object node = xpath.evaluate(xpathExp, inputSource, XPathConstants.NODE);
-		if (log.isDebugEnabled()) {
-			log.debug("Found node=" + node);
-		}
-		return node != null;
+		return xmlContentEquals( message, xpathExp, value, null );
 	}
-
+	
+	/**
+	 * Uses XPath to look for the occurence of a certain tag, specific in the xpath expression.
+	 * </p>
+	 * Note that {@link #selectAsBoolean(Message, String)} can be used instead of this method
+	 * and the XPath equality operator can be used in the XPath expression:
+	 * <br> 
+	 * <pre>{@code
+	 * String xpathExp = "/Order/OrderLines/OrderLine/Product/@productId = 364";
+	 * }</pre>
+	 * <br> 
+	 * 
+	 * @param message - 
+	 * 			the ESB Message which body content will be used.
+	 * @param xpathExp -
+	 * 			XPath expression to find a node.
+	 * @param namespaces -
+	 * 			Map of namespaces to be used in the xpath expression. Key=prefix,value = uri
+	 * @return true -
+	 * 			if the node is found and false in all other cases.
+	 * @throws XPathExpressionException
+	 * 			represents an error in an XPath expression
+	 */
+	public static boolean xmlContentEquals(final Message message, final String xpathExp, final String value, final Map<String,String> namespaces ) throws XPathExpressionException
+	{
+		final String xpathResult = selectAsString( message, xpathExp, namespaces );
+		return xpathResult == null ? false : xpathResult.equals( value );
+	}
+	
     /**
 	 * Uses XPath to look for the occurence of a certain tag, specific in the xpath expression.
+	 * <p/>
+	 * This is the equivalent of calling xmlContentGreaterThan( message, xpathExp, value, null). 
 	 *
-	 * @param message - the ESB Message which body content will be used.
-	 * @param xpathExp - XPath expression to find a node.
-	 * @param value - used to compare against the result found using the XPath expression.
-	 * @return true if equal, false in all other cases.
+	 * @param message - 
+	 * 				the ESB Message which body content will be used.
+	 * @param xpathExp -
+	 * 				XPath expression to find a node.
+	 * @return true 
+	 * 				if the node is found and false in all other cases.
 	 * @throws XPathExpressionException
+	 * 				represents an error in an XPath expression
 	 */
-	public static boolean xmlContentEquals(Message message, String xpathExp, String value) throws XPathExpressionException
+	public static boolean xmlContentGreaterThan( final Message message, final String xpathExp, final String value) throws XPathExpressionException
 	{
-		if (log.isDebugEnabled()) {
-			log.debug("Trying to match xpath: '" + xpathExp +  "' in message=" + message.getBody().get());
-		}
-		XPath xpath = xpf.newXPath();
-        InputSource inputSource = getInputSource(message);
-		String nodeValue = (String) xpath.evaluate(xpathExp, inputSource, XPathConstants.STRING);
-		if (log.isDebugEnabled()) {
-			log.debug("Found nodeValue=" + nodeValue + " which is matched to given value=" + value);
-		}
-		return value.equals(nodeValue);
+		return xmlContentGreaterThan( message, xpathExp, value, null );
 	}
-
-    /**
+	
+	/**
 	 * Uses XPath to look for the occurence of a certain tag, specific in the xpath expression.
 	 *
-	 * @param message - the ESB Message which body content will be used.
-	 * @param xpathExp - XPath expression to find a node.
-	 * @param value - used to compare against the result found using the XPath expression.
-	 * @return true if node (returned by the xpath expression) is greater than the current value, false in all other cases.
+	 * @param message - 
+	 * 				the ESB Message which body content will be used.
+	 * @param xpathExp -
+	 * 				XPath expression to find a node.
+	 * @param namespaces -
+	 * 				Map of namespaces to be used in the xpath expression. Key=prefix,value = uri
+	 * @return true 
+	 * 				if the node is found and false in all other cases.
 	 * @throws XPathExpressionException
+	 * 				represents an error in an XPath expression
 	 */
-	public static boolean xmlContentGreaterThan(Message message, String xpathExp, String value) throws XPathExpressionException
+	public static boolean xmlContentGreaterThan( final Message message, final String xpathExp, final String value, final Map<String,String> namespaces) throws XPathExpressionException
 	{
-		String nodeValue=null;
-		double doubleValue=0;
-		double doubleNodeValue=0;
+		final String xpathResult = (String) selectAsString( message, xpathExp, namespaces );
 
-		if (log.isDebugEnabled()) {
-			log.debug("Trying to match xpath: '" + xpathExp +  "' in message=" + message.getBody().get());
-		}
-		XPath xpath = xpf.newXPath();
-		InputSource inputSource = getInputSource(message);	
-		nodeValue = (String) xpath.evaluate(xpathExp, inputSource, XPathConstants.STRING);if (log.isDebugEnabled()) {
-			log.debug("Found nodeValue=" + nodeValue + " which is matched to given value=" + value);
-		}
-		if (nodeValue!=null && !"".equals(nodeValue)) {
-
-			try {
-				doubleValue = Double.parseDouble(value);
-			} catch (NumberFormatException ne) {
-				log.equals("Could not parse value=" + doubleValue + " to double");
-			}
-			try {
-				doubleNodeValue = Double.parseDouble(nodeValue);
-			} catch (NumberFormatException ne) {
-				log.equals("Could not parse nodeValue=" + doubleNodeValue + " to double");
-			}
-			if (doubleNodeValue > doubleValue) {
-				return true;
-			}
-		}
-		return false;
+		if ( xpathResult != null && !"".equals( xpathResult ) ) 
+			return parseDouble( xpathResult ) > parseDouble( value );
+		else
+    		return false;
 	}
-
-    /**
+	
+	/**
 	 * Uses XPath to look for the occurence of a certain tag, specific in the xpath expression.
+	 * <p/>
+	 * This is the equivalent of calling xmlContentLessThan( message, xpathExp, value, null). 
 	 *
-	 * @param message - the ESB Message which body content will be used.
-	 * @param xpathExp - XPath expression to find a node.
-	 * @param value - used to compare against the result found using the XPath expression.
-	 * @return true if node (returned by the xpath expression) is less than the current value, false in all other cases.
+	 * @param message - 
+	 * 				the ESB Message which body content will be used.
+	 * @param xpathExp -
+	 * 				XPath expression to find a node.
+	 * @return true 
+	 * 				if the node is found and false in all other cases.
 	 * @throws XPathExpressionException
+	 * 				represents an error in an XPath expression
 	 */
-	public static boolean xmlContentLessThan(Message message, String xpathExp, String value) throws XPathExpressionException
+    public static boolean xmlContentLessThan( final Message message, final String xpathExp, final String value) throws XPathExpressionException
+    {
+        return xmlContentLessThan( message, xpathExp, value, null );
+    }
+	
+    /**
+     * Uses XPath to look for the occurence of a certain tag, specific in the xpath expression.
+     *
+     * @param message -
+     *              the ESB Message which body content will be used.
+     * @param xpathExp -
+     *              XPath expression to find a node.
+     * @return true
+     *              if the node is found and false in all other cases.
+     * @throws XPathExpressionException
+     *              represents an error in an XPath expression
+     */
+    public static boolean xmlContentLessThan( final Message message, final String xpathExp, final String value, final Map<String,String> namespaces) throws XPathExpressionException
+    {
+        final String xpathResult = (String) selectAsString( message, xpathExp, namespaces );
+
+        if ( xpathResult != null && !"".equals( xpathResult ) )
+            return parseDouble( xpathResult ) < parseDouble( value );
+        else
+            return false;
+    }
+    
+    /**
+     * Will take the passed in string of namespaces in the form "prefix=uri,prefix=uri".
+     * 
+     * @param namespaces string of namespaces in the form "prefix=uri,prefix=uri"
+     * @return Map<String,String> where the key will be the namespace prefix and the value the uri
+     */
+    public static Map<String, String> parseNamespaces( final String namespaces )
 	{
-		String nodeValue=null;
-		double doubleValue=0;
-		double doubleNodeValue=0;
-
-		if (log.isDebugEnabled()) {
-			log.debug("Trying to match xpath: '" + xpathExp +  "' in message=" + message.getBody().get());
+		AssertArgument.isNotNullAndNotEmpty( namespaces, "namespaces" );
+		
+		final String[] namespacesElements = namespaces.split( "," );
+		final Map<String,String> namespacesMap = new HashMap<String,String>();
+		for ( String ns : namespacesElements )
+		{
+			final String[] pairs = ns.split( "=" );
+			namespacesMap.put( pairs[0].trim(), pairs[1].trim() );
 		}
-		XPath xpath = xpf.newXPath();
-		InputSource inputSource = getInputSource(message);
-		nodeValue = (String) xpath.evaluate(xpathExp, inputSource, XPathConstants.STRING);if (log.isDebugEnabled()) {
-			log.debug("Found nodeValue=" + nodeValue + " which is matched to given value=" + value);
+		return namespacesMap;
+	}
+    
+	/*
+	 * Checks if the cachedObject was non-null, and if so, checks the message hashCode against
+	 * the cachedObjects messageHashCode.
+	 */
+    private static <T> boolean cacheHit ( final XPathCacheObject<T> cachedObject, final Message message )
+    {
+		return cachedObject != null && cachedObject.getMessageHashCode() == message.hashCode();
+    }
+	
+	private static double parseDouble( final String string ) throws XPathExpressionException
+	{
+		try 
+		{
+			return Double.parseDouble( string );
+		} 
+		catch (NumberFormatException e) 
+		{
+			throw new XPathExpressionException("Could not parse value [" + string + "] to double" );
 		}
-		if (nodeValue!=null && !"".equals(nodeValue)) {
-
-			try {
-				doubleValue = Double.parseDouble(value);
-			} catch (NumberFormatException ne) {
-				log.equals("Could not parse value=" + doubleValue + " to double");
-			}
-			try {
-				doubleNodeValue = Double.parseDouble(nodeValue);
-			} catch (NumberFormatException ne) {
-				log.equals("Could not parse nodeValue=" + doubleNodeValue + " to double");
-			}
-			if (doubleNodeValue < doubleValue) {
-				return true;
-			}
-		}
-		return false;
 	}
+	
+	private static void setNamespaces( final XPath xpath, final Map<String,String> namespaces )
+    {
+        if ( namespaces == null )
+            return;
 
-    private static InputSource getInputSource(Message message) throws XPathExpressionException {
+        final XPathNamespaceContext namespaceContext = new XPathNamespaceContext();
+        for ( Entry<String, String> entry : namespaces.entrySet() )
+            namespaceContext.setMapping( entry.getKey(), entry.getValue() );
+
+        xpath.setNamespaceContext( namespaceContext );
+    }
+
+
+    private static InputSource getInputSource(Message message) throws XPathExpressionException 
+    {
         Object payload;
 
-        try {
+        try 
+        {
             payload = payloadProxy.getPayload(message);
-        } catch (MessageDeliverException e) {
+        } 
+        catch (MessageDeliverException e) 
+        {
             throw new XPathExpressionException(e);
         }
 
-        if(payload instanceof byte[]) {
+        if(payload instanceof byte[]) 
+        {
             return new InputSource(new ByteArrayInputStream((byte[]) payload));
-        } else if(payload instanceof String) {
+        } 
+        else if(payload instanceof String) 
+        {
             return new InputSource(new StringReader((String) payload));
-        } else {
+        } 
+        else 
+        {
             throw new XPathExpressionException("Unsupport expression input object type: " + payload.getClass().getName());
         }
     }
+    
+    private static XPath getXPath( final Map<String,String> namespaces )
+    {
+		final XPath xpath = xpf.newXPath();
+		setNamespaces( xpath, namespaces );
+		return xpath;
+    }
+    
+	/**
+	 * XPathCacheObject holds results from XPath evaluations and message object instance hashcodes.
+	 * </p> 
+	 * The intent of this class is for it to be used as the value in a Map:
+	 * <pre>
+	 * {@code  
+	 * Map<String,XPathCacheObject> xpathResults = new WeakHashMap<String,XPathCacheObject>() );
+	 * }</pre><br><br>
+	 * The key would be a String representing the XPath expression which was used to evaluate the result from 
+	 * the Message Object instance represented by the messageHashCode.
+	 * 
+	 */
+	private static class XPathCacheObject<T>
+	{
+		/*
+		 * The hashCode of the Message object used in the XPath evaluation
+		 */
+		private final int messageHashCode;
+		/*
+		 * The result from the XPath evalutaion
+		 */
+		private final T result;
+		
+		/**
+		 * Sole constructor.
+		 * 
+		 * @param messageHashCode -
+		 * 				The hashCode of the Message object used in the XPath evaluation
+		 * @param result -
+		 * 				The result from the XPath evalutaion
+		 */
+		public XPathCacheObject( final int messageHashCode, final T result )
+		{
+			this.messageHashCode = messageHashCode;
+			this.result = result;
+		}
+		
+		public int getMessageHashCode() 
+		{ 
+			return messageHashCode; 
+		}
+		
+		public T getResult() 
+		{ 
+			return result; 
+		}
+	}
+	
 }
 	

Modified: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/routing/cbr/JBRulesCounter.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/routing/cbr/JBRulesCounter.java	2008-11-05 12:54:27 UTC (rev 23713)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/routing/cbr/JBRulesCounter.java	2008-11-05 13:39:40 UTC (rev 23714)
@@ -256,7 +256,7 @@
 	/**
 	 * Register this MBean with JBoss.
 	 */
-	protected void registerMBean() {
+	public void registerMBean() {
 		MBeanServer mbeanServer = null;
 		try {
 			mbeanServer = MBeanServerLocator.locateJBoss();

Modified: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/routing/cbr/JBossRulesRouter.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/routing/cbr/JBossRulesRouter.java	2008-11-05 12:54:27 UTC (rev 23713)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/routing/cbr/JBossRulesRouter.java	2008-11-05 13:39:40 UTC (rev 23714)
@@ -21,69 +21,32 @@
  */
 package org.jboss.internal.soa.esb.services.routing.cbr;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.log4j.Logger;
-import org.apache.log4j.Level;
-import org.drools.RuleBase;
-import org.drools.RuleBaseFactory;
-import org.drools.StatefulSession;
-import org.drools.compiler.DroolsParserException;
-import org.drools.compiler.PackageBuilder;
-import org.drools.compiler.PackageBuilderConfiguration;
-import org.drools.rule.Package;
-import org.jboss.internal.soa.esb.services.routing.cbr.JBRulesCounter;
+import org.jboss.internal.soa.esb.services.rules.RuleServiceCallHelper;
+import org.jboss.internal.soa.esb.services.rules.RuleServiceException;
 import org.jboss.soa.esb.helpers.ConfigTree;
-import org.jboss.soa.esb.lifecycle.LifecyclePriorities;
-import org.jboss.soa.esb.lifecycle.LifecycleResource;
-import org.jboss.soa.esb.lifecycle.LifecycleResourceException;
-import org.jboss.soa.esb.lifecycle.LifecycleResourceFactory;
 import org.jboss.soa.esb.message.Message;
 import org.jboss.soa.esb.services.routing.MessageRouterException;
-import org.jboss.soa.esb.services.routing.cbr.CBRException;
 import org.jboss.soa.esb.services.routing.cbr.ContentBasedRouter;
-import org.jboss.soa.esb.util.ClassUtil;
 
 /**
- * The Implementation of a rule based Content Router. Here we use JBossRules. We
- * keep a HashMap of so called working memories for performance reasons.
- * 
+ * The Implementation of a rule based Content Router. Here we use JBossRules.
+ * <p/>
+ * We keep a HashMap of so called working memories for performance reasons.
+ * <br><br>
  * @author kstam at redhat.com
  * 
  */
 public class JBossRulesRouter implements ContentBasedRouter
 {
-        /**
-         * The lifecycle resource factory.
-         */
-        private static final LifecycleResourceFactory<Map<String, RuleBase>> lifecycleRuleBaseFactory = new LifecycleRuleBaseFactory() ;
-        /**
-         * Lifecycle couriers.
-         */
-        private static final LifecycleResource<Map<String, RuleBase>> lifecycleRuleBases =
-            new LifecycleResource<Map<String,RuleBase>>(lifecycleRuleBaseFactory,
-                    LifecyclePriorities.RULE_BASE_PRIORITY) ;
-        /**
-         * The lifecycle resource factory.
-         */
-        private static final LifecycleResourceFactory<Map<String, String>> lifecycleRuleSetFactory = new LifecycleRuleSetFactory() ;
-        /**
-         * Lifecycle couriers.
-         */
-        private static final LifecycleResource<Map<String, String>> lifecycleRuleSets =
-            new LifecycleResource<Map<String,String>>(lifecycleRuleSetFactory,
-                    LifecyclePriorities.RULE_BASE_PRIORITY) ;
-        
 	private static Logger logger = Logger.getLogger(JBossRulesRouter.class);
 	
-	private JBRulesCounter rulesCounter = null;
+	private ConfigTree configTree;
 	
 	/**
      * Route the message with a reference to the ruleSets supplied in the message.
@@ -91,8 +54,7 @@
 	 * 
 	 * @param message - Message that needs routing.
 	 */
-	public List<String> route (Message message)
-    throws MessageRouterException
+	public List<String> route (Message message) throws MessageRouterException
 	{
         logger.error("Not implemented");
 		return null;
@@ -102,12 +64,25 @@
 	 * Route the message, using the given ruleSet (drl).
 	 * 
 	 * @param ruleSet -
-	 *            Filename of the drl that will be used.
+	 *            String reference to a file which contains a ruleSet.
+	 * @param ruleLanguage -
+	 *            String reference to a file which contains a custom rule language
+	 *            definition.
 	 * @param message -
 	 *            Message that needs routing.
+	 * @param objectList -
+	 *            List of objects that should be extracted from the message
+	 *            object and which will be inserted into the Drools working 
+	 *            memory.
+	 * @return List<String> -
+	 *            List of destinations
+	 * 			
 	 */
-	public List<String> route (String ruleSet, boolean ruleReload,
-			Message message, List<Object> objectList) throws MessageRouterException
+	public List<String> route (
+			final String ruleSet, 
+			final boolean ruleReload,
+			final Message message, 
+			final List<Object> objectList) throws MessageRouterException
 	{
 		return route(ruleSet, null, ruleReload, message, objectList);
 	}
@@ -118,301 +93,45 @@
 	 * now. However when the need arises, this is where it goes.
 	 * 
 	 * @param ruleSet -
-	 *            Filename of the drl that will be used.
+	 *            String reference to a file which contains a ruleSet.
 	 * @param ruleLanguage -
-	 *            Filename of the dsl that will be used.
+	 *            String reference to a file which contains a custom rule language
+	 *            definition.
+	 * @param ruleReload -
+	 *            if set to true, a ruleSet update should result in reloading the
+	 *            ruleSet.
 	 * @param message -
 	 *            Message that needs routing.
+	 * @param objectList - 
+	 *			  a list with additional objects (typically pulled from the message) to be inserted into 
+	 *            working memory.
+	 * @return List<String> -
+	 *            List of Service destinations.
 	 */
-	@SuppressWarnings("unchecked")
-	public List<String> route (String ruleSet, String ruleLanguage,
-			boolean ruleReload, Message message, List<Object> objectList) throws MessageRouterException
+	public List<String> route (
+			final String ruleSet, 
+			final String ruleLanguage,
+			final boolean ruleReload, 
+			Message message, 
+			final List<Object> objectList ) throws MessageRouterException
 	{
-        List<String> destinations = new ArrayList();
-        long startTime = System.nanoTime();
-
-        try {
-    		String newRuleSet = null;
-    		boolean isRulesChanged = false;
-    
-                final Map<String, String> ruleSets = lifecycleRuleSets.getLifecycleResource() ;
-    		if (ruleReload)
-    		{
-    			String currentRuleSet = ruleSets.get(ruleSet);
-    			newRuleSet = getRules(ruleSet, ruleLanguage);
-    			if (currentRuleSet == null || !currentRuleSet
-    					.equals(newRuleSet))
-    			{
-    				isRulesChanged = true;
-    			}
-    		}
-    		final Map<String, RuleBase> ruleBases = lifecycleRuleBases.getLifecycleResource() ;
-    		RuleBase ruleBase = ruleBases.get(ruleSet);
-    		if (ruleBase == null || isRulesChanged)
-    		{
-    			logger.log(Level.DEBUG,
-    					"Reading ruleSet from file=" + ruleSet);
-    			ruleBase = readRuleBase(ruleSet, ruleLanguage);
-    			if (ruleBase != null) ruleBases.put(ruleSet, ruleBase);
-    			if (newRuleSet == null)
-    			{
-    				newRuleSet = getRules(ruleSet, ruleLanguage);
-    			}
-    			if (ruleSet != null) ruleSets.put(ruleSet, newRuleSet);
-    		}
-    		StatefulSession workingMemory = ruleBase.newStatefulSession();
-    		logger.log(Level.DEBUG,
-    				"Obtained message=" + message + " with ruleSet=" + ruleSet);
-    		workingMemory.setGlobal("destinations", destinations);
-            if (objectList!=null) {
-                for (Object object : objectList) {
-                    workingMemory.insert(object);
-                }
-            }
-    		workingMemory.insert(message);
-    		logger.log(Level.DEBUG, "Fire the JBossRules Engine");
-    		workingMemory.fireAllRules();
-    		long procTime = System.nanoTime() - startTime;
-    		if (rulesCounter != null) {
-    			rulesCounter.update(procTime, ruleSet, JBRulesCounter.RULES_SUCCEED);
-    		}
-    			
-    		logger.log(Level.DEBUG,
-    				"Outgoing Destinations: " + destinations);
-            workingMemory.dispose();
-            return destinations;
-        } catch (final LifecycleResourceException lre) {
-            if (rulesCounter != null) {
-                    long procTime = System.nanoTime() - startTime;
-                    rulesCounter.update(procTime, ruleSet, JBRulesCounter.RULES_FAILED);
-            }
-            throw new MessageRouterException("Could not load lifecycle data. " + lre.getMessage(), lre);
-        } catch (IOException ioe) {
-        	if (rulesCounter != null) {
-        		long procTime = System.nanoTime() - startTime;
-        		rulesCounter.update(procTime, ruleSet, JBRulesCounter.RULES_FAILED);
-        	}
-        	throw new MessageRouterException("Could not read the rules. " +  ioe.getMessage(), ioe);
-        } catch (DroolsParserException dpe) {
-        	if (rulesCounter != null) {
-        		long procTime = System.nanoTime() - startTime;
-        		rulesCounter.update(procTime, ruleSet, JBRulesCounter.RULES_FAILED);
-        	}
-        	throw new MessageRouterException("Could not parse the rules. " +  dpe.getMessage(), dpe);
-        } catch (CBRException cbre) {
-        	if (rulesCounter != null) {
-        		long procTime = System.nanoTime() - startTime;
-        		rulesCounter.update(procTime, ruleSet, JBRulesCounter.RULES_FAILED);
-        	}
-        	throw new MessageRouterException("Could not parse the rules. " +  cbre.getMessage(), cbre);
-        }
-	}
-
-	/**
-	 * Reading the rules and dsl from files. Note that we may want to allow
-	 * other ways to set the rule, but for now it's just files.
-	 */
-	private static RuleBase readRuleBase (String rulesFile, String ruleLanguage)
-			throws DroolsParserException, IOException, CBRException
-	{
-		// read in the rules
-		logger.debug("Going to read the rule: " + rulesFile);
-		InputStream inputStreamDrl = ClassUtil.getResourceAsStream(rulesFile.charAt(0) == '/' ? rulesFile : "/" + rulesFile, JBossRulesRouter.class);
-		if (inputStreamDrl == null)
+		try
 		{
-			logger.error("Could not find rulesFile: " + rulesFile);
-			return null;
-		}
-		else
+    		Map<String,Object> globals = new HashMap<String,Object>();
+    		List<String> destinations = new ArrayList<String>();
+    		globals.put( "destinations", destinations );
+    		message = RuleServiceCallHelper.executeRulesService( ruleSet, ruleLanguage, ruleReload, message, objectList, globals, configTree );
+    		return destinations;
+		} 
+		catch (final RuleServiceException e)
 		{
-	            PackageBuilderConfiguration pkgBuilderCfg = new PackageBuilderConfiguration();
-	            //pkgBuilderCfg.setCompiler(PackageBuilderConfiguration.JANINO);
-	            PackageBuilder builder = new PackageBuilder(pkgBuilderCfg);
-	            try
-	            {
-                        Reader rules = new InputStreamReader(inputStreamDrl);
-                        // this wil parse and compile in one step
-                        if (ruleLanguage == null)
-                        {
-                                builder.addPackageFromDrl(rules);
-                        }
-                        else
-                        {
-                                logger.debug("Going to read the language: " + ruleLanguage);
-                                InputStream inputStreamDsl = ClassUtil.getResourceAsStream(ruleLanguage.charAt(0) == '/' ? ruleLanguage : "/" + ruleLanguage, JBossRulesRouter.class);
-                                if (inputStreamDsl == null)
-                                {
-                                        logger.error("Could not find ruleLanguage: " + rulesFile);
-                                }
-                                else
-                                {
-                                    try
-                                    {
-                                        Reader dsl = new InputStreamReader(inputStreamDsl);
-                                        builder.addPackageFromDrl(rules, dsl);
-                                    }
-                                    finally
-                                    {
-                                        safeClose(inputStreamDsl);
-                                    }
-                                }
-                        }
-	            }
-	            finally
-	            {
-	                safeClose(inputStreamDrl);
-	            }
-			// get the compiled package (which is serializable)
-			Package pkg = builder.getPackage();
-			// add the package to a rulebase (deploy the rule package).
-			try
-			{
-				RuleBase ruleBase = RuleBaseFactory.newRuleBase();
-				ruleBase.addPackage(pkg);
-				return ruleBase;
-			} catch (Exception ex) {
-				throw new CBRException(ex.getMessage(), ex);
-			}
+			throw new MessageRouterException(e.getMessage(), e);
 		}
 	}
 
-	/**
-	 * Reading the rules and dsl from files. Note that we may want to allow
-	 * other ways to set the rule, but for now it's just files.
-	 */
-	private static String getRules (String rulesFile, String ruleLanguage)
-			throws IOException
+	public void setConfigTree(final ConfigTree configTree) 
 	{
-		logger.debug("Going to hash the rule: " + rulesFile);
-		InputStream inputStreamDrl = ClassUtil.getResourceAsStream(rulesFile.charAt(0) == '/' ? rulesFile : "/" + rulesFile, JBossRulesRouter.class);
-		if (inputStreamDrl == null)
-		{
-			logger.error("Could not find rulesFile: " + rulesFile);
-			return null;
-		}
-		else
-		{
-		    final String rules ;
-		    try
-		    {
-                        rules = getString(inputStreamDrl);
-		    }
-		    finally
-		    {
-		        safeClose(inputStreamDrl);
-		    }
-                    String language = "";
-                    if (ruleLanguage != null)
-                    {
-                            logger.debug("Going to hash the language: " + ruleLanguage);
-                            InputStream inputStreamDsl = ClassUtil.getResourceAsStream(ruleLanguage.charAt(0) == '/' ? ruleLanguage : "/" + ruleLanguage, JBossRulesRouter.class);
-                            if (inputStreamDsl == null)
-                            {
-                                    logger.error("Could not find language: " + ruleLanguage);
-                            }
-                            else
-                            {
-                                try
-                                {
-                                    language = getString(inputStreamDsl);
-                                }
-                                finally
-                                {
-                                    safeClose(inputStreamDsl);
-                                }
-                            }
-                    }
-                    return rules + language;
-		}
-
+		this.configTree = configTree;
 	}
-
-	private static void safeClose(final InputStream is)
-	{
-	    try
-	    {
-	        is.close() ;
-	    }
-	    catch (final Throwable th) {} // ignore
-	}
-	
-	private static String getString (InputStream in) throws IOException
-	{
-		StringBuffer stringBuffer = new StringBuffer();
-		byte[] b = new byte[4096];
-		for (int i; (i = in.read(b)) != -1;)
-		{
-			stringBuffer.append(new String(b, 0, i));
-		}
-		return stringBuffer.toString();
-	}
-
-	public void setConfigTree(ConfigTree configTree) {
-		rulesCounter = new JBRulesCounter(configTree);
-		rulesCounter.registerMBean();
-	}
         
-        /**
-         * The lifecycle resource factory for rule sets.
-         * @author kevin
-         */
-        public static class LifecycleRuleBaseFactory implements LifecycleResourceFactory<Map<String, RuleBase>>
-        {
-            /**
-             * Create a resource object which will be associated with the specified lifecycle identity.
-             * @param lifecycleIdentity The associated lifecycle identity.
-             * @return The lifecycle resource
-             * @throws LifecycleResourceException for errors during construction.
-             */
-            public Map<String, RuleBase> createLifecycleResource(final String lifecycleIdentity)
-                throws LifecycleResourceException
-            {
-                return new ConcurrentHashMap<String, RuleBase>() ;
-            }
-        
-            /**
-             * Destroy a resource object which is associated with the specified lifecycle identity.
-             * @param resource The lifecycle resource.
-             * @param lifecycleIdentity The associated lifecycle identity.
-             * @return The lifecycle resource.
-             * @throws LifecycleResourceException for errors during destroy.
-             */
-            public void destroyLifecycleResource(final Map<String, RuleBase> resource,
-                final String lifecycleIdentity)
-                throws LifecycleResourceException
-            {
-            }
-        }
-	
-        /**
-         * The lifecycle resource factory for rule sets.
-         * @author kevin
-         */
-        public static class LifecycleRuleSetFactory implements LifecycleResourceFactory<Map<String, String>>
-        {
-            /**
-             * Create a resource object which will be associated with the specified lifecycle identity.
-             * @param lifecycleIdentity The associated lifecycle identity.
-             * @return The lifecycle resource
-             * @throws LifecycleResourceException for errors during construction.
-             */
-            public Map<String, String> createLifecycleResource(final String lifecycleIdentity)
-                throws LifecycleResourceException
-            {
-                return new ConcurrentHashMap<String, String>() ;
-            }
-        
-            /**
-             * Destroy a resource object which is associated with the specified lifecycle identity.
-             * @param resource The lifecycle resource.
-             * @param lifecycleIdentity The associated lifecycle identity.
-             * @return The lifecycle resource.
-             * @throws LifecycleResourceException for errors during destroy.
-             */
-            public void destroyLifecycleResource(final Map<String, String> resource,
-                final String lifecycleIdentity)
-                throws LifecycleResourceException
-            {
-            }
-        }
 }

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleBaseHelper.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleBaseHelper.java	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleBaseHelper.java	2008-11-05 13:39:40 UTC (rev 23714)
@@ -0,0 +1,303 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * 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.jboss.internal.soa.esb.services.rules;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.UnsupportedEncodingException;
+import java.util.Properties;
+
+import org.apache.log4j.Logger;
+import org.drools.RuleBase;
+import org.drools.RuleBaseFactory;
+import org.drools.agent.RuleAgent;
+import org.drools.compiler.DroolsParserException;
+import org.drools.compiler.PackageBuilder;
+import org.drools.compiler.PackageBuilderConfiguration;
+import org.drools.decisiontable.InputType;
+import org.drools.decisiontable.SpreadsheetCompiler;
+import org.jboss.internal.soa.esb.util.StreamUtils;
+import org.jboss.soa.esb.util.ClassUtil;
+
+/**
+ * A helper class, it returns rulebases based on various methods of creating them.
+ * <p/> 
+ * 
+ * @author jdelong at redhat.com
+ * @author <a href="mailto:dbevenius at redhat.com">Daniel Bevenius</a>
+ * 
+ */
+public class DroolsRuleBaseHelper {
+
+	private static Logger logger = Logger.getLogger(DroolsRuleBaseHelper.class);
+	
+	private DroolsRuleBaseHelper()  {}
+	
+	/**
+	 * Factory method that returns an instance of this class.
+	 * </p>
+	 * The current implementation returns a new instance of this
+	 * class for every call.
+	 * 
+	 * @return {@link DroolsRuleBaseHelper}
+	 */
+	public static DroolsRuleBaseHelper getInstance()
+	{
+		return new DroolsRuleBaseHelper();
+	}
+
+	/**
+	 * Creates a rulebase using rules and dsl from files
+	 * <p/>
+	 * 
+	 * @param ruleFile - 
+	 * 			file name which contains the Drools rules. Can be a file on the local
+	 *  		filesystem, a file on the classpath or an URL. Must not be null.
+	 * @param dsl - 
+	 *			file containing the Drools Domain Specific Language (dsl)
+	 * @throws DroolsParserException -
+	 * 			if an exception occurs during Drools package building	
+	 * @throws IOException -
+	 * 			if an IOException occurs during Drools package building	
+	 * @throws RuleServiceException -
+	 * 			if the ruleFile cannot be located or if it was not possible to
+	 * 			add the package to the RuleBase.
+	 */
+	public RuleBase createRuleBaseFromRuleFiles(
+			final String ruleFile, 
+			final String dsl)
+			throws DroolsParserException, IOException, RuleServiceException, RuleServiceBuilderException
+	{
+		assertNotNull( ruleFile, "ruleFile" );
+		
+		// read in the rules
+		InputStream rulesInputStream = getRulesInputStream( ruleFile );
+
+		Reader ruleReader = getRulesReader( rulesInputStream );
+
+		PackageBuilder builder = new PackageBuilder( new PackageBuilderConfiguration() );
+		try 
+		{
+			if ( dsl == null ) 
+			{
+				builder.addPackageFromDrl(ruleReader);
+			} 
+			else 
+			{
+				InputStream dslInputStream = getRulesInputStream( dsl );
+				Reader dslReader = getRulesReader( dslInputStream );
+				if ( dslReader == null ) 
+				{
+					logger.error("Could not find dsl file [" + dsl + "]");
+				} 
+				else 
+				{
+					try 
+					{
+						builder.addPackageFromDrl(ruleReader, dslReader);
+					} 
+					finally 
+					{
+						safeClose(dslInputStream);
+					}
+				}
+			}
+		} 
+		finally 
+		{
+			safeClose(rulesInputStream);
+		}
+
+		return getNewRuleBaseWithPackage( builder );
+	}
+	
+	
+
+	/**
+	 * Reads the rules and dsl from files and returning as a string
+	 * 
+	 * @param ruleFile - 
+	 * 			file name which contains the Drools rules. Can be a file on the local
+	 *  		filesystem, a file on the classpath or an URL. Must not be null.
+	 * @param dsl - 
+	 *			file containing the Drools Domain Specific Language (dsl)
+	 * @return String -
+	 * 			String representation of the rules
+	 * @throws IOException -
+	 * 			if an IOException occurs during Drools package building	
+	 * @throws RuleServiceException -
+	 * 			if the ruleFile cannot be located or if it was not possible to
+	 * 			add the package to the RuleBase.
+	 * @throws RuleServiceException 
+	 */
+	public String getRulesAsString( 
+			final String ruleFile, 
+			final String dsl) throws IOException, RuleServiceException 
+	{
+		assertNotNull( ruleFile, "rulefile" );
+		
+		final String rules = getFileContents( ruleFile ); 
+		return dsl == null ? rules : rules + getFileContents( dsl );
+	}
+	
+	/**
+	 * Reading the rules from a decision table.
+	 * <p/>
+	 * @param decisionTable -
+	 * 			file name which contains the Drools decision table. Can be a file on the local
+	 *  		filesystem, a file on the classpath or an URL. Must not be null.
+	 * @throws DroolsParserException -
+	 * 			
+	 * @throws IOException -
+	 * 			
+	 * @throws RuleServiceException -
+	 */
+	public RuleBase createRuleBaseFromDecisionTable(
+			final String decisionTable)
+			throws DroolsParserException, IOException, RuleServiceException, RuleServiceBuilderException
+	{
+		assertNotNull( decisionTable, "decisionTable" );
+		
+		final String drl = getSpreadsheetRules(decisionTable);
+		PackageBuilder builder = new PackageBuilder();
+		builder.addPackageFromDrl( new StringReader(drl) );
+		return getNewRuleBaseWithPackage( builder );
+	}
+
+	/**
+	 * Reading the decision table and creating a drl
+	 * </p>
+	 * @throws RuleServiceException 
+	 */
+	public String getSpreadsheetRules(final String decisionTable) throws RuleServiceException 
+	{
+		InputStream inputStreamDT = getRulesInputStream(decisionTable);
+		try 
+		{
+			return new SpreadsheetCompiler().compile(inputStreamDT, InputType.XLS);
+		} 
+		finally 
+		{
+			safeClose(inputStreamDT);
+		}
+	}
+
+	/**
+	 * This shows how rules are loaded up from a deployed package.
+	 */
+	public RuleBase loadRuleBaseFromRuleAgent(final String ruleAgentProperties) throws IOException, Exception 
+	{
+		return RuleAgent.newRuleAgent( "/" + ruleAgentProperties ).getRuleBase();
+	}
+	
+	public RuleBase loadRuleBaseFromRuleAgent(final Properties ruleAgentProperties) throws IOException, Exception 
+	{
+		return RuleAgent.newRuleAgent( ruleAgentProperties ).getRuleBase();
+	}
+	
+	/**
+	 * This shows how rules are loaded up from a deployed package.
+	 */
+	public RuleAgent createRuleAgent(final String ruleAgentProperties) throws IOException, Exception 
+	{
+		return RuleAgent.newRuleAgent( "/" + ruleAgentProperties );
+	}
+	
+	private String getFileContents( final String fileName ) throws RuleServiceException
+	{
+		InputStream inputStream = getRulesInputStream( fileName );
+		try 
+		{
+    		return StreamUtils.readStreamString( inputStream, "UTF-8" );
+		} 
+		catch ( final UnsupportedEncodingException e)
+		{
+			throw new RuleServiceException("Could not read from file [" + fileName + "].", e);
+		} 
+		finally 
+		{
+			safeClose( inputStream );
+		}
+	}
+	
+	//	private instance methods
+	
+	private Reader getRulesReader(final InputStream inputStream) 
+	{
+		return new InputStreamReader( inputStream );
+	}
+
+	private InputStream getRulesInputStream(final String rulesFile) throws RuleServiceException 
+	{
+		InputStream resourceAsStream = ClassUtil.getResourceAsStream( "/" + rulesFile, getClass() );
+		if ( resourceAsStream == null )
+    		throw new RuleServiceException("Could not locate file [" + rulesFile + "], neither as a file on the local filesystem, on the classpath nor as a URL.");
+		else
+			return resourceAsStream;
+	}
+	
+	private RuleBase getNewRuleBaseWithPackage( final PackageBuilder builder ) throws RuleServiceException, RuleServiceBuilderException
+	{
+		RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+		try 
+		{
+			ruleBase.addPackage( builder.getPackage() );
+		} 
+		catch (final Exception ex) 
+		// 	need to catch Exception as RuleBase.addPackage throws it
+		{
+			throw new RuleServiceException(ex.getMessage(), ex);
+		}
+		
+		if ( builder.hasErrors() )
+		{
+			throw new RuleServiceBuilderException( "PackageBuilder generated errors: ", builder.getErrors() );
+		}
+		
+		return ruleBase;
+	}
+	
+	//	private static methods
+	
+	private static void safeClose( final InputStream is ) 
+	{
+		try 
+		{
+			is.close();
+		} 
+		catch (final IOException e) 
+		{
+			logger.warn("Caught an IOException while trying to close as inputstream.", e );
+		} 
+	}
+
+	private static void assertNotNull( final String argumentValue, final String argumentName ) 
+	{
+		if( argumentValue == null )
+			throw new NullPointerException("[" + argumentName + "] argument must not be null");
+	}
+	
+}

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleService.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleService.java	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleService.java	2008-11-05 13:39:40 UTC (rev 23714)
@@ -0,0 +1,855 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * 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.jboss.internal.soa.esb.services.rules;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.drools.RuleBase;
+import org.drools.StatefulSession;
+import org.drools.StatelessSession;
+import org.drools.WorkingMemory;
+import org.drools.agent.RuleAgent;
+import org.drools.compiler.DroolsParserException;
+import org.jboss.internal.soa.esb.assertion.AssertArgument;
+import org.jboss.internal.soa.esb.services.routing.cbr.JBRulesCounter;
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.lifecycle.LifecyclePriorities;
+import org.jboss.soa.esb.lifecycle.LifecycleResource;
+import org.jboss.soa.esb.lifecycle.LifecycleResourceException;
+import org.jboss.soa.esb.lifecycle.LifecycleResourceFactory;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.services.rules.RuleService;
+
+/**
+ * JBossRules (aka Drools) Implementation of a rule engine interface for rules services. Here we use
+ * <p/>
+ * 
+ * @author jdelong at redhat.com
+ * @author <a href="mailto:dbevenius at redhat.com">Daniel Bevenius</a>
+ * 
+ */
+public class DroolsRuleService implements RuleService 
+{
+	/**
+	 * The lifecycle resource factory for RuleBases.
+	 */
+	private static final LifecycleResourceFactory<Map<String, RuleBase>> lifecycleRuleBaseFactory = new LifecycleRuleBaseFactory();
+	
+	private static final LifecycleResourceFactory<Map<String, RuleAgent>> lifecycleRuleAgentFactory = new LifecycleRuleAgentFactory();
+	/**
+	 * The lifecycle resource rule bases.
+	 */
+	private static final LifecycleResource<Map<String, RuleBase>> lifecycleRuleBases = new LifecycleResource<Map<String, RuleBase>>(
+			lifecycleRuleBaseFactory, LifecyclePriorities.RULE_BASE_PRIORITY);
+	/**
+	 * RuleAgents cache
+	 */
+	private static final LifecycleResource<Map<String, RuleAgent>> lifecycleRuleAgents = new LifecycleResource<Map<String, RuleAgent>>(
+			lifecycleRuleAgentFactory, LifecyclePriorities.RULE_BASE_PRIORITY);
+	/**
+	 * The lifecycle resource rule sets.
+	 */
+	private static final LifecycleResourceFactory<Map<String, String>> lifecycleRuleSetFactory = new LifecycleRuleSetFactory();
+	/**
+	 * Lifecycle couriers.
+	 */
+	private static final LifecycleResource<Map<String, String>> lifecycleRuleSets = new LifecycleResource<Map<String, String>>(
+			lifecycleRuleSetFactory, LifecyclePriorities.RULE_BASE_PRIORITY);
+
+	/**
+	 * See {@link JBRulesCounter}
+	 */
+	private JBRulesCounter rulesCounter = null;
+
+	/**
+	 * Execute rules using a certain ruleSet and domain specific language using
+	 * the Stateless rule engine API
+	 * 
+	 * @param ruleSet -
+	 *            String reference to a file which contains a ruleSet.
+	 * @param dsl -
+	 *            String reference to a file which contains a custom rule
+	 *            language definition
+	 * @param ruleReload -
+	 *            if set to true, a ruleSet update should result in reloading
+	 *            the ruleSet.
+	 * @param message -
+	 *            Message that is updated with the results.
+	 * @param globals -
+	 *            Map of globals variables that should be set in the working memory
+	 * @param objectList -
+	 *            a list with additional objects (typically pulled from the
+	 *            message) to be inserted into working memory
+	 * 
+	 * @return Message with updated objects.
+	 */
+	public Message executeStatelessRules(
+			final String ruleSet, 
+			final String dsl,
+			final boolean ruleReload, 
+			Message message, 
+			final Map<String,Object> globals,
+			final List<Object> objectList) throws RuleServiceException 
+	{
+		AssertArgument.isNotNullAndNotEmpty( ruleSet, "ruleSet" );
+		
+		final long startTime = System.nanoTime();
+
+		try 
+		{
+			RuleBase ruleBase = getRuleBaseForFileBasedRules(ruleSet, dsl, ruleReload);
+			message = executeStatelessRules(ruleBase, message, globals, objectList);
+
+			updateJBRulesCounter( startTime, ruleSet, JBRulesCounter.RULES_SUCCEED );
+		} 
+		catch (RuleServiceException e) 
+		{
+			updateJBRulesCounter( startTime, ruleSet, JBRulesCounter.RULES_FAILED );
+			throw e;
+		}
+		return message;
+	}
+
+	/**
+	 * Execute rules from a decision table using the Stateless rule engine API
+	 * 
+	 * @param decisionTable -
+	 *            String reference to a file which contains a spreadsheet of rules
+	 * @param ruleReload -
+	 *            if set to true, a ruleSet update should result in reloading
+	 *            the ruleSet.
+	 * @param message -
+	 *            Message that is updated with the results.
+	 * @param globals -
+	 *            Map of globals variables that should be set in the working memory
+	 * @param objectList - a list with additional objects (typically pulled from the message) to be inserted into 
+	 *            working memory 
+	 * 
+	 * @return Message with updated objects.
+	 */
+	public Message executeStatelessRulesFromDecisionTable(
+			final String decisionTable,
+			final boolean ruleReload, 
+			Message message, 
+			final Map<String,Object> globals,
+			final List<Object> objectList) throws RuleServiceException 
+	{
+		AssertArgument.isNotNullAndNotEmpty( decisionTable, "decisionTable" );
+		
+		final long startTime = System.nanoTime();
+
+		try 
+		{
+			RuleBase ruleBase = getRuleBaseForDecisionTable( decisionTable, ruleReload );
+			message = executeStatelessRules( ruleBase, message, globals, objectList );
+
+			updateJBRulesCounter( startTime, decisionTable, JBRulesCounter.RULES_SUCCEED );
+		} 
+		catch (RuleServiceException e) 
+		{
+			updateJBRulesCounter( startTime, decisionTable, JBRulesCounter.RULES_FAILED );
+			throw e;
+		}
+		return message;
+	}
+
+	/**
+	 * Execute rules using a rule package retrieved via the Rule Agent from a URL of local file system
+	 *            using the Stateless rule engine API
+	 * 
+	 * @param ruleAgentProperties -
+	 *            String reference to a file which contains properties used by the RuleAgent to locate a rule package.
+	 * @param message -
+	 *            Message that is updated with the results.
+	 * @param globals -
+	 *            Map of globals variables that should be set in the working memory
+	 * @param objectList - a list with additional objects (typically pulled from the message) to be inserted into 
+	 *            working memory 
+	 * 
+	 * @return Message with updated objects.
+	 */
+	public Message executeStatelessRulesFromRuleAgent(
+			final String ruleAgentProperties, 
+			Message message, 
+			final Map<String,Object> globals,
+			final List<Object> objectList) throws RuleServiceException 
+	{
+		AssertArgument.isNotNullAndNotEmpty( ruleAgentProperties, "ruleAgentProperties" );
+		
+		final long startTime = System.nanoTime();
+		try 
+		{
+    		final RuleBase ruleBase = getRuleBaseForRuleAgent( ruleAgentProperties ) ;
+			message = executeStatelessRules(ruleBase, message, globals, objectList);
+			updateJBRulesCounter( startTime, ruleAgentProperties, JBRulesCounter.RULES_SUCCEED );
+		} 
+		catch ( final IOException e) 
+		{
+			updateJBRulesCounter( startTime, ruleAgentProperties, JBRulesCounter.RULES_FAILED );
+			throw new RuleServiceException( "Could not read the ruleAgentProperties file [" + ruleAgentProperties + "]", e);
+		} 
+		catch ( final RuleServiceException e) 
+		{
+			updateJBRulesCounter( startTime, ruleAgentProperties, JBRulesCounter.RULES_FAILED );
+			throw e;
+		} 
+		catch ( final Exception e) 
+		{
+			updateJBRulesCounter( startTime, ruleAgentProperties, JBRulesCounter.RULES_FAILED );
+			throw new RuleServiceException( "RuleAgent could not get the RuleBase. " + e.getMessage(), e);
+		}
+		return message;
+	}
+
+	/**
+	 * Execute rules using a certain ruleSet and domain specific language using the Stateful rule engine API
+	 * 
+	 * @param ruleSet -
+	 *            String reference to a file which contains a ruleSet.
+	 * @param dsl -
+	 *            String reference to a file which contains a custom rule
+	 *            language definition(Domain Specific Language)
+	 * @param ruleReload -
+	 *            if set to true, a ruleSet update should result in reloading
+	 *            the ruleSet.
+	 * @param message -
+	 *            Message that is updated with the results.
+	 * @param globals -
+	 *            Map of globals variables that should be set in the working memory
+	 * @param objectList - a list with additional objects (typically pulled from the message) to be inserted into 
+	 *            working memory 
+	 * 
+	 * @return Message with updated objects.
+	 */
+	public Message executeStatefulRules(
+			final String ruleSet, 
+			final String dsl,
+			final boolean ruleReload, 
+			Message message,
+			final Map<String,Object> globals,
+			final List<Object> objectList) throws RuleServiceException 
+	{
+		AssertArgument.isNotNullAndNotEmpty( ruleSet, "ruleSet" );
+		
+		final long startTime = System.nanoTime();
+
+		try 
+		{
+			RuleBase ruleBase = getRuleBaseForFileBasedRules( ruleSet, dsl, ruleReload );
+			message = executeStatefulRules( ruleBase, false, message, globals, objectList );
+
+			updateJBRulesCounter( startTime, ruleSet, JBRulesCounter.RULES_SUCCEED);
+		} 
+		catch (final RuleServiceException e) 
+		{
+			updateJBRulesCounter( startTime, ruleSet, JBRulesCounter.RULES_FAILED );
+			throw e;
+		}
+		return message;
+	}
+
+	/**
+	 * Execute rules from a decision table using the Stateful rule engine API
+	 * 
+	 * @param decisionTable -
+	 *            String reference to a file which contains a spreadsheet of rules
+	 * @param ruleReload -
+	 *            if set to true, a ruleSet update should result in reloading
+	 *            the ruleSet.
+	 * @param message -
+	 *            Message that is updated with the results.
+	 * @param globals -
+	 *            Map of globals variables that should be set in the working memory
+	 * @param objectList - a list with additional objects (typically pulled from the message) to be inserted into 
+	 *            working memory 
+	 * 
+	 * @return Message with updated objects.
+	 */
+	public Message executeStatefulRulesFromDecisionTable(
+			final String decisionTable,
+			final boolean ruleReload, 
+			Message message,
+			final Map<String,Object> globals,
+			final List<Object> objectList) throws RuleServiceException 
+	{
+		AssertArgument.isNotNullAndNotEmpty( decisionTable, "decisionTable" );
+		
+		final long startTime = System.nanoTime();
+
+		try 
+		{
+			final RuleBase ruleBase = getRuleBaseForDecisionTable(decisionTable, ruleReload);
+			
+			message = executeStatefulRules(ruleBase, false, message, globals, objectList);
+
+			updateJBRulesCounter( startTime, decisionTable, JBRulesCounter.RULES_SUCCEED );
+		} 
+		catch (RuleServiceException e) 
+		{
+			updateJBRulesCounter( startTime, decisionTable, JBRulesCounter.RULES_FAILED );
+			throw e;
+		}
+		return message;
+	}
+
+	/**
+	 * Execute rules using a rule package retrieved via the Rule Agent from a URL of local file system
+	 *            using the Stateful rule engine API
+	 * 
+	 * @param ruleAgentProperties -
+	 *            String reference to a file which contains properties used by the RuleAgent to locate a rule package.
+	 * @param message -
+	 *            Message that is updated with the results.
+	 * @param globals -
+	 *            Map of globals variables that should be set in the working memory
+	 * @param objectList - a list with additional objects (typically pulled from the message) to be inserted into 
+	 *            working memory 
+	 * 
+	 * @return Message with updated objects.
+	 */
+	public Message executeStatefulRulesFromRuleAgent(
+			final String ruleAgentProperties, 
+			Message message,
+			final Map<String,Object> globals,
+			final List<Object> objectList) throws RuleServiceException 
+	{
+		AssertArgument.isNotNullAndNotEmpty( ruleAgentProperties, "ruleAgentProperties" );
+		
+		final long startTime = System.nanoTime();
+		try 
+		{
+    		final RuleBase ruleBase = getRuleBaseForRuleAgent( ruleAgentProperties ) ;
+			
+			message = executeStatefulRules(ruleBase, false, message, globals, objectList);
+
+			updateJBRulesCounter( startTime, ruleAgentProperties, JBRulesCounter.RULES_SUCCEED );
+		} 
+		catch (IOException e) 
+		{
+			updateJBRulesCounter( startTime, ruleAgentProperties, JBRulesCounter.RULES_FAILED );
+			throw new RuleServiceException( "Could not read the ruleAgentProperties. " + e.getMessage(), e);
+		} 
+		catch (RuleServiceException e) 
+		{
+			updateJBRulesCounter( startTime, ruleAgentProperties, JBRulesCounter.RULES_FAILED );
+			throw e;
+		} 
+		catch (Exception e) 
+		{
+			updateJBRulesCounter( startTime, ruleAgentProperties, JBRulesCounter.RULES_FAILED );
+			throw new RuleServiceException( "RuleAgent could not get the RuleBase. " + e.getMessage(), e);
+		}
+		return message;
+	}
+	
+	/**
+	 * Continue executing rules where the working memory already exists.
+	 * 
+	 * @param rules -
+	 *            String reference to a file, either the drl file, the decision table,
+	 *            or the ruleAgentProperties. This is used to find the ruleBase.
+	 * @param dispose -
+	 *            if set to true, working memory will be disposed after the rules are fired
+	 * @param message -
+	 *            Message that is updated with the results.
+	 * @param globals -
+	 *            Map of globals variables that should be set in the working memory
+	 * @param objectList - a list with additional objects (typically pulled from the message) to be inserted into 
+	 *            working memory 
+	 * 
+	 * @return Message with updated objects.
+	 */
+	public Message continueStatefulRulesExecution(
+			final String rules,
+			final boolean dispose, 
+			Message message, 
+			final Map<String,Object> globals,
+			final List<Object> objectList) throws RuleServiceException 
+	{
+		AssertArgument.isNotNullAndNotEmpty( rules, "rules" );
+		
+		final long startTime = System.nanoTime();
+		
+		try 
+		{
+			final Map<String, RuleBase> ruleBases = lifecycleRuleBases.getLifecycleResource();
+			final RuleBase ruleBase = ruleBases.get( rules );
+			
+			message = executeStatefulRules( ruleBase, dispose, message, globals, objectList );
+
+			updateJBRulesCounter( startTime, rules, JBRulesCounter.RULES_SUCCEED );
+		} 
+		catch (Exception e) 
+		{
+			updateJBRulesCounter( startTime, rules, JBRulesCounter.RULES_FAILED );
+			throw new RuleServiceException( "Could not continue rule execution. " + e.getMessage(), e);
+		}
+		return message;
+	}
+	
+	public void setConfigTree( final ConfigTree configTree ) 
+	{
+		rulesCounter = new JBRulesCounter( configTree );
+		rulesCounter.registerMBean();
+	}
+	
+	//	private methods 
+	
+	private void updateJBRulesCounter( final long startTime , final String rules, final String result  )
+	{
+		if (rulesCounter != null) 
+		{
+			long procTime = System.nanoTime() - startTime;
+			rulesCounter.update(procTime, rules, result );
+		}
+	}
+	
+	//	package protected methods
+	
+	/**
+	 * Determine if file based rules need reloading and return the rulebase
+	 * 
+	 * @param ruleSet -
+	 *            String reference to a file which contains a ruleSet.
+	 * @param dsl -
+	 *            String reference to a file which contains a custom rule language
+	 *            definition
+	 * @param ruleReload -
+	 *            if set to true, a ruleSet update should result in reloading the
+	 *            ruleSet.
+	 * 
+	 * @return Message with updated objects.
+	 */
+	RuleBase getRuleBaseForFileBasedRules(
+			final String ruleSet, 
+			final String dsl,
+			final boolean ruleReload) throws RuleServiceException 
+	{
+		final long startTime = System.nanoTime();
+		
+		try 
+		{
+			final DroolsRuleBaseHelper rbHelper = DroolsRuleBaseHelper.getInstance();
+
+			String newRuleSet = null;
+			boolean isRulesChanged = false;
+
+			final Map<String, String> ruleSets = lifecycleRuleSets.getLifecycleResource();
+
+            synchronized (ruleSets) {
+                if ( ruleReload )
+                {
+                    String currentRuleSet = ruleSets.get( ruleSet );
+                    newRuleSet = rbHelper.getRulesAsString( ruleSet, dsl );
+                    if ( currentRuleSet == null || !currentRuleSet.equals(newRuleSet) )
+                    {
+                        isRulesChanged = true;
+                    }
+                }
+                final Map<String, RuleBase> ruleBases = lifecycleRuleBases.getLifecycleResource();
+                RuleBase ruleBase = ruleBases.get( ruleSet );
+                if ( ruleBase == null || isRulesChanged )
+                {
+                    ruleBase = rbHelper.createRuleBaseFromRuleFiles(ruleSet, dsl);
+                    if (ruleBase != null)
+                        ruleBases.put(ruleSet, ruleBase);
+                    if (newRuleSet == null)
+                        newRuleSet = rbHelper.getRulesAsString(ruleSet, dsl);
+                    if (ruleSet != null)
+                        ruleSets.put(ruleSet, newRuleSet);
+                }
+
+                return ruleBase;
+            }            
+		} 
+		catch (final LifecycleResourceException e) 
+		{
+			updateJBRulesCounter( startTime, ruleSet, JBRulesCounter.RULES_FAILED );
+			throw new RuleServiceException("Could not load lifecycle data. " + e.getMessage(), e);
+		} 
+		catch (final IOException e) 
+		{
+			updateJBRulesCounter( startTime, ruleSet, JBRulesCounter.RULES_FAILED );
+			throw new RuleServiceException("Could not read the rules. " + e.getMessage(), e);
+		} 
+		catch (final DroolsParserException e) 
+		{
+			updateJBRulesCounter( startTime, ruleSet, JBRulesCounter.RULES_FAILED );
+			throw new RuleServiceException("Could not parse the rules. " + e.getMessage(), e);
+		} 
+		catch (final RuleServiceException e) 
+		{
+			updateJBRulesCounter( startTime, ruleSet, JBRulesCounter.RULES_FAILED );
+			throw e;
+		}
+	}
+	
+	/**
+	 * Determine if decision table need reloading and return the rulebase
+	 * 
+	 * @param decisionTable -
+	 *            String reference to a file which contains a decision table.
+	 * @param ruleReload -
+	 *            if set to true, a ruleSet update should result in reloading the
+	 *            ruleSet.
+	 * 
+	 * @return Message with updated objects.
+	 */
+	RuleBase getRuleBaseForDecisionTable(
+			final String decisionTable,
+			final boolean ruleReload ) throws RuleServiceException {
+		
+		final long startTime = System.nanoTime();
+		try 
+		{
+            Map<String, RuleBase> ruleBases = getCachedRuleBases();
+
+            synchronized (ruleBases) {
+                RuleBase ruleBase = ruleBases.get( decisionTable );
+                if ( ruleReload || ruleBase == null ) 
+                {
+                    ruleBase = DroolsRuleBaseHelper.getInstance().createRuleBaseFromDecisionTable(decisionTable);
+                    ruleBases.put( decisionTable, ruleBase );
+                }
+                return ruleBase;
+            }
+        }
+		catch (final IOException e) 
+		{
+			updateJBRulesCounter( startTime, decisionTable, JBRulesCounter.RULES_FAILED );
+			throw new RuleServiceException("Could not read the rules from [" + decisionTable + "]", e);
+		} 
+		catch (final DroolsParserException e) 
+		{
+			updateJBRulesCounter( startTime, decisionTable, JBRulesCounter.RULES_FAILED );
+			throw new RuleServiceException("Could not parse the rules in [" + decisionTable + "]", e);
+		} 
+		catch (final RuleServiceException e) 
+		{
+			updateJBRulesCounter( startTime, decisionTable, JBRulesCounter.RULES_FAILED );
+			throw e;
+		} 
+		catch (final LifecycleResourceException e)
+		{
+			updateJBRulesCounter( startTime, decisionTable, JBRulesCounter.RULES_FAILED );
+			throw new RuleServiceException("Caught a LifecycleResourceException :", e);
+		}
+	}
+	
+	/**
+	 * Execute rules using using the Stateless API
+	 * 
+	 * @param rulebase -
+	 *          the rulebase to use
+	 * @param message -
+	 *          Message that is updated with the results.
+	 * @param objectList -
+	 * 			a list with additional objects (typically pulled from the message)
+	 * 			to be inserted into working memory
+	 * @param globals -
+	 *            Map of globals variables that should be set in the working memory
+	 * 
+	 * @return Message -
+	 * 			with updated objects.
+	 */
+	Message executeStatelessRules(
+			final RuleBase ruleBase, 
+			final Message message,
+			final Map<String,Object> globals,
+			final List<Object> objectList) 
+	{
+		
+		final StatelessSession statelessSession = ruleBase.newStatelessSession();
+		final List<Object> facts = getFacts( message, objectList );
+		addGlobalsVariables( statelessSession, globals );
+		statelessSession.execute(facts);
+		return message;
+	}
+	
+	/**
+	 * Execute rules using using the Stateful API
+	 * 
+	 * @param   rulebase -
+     * 			the rulebase to use
+	 * @param dispose -
+	 * 			if true the working memory will be dereferenced.	
+	 * @param message -
+	 * 			Message that is updated with the results.
+	 * @param globals -
+	 * 			Map of globals variables that should be set in the working memory
+	 * @param objectList -
+	 * 			a list with additional objects  to be inserted into working memory
+	 * 
+	 * @return Message -
+	 * 			a possibly updated Message object. The message object is available
+	 * 			to Rules and my be updated by them.
+	 */
+	Message executeStatefulRules(
+			final RuleBase ruleBase, 
+			final boolean dispose,
+			final Message message, 
+			final Map<String,Object> globals,
+			final List<Object> objectList) 
+	{
+        synchronized (ruleBase) {
+            final StatefulSession statefulSession = getStatefulSession( ruleBase );
+            try
+            {
+                addGlobalsVariables( statefulSession, globals );
+                final List<Object> facts = getFacts( message, objectList );
+                insertObjectsIntoWorkingMemory( facts, statefulSession );
+                statefulSession.fireAllRules();
+            }
+            finally
+            {
+                if ( dispose )
+                {
+                    statefulSession.dispose();
+                }
+            }
+        }
+		
+        return message;
+	}
+	
+	private List<Object> getFacts(final Message message, final List<Object> objectList )
+	{
+		final List<Object> facts = new ArrayList<Object>();
+		facts.add( message );
+		if ( objectList != null )
+			facts.addAll( objectList );
+		return facts;
+	}
+	
+	/*
+	 * Checks whether the ruleBase has an existing session, and returns
+	 * that session, otherwise a new session is created.
+	 */
+	private StatefulSession getStatefulSession( final RuleBase ruleBase )
+	{
+        synchronized (ruleBase) {
+            final StatefulSession[] statefulSessions = ruleBase.getStatefulSessions();
+            boolean existingSession = statefulSessions != null && statefulSessions.length > 0;
+            return existingSession ? statefulSessions[0] : ruleBase.newStatefulSession();
+        }
+    }
+	
+	/*
+	 * Will set the passed-in elements in the globals Map as global
+	 * variables.
+	 */
+	private void addGlobalsVariables( final StatelessSession statelessSession, final Map<String,Object> globals )
+	{
+		if ( globals != null )
+		{
+			Set<Entry<String, Object>> entrySet = globals.entrySet();
+			for ( Entry<String, Object> entry : entrySet ) {
+				statelessSession.setGlobal( entry.getKey(), entry.getValue() );
+            }
+        }
+	}
+	
+	/*
+	 * Will set the passed-in elements in the globals Map as global
+	 * variables.
+	 */
+	private void addGlobalsVariables( final StatefulSession statefulSession, final Map<String,Object> globals )
+	{
+		if ( globals != null )
+		{
+			Set<Entry<String, Object>> entrySet = globals.entrySet();
+			for ( Entry<String, Object> entry : entrySet )
+			{
+				statefulSession.setGlobal( entry.getKey(), entry.getValue() );
+			}
+		}
+	}
+	
+	private void insertObjectsIntoWorkingMemory(final List<Object> objectList, final WorkingMemory workingMemory)
+	{
+		if (objectList != null) 
+		{
+			for (Object object : objectList) 
+			{
+				workingMemory.insert(object);
+			}
+		}
+	}
+	
+	RuleBase getRuleBaseForRuleAgent( final String ruleAgentProperties ) throws IOException, Exception
+	{
+		Map<String, RuleAgent> ruleAgents = getCachedRuleAgents();
+		RuleAgent ruleAgent = ruleAgents.get( ruleAgentProperties );
+		if ( ruleAgent == null )
+		{
+			ruleAgent = DroolsRuleBaseHelper.getInstance().createRuleAgent( ruleAgentProperties );
+			ruleAgents.put( ruleAgentProperties, ruleAgent );
+		}
+		
+		RuleBase currentRuleBase = ruleAgent.getRuleBase();
+		//	always update the cache as the rulebase might have been updated.
+		getCachedRuleBases().put( ruleAgentProperties, currentRuleBase );
+		return currentRuleBase;
+	}
+	
+	Map<String, RuleAgent> getCachedRuleAgents() throws LifecycleResourceException
+	{
+		return lifecycleRuleAgents.getLifecycleResource();
+	}
+	
+	Map<String, RuleBase> getCachedRuleBases() throws LifecycleResourceException
+	{
+		return lifecycleRuleBases.getLifecycleResource();
+	}
+	
+	/**
+	 * The lifecycle resource factory for rule sets.
+	 * 
+	 * @author kevin
+	 */
+	public static class LifecycleRuleBaseFactory implements
+			LifecycleResourceFactory<Map<String, RuleBase>> {
+		/**
+		 * Create a resource object which will be associated with the
+		 * specified lifecycle identity.
+		 * 
+		 * @param lifecycleIdentity
+		 *            The associated lifecycle identity.
+		 * @return The lifecycle resource
+		 * @throws LifecycleResourceException
+		 *             for errors during construction.
+		 */
+		public Map<String, RuleBase> createLifecycleResource(
+				final String lifecycleIdentity)
+				throws LifecycleResourceException 
+		{
+			return new ConcurrentHashMap<String, RuleBase>();
+		}
+
+		/**
+		 * Destroy a resource object which is associated with the specified
+		 * lifecycle identity.
+		 * 
+		 * @param resource
+		 *            The lifecycle resource.
+		 * @param lifecycleIdentity
+		 *            The associated lifecycle identity.
+		 * @return The lifecycle resource.
+		 * @throws LifecycleResourceException
+		 *             for errors during destroy.
+		 */
+		public void destroyLifecycleResource(
+				final Map<String, RuleBase> resource,
+				final String lifecycleIdentity)
+				throws LifecycleResourceException 
+		{
+			//	NoOp
+		}
+	}
+	
+	public static class LifecycleRuleAgentFactory implements LifecycleResourceFactory<Map<String, RuleAgent>> {
+        /**
+         * Create a resource object which will be associated with the
+         * specified lifecycle identity.
+         * 
+         * @param lifecycleIdentity
+         *            The associated lifecycle identity.
+         * @return The lifecycle resource
+         * @throws LifecycleResourceException
+         *             for errors during construction.
+         */
+        public Map<String, RuleAgent> createLifecycleResource( final String lifecycleIdentity) throws LifecycleResourceException 
+        {
+        	return new ConcurrentHashMap<String, RuleAgent>();
+        }
+    
+        /**
+         * Destroy a resource object which is associated with the specified
+         * lifecycle identity.
+         * 
+         * @param resource
+         *            The lifecycle resource.
+         * @param lifecycleIdentity
+         *            The associated lifecycle identity.
+         * @return The lifecycle resource.
+         * @throws LifecycleResourceException
+         *             for errors during destroy.
+         */
+        public void destroyLifecycleResource( final Map<String, RuleAgent> resource, final String lifecycleIdentity) throws LifecycleResourceException 
+        {
+        	//	NoOp
+        }
+    }
+
+	/**
+	 * The lifecycle resource factory for rule sets.
+	 * 
+	 * @author kevin
+	 */
+	public static class LifecycleRuleSetFactory implements
+			LifecycleResourceFactory<Map<String, String>> 
+	{
+		/**
+		 * Create a resource object which will be associated with the
+		 * specified lifecycle identity.
+		 * 
+		 * @param lifecycleIdentity
+		 *            The associated lifecycle identity.
+		 * @return The lifecycle resource
+		 * @throws LifecycleResourceException
+		 *             for errors during construction.
+		 */
+		public Map<String, String> createLifecycleResource(
+				final String lifecycleIdentity)
+				throws LifecycleResourceException 
+		{
+			return new ConcurrentHashMap<String, String>();
+		}
+
+		/**
+		 * Destroy a resource object which is associated with the specified
+		 * lifecycle identity.
+		 * 
+		 * @param resource
+		 *            The lifecycle resource.
+		 * @param lifecycleIdentity
+		 *            The associated lifecycle identity.
+		 * @return The lifecycle resource.
+		 * @throws LifecycleResourceException
+		 *             for errors during destroy.
+		 */
+		public void destroyLifecycleResource(
+				final Map<String, String> resource,
+				final String lifecycleIdentity)
+				throws LifecycleResourceException 
+		{
+			// NoOp
+		}
+	}
+	
+}

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleServiceBuilderException.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleServiceBuilderException.java	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleServiceBuilderException.java	2008-11-05 13:39:40 UTC (rev 23714)
@@ -0,0 +1,76 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * 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.jboss.internal.soa.esb.services.rules;
+
+import org.drools.compiler.PackageBuilderErrors;
+
+/**
+ * RuleServiceBuilderException adds {@link PackageBuilderErrors}.
+ * <p/>
+ * @author <a href="mailto:dbevenius at redhat.com">Daniel Bevenius</a>
+ *
+ */
+public class RuleServiceBuilderException extends RuleServiceException
+{
+	private static final long serialVersionUID = 1L;
+	
+	private PackageBuilderErrors builderErrors;
+
+	public RuleServiceBuilderException()
+	{
+		super();
+	}
+
+	public RuleServiceBuilderException(String msg, Throwable cause)
+	{
+		super( msg, cause );
+	}
+
+	public RuleServiceBuilderException(String msg)
+	{
+		super( msg );
+	}
+
+	public RuleServiceBuilderException(Throwable cause)
+	{
+		super( cause );
+	}
+	
+	public RuleServiceBuilderException(String msg, PackageBuilderErrors builderErrors)
+	{
+		super( msg );
+		this.builderErrors = builderErrors;
+	}
+	
+	public RuleServiceBuilderException(String msg, Throwable cause, PackageBuilderErrors builderErrors)
+	{
+		super( msg, cause );
+		this.builderErrors = builderErrors;
+	}
+
+	public PackageBuilderErrors getBuilderErrors()
+	{
+		return builderErrors;
+	}
+
+}

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleServiceCallHelper.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleServiceCallHelper.java	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleServiceCallHelper.java	2008-11-05 13:39:40 UTC (rev 23714)
@@ -0,0 +1,168 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * 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.jboss.internal.soa.esb.services.rules;
+
+import static org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.CONTINUE;
+import static org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.DECISION_TABLE;
+import static org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.RULE_AGENT_PROPERTIES;
+import static org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.DISPOSE;
+import static org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.IMPL_CLASS;
+import static org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.STATEFUL;
+import java.util.List;
+import java.util.Map;
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.listeners.ListenerTagNames;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.services.rules.RuleService;
+import org.apache.log4j.Logger;
+
+/**
+ * RuleServiceCallHelper is a util class for calling
+ * methods on a {@link RuleService} implementation.
+ * </p>
+ * 
+ * @author <a href="mailto:dbevenius at redhat.com">Daniel Bevenius</a>
+ *
+ */
+public class RuleServiceCallHelper
+{
+
+    private static Logger logger = Logger.getLogger(RuleServiceCallHelper.class);
+
+    private RuleServiceCallHelper()
+	{
+		throw new AssertionError();
+	}
+	
+	/**
+	 * This helper method delegates to the configured RuleService implementation.
+	 * <p/>
+	 * If the message object instance has a property 'continue' set to true, this method
+	 * will invoke {@link RuleService#continueStatefulRulesExecution(String, boolean, Message, Map, List)}.
+	 * This will continue an existing stateful session.
+	 * <br>
+	 * <br>
+	 * Otherwise this method will delete one of the stateless or stateful methods in RuleService 
+	 * depending on the configuration property 'stateful' is true or false. Default is stateless.
+	 * 
+	 * @param ruleSet -
+	 *            String reference to a file which contains a ruleSet.
+	 * @param ruleLanguage -
+	 *            String reference to a file which contains a custom rule
+	 *            language definition
+	 * @param ruleReload -
+	 *            if set to true, a ruleSet update should result in reloading the ruleSet.
+	 * @param message -
+	 *            Message that is updated with the results.
+	 * @param objectList - 
+	 * 			  a list with additional objects (typically pulled from the message) to be inserted into 
+	 *            working memory 
+	 * @param globals -
+	 *            Map of globals variables that should be set in the working memory
+	 * @param configTree -
+	 * 			  configuration instance to access properties from jboss-esb.xml
+	 * @return Message	-
+	 * 			  the ESB Message object which might have been updated.
+	 * @throws RuleServiceException
+	 */
+	public static Message executeRulesService( 
+			String ruleSet,
+			final String ruleLanguage,
+			final boolean ruleReload,
+			Message message, 
+			final List<Object> objectList,
+			final Map<String, Object> globals,
+			final ConfigTree configTree ) throws RuleServiceException 
+	{
+		final String ruleServiceImpl = configTree.getAttribute( IMPL_CLASS.getTagName(), "org.jboss.internal.soa.esb.services.rules.DroolsRuleService" );
+		final RuleService ruleService = RuleServiceFactory.getRuleService( ruleServiceImpl );
+		ruleService.setConfigTree( configTree );
+		
+		final String decisionTable = configTree.getAttribute( DECISION_TABLE.getTagName() );
+		final String ruleAgent = configTree.getAttribute( RULE_AGENT_PROPERTIES.getTagName() );
+
+        if(logger.isDebugEnabled()) {
+            final boolean isRuleReloadSpecified = (configTree.getAttribute(ListenerTagNames.RULE_RELOAD_TAG) != null);
+            if (ruleAgent != null && isRuleReloadSpecified) {
+                logger.debug("'" + ListenerTagNames.RULE_RELOAD_TAG + "' is specified on the same configuration as a Rule Agent configuration is specified.  Ignoring the '" + ListenerTagNames.RULE_RELOAD_TAG + "' configuration.");
+            }
+        }
+
+        final Boolean continueStateful = (Boolean) message.getProperties().getProperty( CONTINUE.getTagName(), Boolean.FALSE );
+		if ( continueStateful )
+		{
+			//	ruleSet can be a rule file, decisiontable or a ruleAgent properties file for continueStatefulRules
+			if ( ruleSet == null )
+				ruleSet = decisionTable != null ? decisionTable : ruleAgent;  
+			
+			message = ruleService.continueStatefulRulesExecution( ruleSet, getDisposeProperty( message ), message, globals, objectList );
+		}
+		else
+		{
+    		final boolean stateful = Boolean.valueOf( configTree.getAttribute( STATEFUL.getTagName()) );
+		
+    		if ( stateful )
+    		{
+    			if ( ruleSet != null )
+        			message = ruleService.executeStatefulRules( ruleSet, ruleLanguage, ruleReload, message, globals, objectList );
+    			else if ( decisionTable != null )
+        			message =  ruleService.executeStatefulRulesFromDecisionTable( decisionTable, ruleReload, message, globals, objectList );
+    			else if ( ruleAgent != null )
+        			message = ruleService.executeStatefulRulesFromRuleAgent( ruleAgent, message, globals, objectList );
+    			else
+    				throwRuleServiceException();
+    		}
+    		else
+    		{
+    			if ( ruleSet != null )
+        			message = ruleService.executeStatelessRules( ruleSet, ruleLanguage, ruleReload, message, globals, objectList );
+    			else if ( decisionTable != null )
+        			message = ruleService.executeStatelessRulesFromDecisionTable( decisionTable, ruleReload, message, globals, objectList );
+    			else if ( ruleAgent != null )
+        			message = ruleService.executeStatelessRulesFromRuleAgent( ruleAgent, message, globals, objectList );
+    			else
+    				throwRuleServiceException();
+    		}
+		}
+		return message;
+	}
+	
+	//	private static methods
+	
+	private static void throwRuleServiceException() throws RuleServiceException
+	{
+		throw new RuleServiceException( "One of '" + ListenerTagNames.RULE_SET_TAG + "', '" + DECISION_TABLE.getTagName() + "', or ' " + RULE_AGENT_PROPERTIES.getTagName() + "'must be specified as properties in jboss-esb.xml");
+	}
+	
+	private static boolean getDisposeProperty( final Message message ) throws RuleServiceException
+	{
+		Object dispose = message.getProperties().getProperty( DISPOSE.getTagName() );
+		if ( dispose == null )
+		{
+			throw new RuleServiceException("The property [" + DISPOSE.getTagName() + "] must be specified when [" +
+					CONTINUE.getTagName() + "] is true. This is required as it is important that the rules working memory "+
+					" be disposed or memory leaks can occur.");
+		}
+		return (Boolean)dispose;
+	}
+
+}

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleServiceException.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleServiceException.java	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleServiceException.java	2008-11-05 13:39:40 UTC (rev 23714)
@@ -0,0 +1,47 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * 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.jboss.internal.soa.esb.services.rules;
+
+/**
+ * @author jdelong at redhat.com
+ * 
+ */
+public class RuleServiceException extends Exception {
+	private static final long serialVersionUID = 1L;
+
+	public RuleServiceException() {
+		super();
+	}
+
+	public RuleServiceException(String msg) {
+		super(msg);
+	}
+
+	public RuleServiceException(Throwable cause) {
+		super(cause);
+	}
+
+	public RuleServiceException(String msg, Throwable cause) {
+		super(msg, cause);
+	}
+}

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleServiceFactory.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleServiceFactory.java	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleServiceFactory.java	2008-11-05 13:39:40 UTC (rev 23714)
@@ -0,0 +1,63 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * 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.jboss.internal.soa.esb.services.rules;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.jboss.soa.esb.services.rules.RuleService;
+import org.jboss.soa.esb.util.ClassUtil;
+/**
+ * Returns an instance of the RuleService.
+ *
+ * @author jdelong at redhat.com
+ *
+ */
+public class RuleServiceFactory {
+	private static Logger logger = Logger.getLogger(RuleServiceFactory.class);
+
+	/**
+	 * This factory returns a ruleService
+	 * 
+	 * @author jdelong at redhat.com
+	 * 
+	 */
+	public static RuleService getRuleService(String className)
+			throws RuleServiceException {
+		RuleService rs = null;
+		logger.log(Level.DEBUG, "Going to load " + className);
+		try {
+			// instruct class loader to load the RuleService Implementation
+			Class rsClass = ClassUtil.forName(className,
+					RuleServiceFactory.class);
+			// Try to get an instance of the RS
+			rs = (RuleService) rsClass.newInstance();
+		} catch (ClassNotFoundException cnfex) {
+			throw new RuleServiceException("RuleService Implementation="
+					+ className + " not found", cnfex);
+		} catch (Exception e) {
+			throw new RuleServiceException(className + " invocation problem. "
+					+ e.getLocalizedMessage(), e);
+		}
+		return rs;
+	}
+}

Modified: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/soa/esb/actions/BusinessRulesProcessor.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/soa/esb/actions/BusinessRulesProcessor.java	2008-11-05 12:54:27 UTC (rev 23713)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/soa/esb/actions/BusinessRulesProcessor.java	2008-11-05 13:39:40 UTC (rev 23714)
@@ -27,8 +27,12 @@
  */
 package org.jboss.soa.esb.actions;
 
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
+import org.jboss.internal.soa.esb.services.rules.RuleServiceCallHelper;
+import org.jboss.internal.soa.esb.services.rules.RuleServiceException;
 import org.jboss.soa.esb.ConfigurationException;
 import org.jboss.soa.esb.helpers.ConfigTree;
 import org.jboss.soa.esb.message.Message;
@@ -36,16 +40,50 @@
 import org.jboss.soa.esb.services.registry.RegistryException;
 import org.jboss.soa.esb.services.routing.MessageRouterException;
 
+/**
+ * BusinessRulesProcessor extends {@link ContentBasedRouter} but does not perform any routing, it only 
+ * executes the business rules.
+ * <p/>
+ * 
+ * Configuration Example:
+ *<pre>{@code
+ *
+ *<action class="org.jboss.soa.esb.actions.BusinessRulesProcessor" name="YourCBRName">
+ *    <property name="ruleSet" value="OrderDiscountOnMultipleOrders.drl" />
+ *    <property name="ruleReload" value="false" />
+ *    <property name="stateful" value="true" />
+ *    <property name="object-paths">
+ *        <object-path esb="body.TheOrderHeader" />
+ *        <object-path esb="body.TheCustomer" />
+ *    </property>
+ *</action>
+ *
+ * As this class extends {@link ContentBasedRouter} please see its javadoc for 
+ * configuration descriptions that are common to both classes.
+ * 
+ * Property description:
+ * <lu>
+ * <li> <i> class </i> action class, org.jboss.soa.esb.actions.BusinessRulesProcessor
+ * <li> <i> stateful </i> Optional property which tells the RuleService to use a stateful session where facts will be remembered between invokations.
+ * </lu>
+ * </br>
+ * 
+ * 
+ * @author John Doe
+ * @author <a href="mailto:dbevenius at redhat.com">Daniel Bevenius</a>
+ *
+ */
 public class BusinessRulesProcessor extends ContentBasedRouter
 {
+	private ConfigTree configTree;
+	
 	public BusinessRulesProcessor(ConfigTree config) throws ConfigurationException, RegistryException, MessageRouterException
 	{
         super(config);
+        this.configTree = config;
 	}
 	/** 
      * Inspect the content of the message using a rule set 
-     * Router the message to one or more destinations, using the ContentBasedRouter to figure out
-     * to which destinations it is going to be routed too. 
      *  
      * @param message
      * @return Message
@@ -53,16 +91,34 @@
 	 */
 	public Message process(Message message) throws ActionProcessingException
 	{
-        try {
+        try 
+        {
             List<Object> objectList = _mapper.createObjectList(message, _messagePathList);
-            _cbr.route(_ruleSet, _ruleLanguage, _ruleReload, message, objectList);
-        } catch (ObjectMappingException ome) {
-            throw new ActionProcessingException(ome.getMessage(), ome);
-        } catch (MessageRouterException mre) {
-            throw new ActionProcessingException(mre.getMessage(), mre);
+            message = executeRulesService( message, objectList );
+        } 
+        catch (final ObjectMappingException e) 
+        {
+            throw new ActionProcessingException( e.getMessage(), e);
+        } 
+        catch (final RuleServiceException e) 
+        {
+            throw new ActionProcessingException( e.getMessage(), e);
         }
 		return message;
 	}
+	
+	/**
+	 * 
+	 * @param message
+	 * @param objectList
+	 * @throws RuleServiceException 
+	 * @throws MessageRouterException
+	 */
+	Message executeRulesService( final Message message, final List<Object> objectList) throws RuleServiceException 
+	{
+		Map<String,Object> globals = new HashMap<String,Object>();
+		globals.put( "message", message );
+		return RuleServiceCallHelper.executeRulesService( _ruleSet, _ruleLanguage, _ruleReload, message, objectList, globals, configTree )  ;
+	}
     
-    
 }

Modified: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/soa/esb/actions/ContentBasedWiretap.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/soa/esb/actions/ContentBasedWiretap.java	2008-11-05 12:54:27 UTC (rev 23713)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/soa/esb/actions/ContentBasedWiretap.java	2008-11-05 13:39:40 UTC (rev 23714)
@@ -44,10 +44,56 @@
 import org.jboss.soa.esb.services.routing.cbr.ContentBasedRouterFactory;
 
 /**
- * @author <a
- *         href="mailto:schifest at heuristica.com.ar">schifest at heuristica.com.ar</a>
+ * ContentBasedWirtap implements the WireTap pattern. 
+ * The WireTap is an Enterprise Integration Pattern (EIP) where a copy of the message is 
+ * sent to a control channel.
+ * <br>
+ * The CBR­WT is identical in functionality to the ContentBasedRouter, 
+ * however it does not terminate the pipeline which makes it suitable to be used as a WireTap. 
+ * <p/> 
+ * 
+ * Configuration Example:
+ *<pre>{@code
+ *
+ *<action class="org.jboss.soa.esb.actions.ContentBasedRouter" name="OrderDiscountBasedOnCustomerHistory">
+ *    <property name="ruleSet" value="OrderDiscountOnMultipleOrders.drl" />
+ *    <property name="ruleReload" value="false" />
+ *    <property name="stateful" value="true" />
+ *    <property name="object-paths">
+ *        <object-path esb="body.TheOrderHeader" />
+ *        <object-path esb="body.TheCustomer" />
+ *    </property>
+ *    <property name="destinations">
+ *        <route-to destination-name="blue"  service-category="BlueTeam"  service-name="GoBlue" />
+ *        <route-to destination-name="red"   service-category="RedTeam"   service-name="GoRed" />
+ *        <route-to destination-name="green" service-category="GreenTeam" service-name="GoGreen" />
+ *    </property>
+ *</action>
+ *
+ * }</pre>
+ * Property description:
+ * <lu>
+ * <li> <i>class</i>		action class, one of : org.jboss.soa.esb.actions.ContentBasedRouter, org.jboss.soa.esb.actions.ContentBasedWireTap,<br>
+ * 							or org.jboss.soa.esb.actions.MessageFilter
+ * <li> <i>ruleSet</i>		Name of the filename containing the Drools ruleSet.
+ * <li> <i>ruleLanguage</i>	Optional reference to a file containing the definition of a Domain Specific Language to be used for evaluating 
+ * 							the rule set.
+ * <li> <i>ruleReload</i>	Optional property which can be to true to enable 'hot' redeployment of rule sets. 
+ * <li> <i>stateful</i>		Optional property which tells the RuleService to use a stateful session where facts will be 
+ * 							remembered between invokations.
+ * <li> <i>object-paths</i> Optional property to pass Message objects into Rule Services WorkingMemory.
+ * <li> <i>destinations</i> A set of route-­to properties each containing the logical name 
+ * 							of the destination along with the Service category and name 
+ *  						as referenced in the registry.<br> The logical name is the name 
+ *  						which should be used in the rule set.
+ * </lu>
+ * </br>
+ * 
+ * 
+ * @author <a href="mailto:schifest at heuristica.com.ar">schifest at heuristica.com.ar</a>
  * @author kstam at jboss.com
  * @author kevin.conner at jboss.com
+ * @author <a href="mailto:dbevenius at redhat.com">Daniel Bevenius</a>
  */
 public class ContentBasedWiretap extends AbstractActionPipelineProcessor {
 
@@ -73,15 +119,11 @@
         try {
             dlQueueInvoker = new ServiceInvoker(ServiceInvoker.INTERNAL_SERVICE_CATEGORY, ServiceInvoker.DEAD_LETTER_SERVICE_NAME);
         } catch (MessageDeliverException e) {
-            new MessageRouterException(e);
+            throw new MessageRouterException(e);
         }
     }
 
-    public void initialise() {
-        if (messageMulticaster.getRecipientCount() == 0) { 
-            _logger.info("Missing or empty destination list - This action class won't have any effect");
-        }
-    }
+    public void initialise() { }
 
     /**
      * Router the message to one or more destinations, using the
@@ -157,25 +199,13 @@
      * @throws ConfigurationException
      */
     protected void checkMyParms() throws ConfigurationException {
-        if (_config.getAttribute(ListenerTagNames.RULE_SET_TAG) == null) {
-            _logger.error("Required attribute " + ListenerTagNames.RULE_SET_TAG
-                    + " not found in " + _config.getName() + ".");
-            throw new ConfigurationException("Required attribute "
-                    + ListenerTagNames.RULE_SET_TAG + " not found.");
-        } else {
-            _ruleSet = _config.getAttribute(ListenerTagNames.RULE_SET_TAG);
-            if (_ruleSet == null) {
-                throw new ConfigurationException("Required attribute "
-                        + ListenerTagNames.RULE_SET_TAG + " not found.");
-            }
-            _ruleLanguage = _config
-                    .getAttribute(ListenerTagNames.RULE_LANGUAGE_TAG);
-            String ruleReload = _config
-                    .getAttribute(ListenerTagNames.RULE_RELOAD_TAG);
-            if (ruleReload != null && "true".equals(ruleReload)) {
-                _ruleReload = true;
-            }
+        _ruleSet = _config.getAttribute(ListenerTagNames.RULE_SET_TAG);
+        _ruleLanguage = _config.getAttribute(ListenerTagNames.RULE_LANGUAGE_TAG);
+        String ruleReload = _config.getAttribute(ListenerTagNames.RULE_RELOAD_TAG);
+        if (ruleReload != null && "true".equals(ruleReload)) {
+            _ruleReload = true;
         }
+            
         if (_config.getAttribute(ListenerTagNames.CBR_CLASS) != null) {
             _cbrClass = _config.getAttribute(ListenerTagNames.CBR_CLASS);
         } else {

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/soa/esb/services/rules/RuleService.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/soa/esb/services/rules/RuleService.java	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/soa/esb/services/rules/RuleService.java	2008-11-05 13:39:40 UTC (rev 23714)
@@ -0,0 +1,208 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * 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.jboss.soa.esb.services.rules;
+
+import java.util.List;
+import java.util.Map;
+
+import org.jboss.internal.soa.esb.services.rules.RuleServiceException;
+import org.jboss.soa.esb.helpers.ConfigTree;
+
+import org.jboss.soa.esb.message.Message;
+
+/**
+ * RulesEngine Interface. Separates implementation from the runtime, allowing
+ * the ESB to support different implementations of rule engines.
+ * 
+ * @author jdelong at redhat.com
+ * 
+ */
+public interface RuleService {
+	
+	public void setConfigTree(ConfigTree configTree);
+
+	/**
+	 * Execute rules using a certain ruleSet and domain specific language using the Stateless rule engine API
+	 * 
+	 * @param ruleSet -
+	 *            String reference to a file which contains a ruleSet.
+	 * @param dsl -
+	 *            String reference to a file which contains a custom rule
+	 *            language definition
+	 * @param ruleReload -
+	 *            if set to true, a ruleSet update should result in reloading
+	 *            the ruleSet.
+	 * @param message -
+	 *            Message that is updated with the results.
+	 * @param objectList - a list with additional objects (typically pulled from the message) to be inserted into 
+	 *            working memory 
+	 * 
+	 * @return Message with updated objects.
+	 */
+	public Message executeStatelessRules(
+			String ruleSet, 
+			String dsl,
+			boolean ruleReload, 
+			Message message, 
+			Map<String,Object> globals, 
+			List<Object> objectList) throws RuleServiceException;
+
+	/**
+	 * Execute rules from a decision table using the Stateless rule engine API
+	 * 
+	 * @param decisionTable -
+	 *            String reference to a file which contains a spreadsheet of rules
+	 * @param ruleReload -
+	 *            if set to true, a ruleSet update should result in reloading
+	 *            the ruleSet.
+	 * @param message -
+	 *            Message that is updated with the results.
+	 * @param objectList - a list with additional objects (typically pulled from the message) to be inserted into 
+	 *            working memory 
+	 * 
+	 * @return Message with updated objects.
+	 */
+	public Message executeStatelessRulesFromDecisionTable(
+			String decisionTable,
+			boolean ruleReload, 
+			Message message, 
+			Map<String,Object> globals, 
+			List<Object> objectList) throws RuleServiceException;
+
+	/**
+	 * Execute rules using a rule package retrieved via the Rule Agent from a URL of local file system
+	 *            using the Stateless rule engine API
+	 * 
+	 * @param ruleAgentProperties -
+	 *            String reference to a file which contains properties used by the RuleAgent to locate a rule package.
+	 * @param message -
+	 *            Message that is updated with the results.
+	 * @param objectList - a list with additional objects (typically pulled from the message) to be inserted into 
+	 *            working memory 
+	 * 
+	 * @return Message with updated objects.
+	 */
+	public Message executeStatelessRulesFromRuleAgent(
+			String ruleAgentProperties, 
+			Message message, 
+			Map<String,Object> globals, 
+			List<Object> objectList) throws RuleServiceException;
+
+	/**
+	 * Execute rules using a certain ruleSet and domain specific language using the Stateful rule engine API
+	 * 
+	 * @param ruleSet -
+	 *            String reference to a file which contains a ruleSet.
+	 * @param dsl -
+	 *            String reference to a file which contains a custom rule
+	 *            language definition
+	 * @param ruleReload -
+	 *            if set to true, a ruleSet update should result in reloading
+	 *            the ruleSet.
+	 * @param dispose -
+	 *            if set to true, working memory will be disposed after the rules are fired
+	 * @param message -
+	 *            Message that is updated with the results.
+	 * @param objectList - a list with additional objects (typically pulled from the message) to be inserted into 
+	 *            working memory 
+	 * 
+	 * @return Message with updated objects.
+	 */
+	public Message executeStatefulRules(
+			String ruleSet, 
+			String dsl,
+			boolean ruleReload, 
+			Message message,
+			Map<String,Object> globals,
+			List<Object> objectList) throws RuleServiceException;
+
+	/**
+	 * Execute rules from a decision table using the Stateful rule engine API
+	 * 
+	 * @param decisionTable -
+	 *            String reference to a file which contains a spreadsheet of rules
+	 * @param ruleReload -
+	 *            if set to true, a ruleSet update should result in reloading
+	 *            the ruleSet.
+	 * @param dispose -
+	 *            if set to true, working memory will be disposed after the rules are fired
+	 * @param message -
+	 *            Message that is updated with the results.
+	 * @param objectList - a list with additional objects (typically pulled from the message) to be inserted into 
+	 *            working memory 
+	 * 
+	 * @return Message with updated objects.
+	 */
+	public Message executeStatefulRulesFromDecisionTable(
+			String decisionTable,
+			boolean ruleReload, 
+			Message message, 
+			Map<String,Object> globals,
+			List<Object> objectList) throws RuleServiceException;
+
+	/**
+	 * Execute rules using a rule package retrieved via the Rule Agent from a URL of local file system
+	 *            using the Stateful rule engine API
+	 * 
+	 * @param ruleAgentProperties -
+	 *            String reference to a file which contains properties used by the RuleAgent to locate a rule package.
+	 * @param dispose -
+	 *            if set to true, working memory will be disposed after the rules are fired
+	 * @param message -
+	 *            Message that is updated with the results.
+	 * @param objectList - a list with additional objects (typically pulled from the message)t o be inserted into 
+	 *            working memory 
+	 * 
+	 * @return Message with updated objects.
+	 */
+	public Message executeStatefulRulesFromRuleAgent(
+			String ruleAgentProperties, 
+			Message message,
+			Map<String,Object> globals,
+			List<Object> objectList) throws RuleServiceException;
+
+	/**
+	 * Continue executing rules where the working memory already exists.
+	 * 
+	 * @param rules -
+	 *            String reference to a file, either the drl file, the decision table,
+	 *            or the ruleAgentProperties. This is used to find the ruleBase.
+	 * @param dispose -
+	 *            if set to true, working memory will be disposed after the rules are fired
+	 * @param message -
+	 *            Message that is updated with the results.
+	 * @param globals -
+	 *            Map of globals variables that should be set in the working memory
+	 * @param objectList - a list with additional objects (typically pulled from the message) to be inserted into 
+	 *            working memory 
+	 * 
+	 * @return Message with updated objects.
+	 */
+	public Message continueStatefulRulesExecution(
+			String rules,
+			boolean dispose, 
+			Message message,
+			Map<String,Object> globals, 
+			List<Object> objectList) throws RuleServiceException;
+	
+}

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/soa/esb/services/rules/RuleServicePropertiesNames.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/soa/esb/services/rules/RuleServicePropertiesNames.java	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/java/org/jboss/soa/esb/services/rules/RuleServicePropertiesNames.java	2008-11-05 13:39:40 UTC (rev 23714)
@@ -0,0 +1,52 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * 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.jboss.soa.esb.services.rules;
+/**
+ * This enum contains properties specific for a RuleService.
+ * <p/>
+ * 
+ * @author <a href="mailto:dbevenius at redhat.com">Daniel Bevenius</a>
+ *
+ */
+public enum RuleServicePropertiesNames {
+
+	IMPL_CLASS ( "ruleServiceImplClass" ),
+	DECISION_TABLE ( "decisionTable" ),
+	RULE_AGENT_PROPERTIES ( "ruleAgentProperties" ),
+	DISPOSE ( "dispose" ),
+	CONTINUE ( "continue" ),
+	STATEFUL ( "stateful") ;
+	
+	private final String tagName;
+
+	private RuleServicePropertiesNames( final String tagName )
+	{
+		this.tagName = tagName;
+	}
+	
+	public String getTagName()
+	{
+		return tagName;
+	}
+	
+}

Modified: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/resources/XPathLanguage.dsl
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/resources/XPathLanguage.dsl	2008-11-05 12:54:27 UTC (rev 23713)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/main/resources/XPathLanguage.dsl	2008-11-05 13:39:40 UTC (rev 23714)
@@ -5,3 +5,9 @@
 [when]xpathLessThan "{xpath}", "{value}"=msg : org.jboss.soa.esb.message.Message( type == org.jboss.soa.esb.message.format.MessageType.JBOSS_XML ) and eval( org.jboss.internal.soa.esb.services.routing.cbr.DslHelper.xmlContentLessThan(msg, "{xpath}", "{value}") )
 [then]Log : "{message}"=System.out.println("{message}");
 [then]Destination : "{message}"=destinations.add("{message}");
+
+# Namespace(NS) aware methods
+[when]xpathMatch expr "{xpath}" use namespaces "{namespaces}"=msg : org.jboss.soa.esb.message.Message( type == org.jboss.soa.esb.message.format.MessageType.JBOSS_XML ) and eval( org.jboss.internal.soa.esb.services.routing.cbr.DslHelper.xmlContentMatches(msg, "{xpath}",org.jboss.internal.soa.esb.services.routing.cbr.DslHelper.parseNamespaces("{namespaces}")) )
+[when]xpathEquals expr "{xpath}", "{value}" use namespaces "{namespaces}"=msg : org.jboss.soa.esb.message.Message( type == org.jboss.soa.esb.message.format.MessageType.JBOSS_XML ) and eval( org.jboss.internal.soa.esb.services.routing.cbr.DslHelper.xmlContentEquals(msg, "{xpath}", "{value}",org.jboss.internal.soa.esb.services.routing.cbr.DslHelper.parseNamespaces("{namespaces}")))
+[when]xpathGreaterThan expr "{xpath}", "{value}" use namespaces "{namespaces}"=msg : org.jboss.soa.esb.message.Message( type == org.jboss.soa.esb.message.format.MessageType.JBOSS_XML ) and eval( org.jboss.internal.soa.esb.services.routing.cbr.DslHelper.xmlContentGreaterThan(msg, "{xpath}", "{value}",org.jboss.internal.soa.esb.services.routing.cbr.DslHelper.parseNamespaces("{namespaces}") ) )
+[when]xpathLessThan expr "{xpath}", "{value}" use namespaces "{namespaces}"=msg : org.jboss.soa.esb.message.Message( type == org.jboss.soa.esb.message.format.MessageType.JBOSS_XML ) and eval( org.jboss.internal.soa.esb.services.routing.cbr.DslHelper.xmlContentLessThan(msg, "{xpath}", "{value}", org.jboss.internal.soa.esb.services.routing.cbr.DslHelper.parseNamespaces("{namespaces}") ))
\ No newline at end of file

Deleted: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/routing/cbr/BusinessProcessorRoutingUnitTest.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/routing/cbr/BusinessProcessorRoutingUnitTest.java	2008-11-05 12:54:27 UTC (rev 23713)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/routing/cbr/BusinessProcessorRoutingUnitTest.java	2008-11-05 13:39:40 UTC (rev 23714)
@@ -1,114 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2006, 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.jboss.internal.soa.esb.services.routing.cbr;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.List;
-
-import junit.framework.JUnit4TestAdapter;
-
-import org.jboss.soa.esb.message.Message;
-import org.jboss.soa.esb.message.format.MessageFactory;
-import org.jboss.soa.esb.message.format.MessageType;
-import org.jboss.soa.esb.message.mapping.ObjectMapper;
-import org.jboss.soa.esb.message.mapping.ObjectMappingException;
-import org.jboss.soa.esb.services.routing.MessageRouterException;
-import org.junit.Test;
-
-/**
- * 
- * @author kurt.stam at redhat.com
- *
- */
-public class BusinessProcessorRoutingUnitTest
-{
-	@Test
-	public void discount() throws ObjectMappingException
-	{
-        //new messages
-		Message message = MessageFactory.getInstance().getMessage(MessageType.JAVA_SERIALIZED);
-		Order order = new Order();
-        order.setQuantity(20);
-        order.setUnitPrice(new BigDecimal("20.0"));
-		message.getBody().add("Order", order);
-        //extract the order from the message, so the drl can process it
-        List<String> messagePathList = new ArrayList<String>();
-        messagePathList.add("body.Order");
-        ObjectMapper mapper = new ObjectMapper();
-        List<Object> objectList = mapper.createObjectList(message, messagePathList);
-        //Now send to the rules engine
-		JBossRulesRouter jbossRulesRouter = new JBossRulesRouter();
-        try {
-    		List<String> destinations = jbossRulesRouter.route("JBossESBPricingRoutingRules.drl", false, message, objectList);
-            assertEquals(order.getDiscount(),10.0);
-            assertEquals("10%",message.getBody().get("DiscountObject"));
-            String shippingDestination = destinations.iterator().next();
-            System.out.println(shippingDestination);
-            assertEquals("express-shipping-destination", shippingDestination);
-           
-        } catch (MessageRouterException mre) {
-            System.out.println("Exception was thrown.");
-            mre.printStackTrace();
-            assertTrue(false);
-        }
-	}
-    
-    @Test
-    public void nodiscount() throws ObjectMappingException
-    {
-        //new messages
-        Message message = MessageFactory.getInstance().getMessage(MessageType.JAVA_SERIALIZED);
-        Order order = new Order();
-        order.setQuantity(2);
-        order.setUnitPrice(new BigDecimal("20.0"));
-        message.getBody().add("Order", order);
-//      extract the order from the message, so the drl can process it
-        List<String> messagePathList = new ArrayList<String>();
-        messagePathList.add("body.Order");
-        ObjectMapper mapper = new ObjectMapper();
-        List<Object> objectList = mapper.createObjectList(message, messagePathList);
-        //Now send to the rules engine
-        JBossRulesRouter jbossRulesRouter = new JBossRulesRouter();
-        try {
-            List<String> destinations = jbossRulesRouter.route("JBossESBPricingRoutingRules.drl", false, message, objectList);
-            assertEquals(order.getDiscount(),0.0);
-            assertEquals("0%",message.getBody().get("DiscountObject"));
-            String shippingDestination = destinations.iterator().next();
-            System.out.println(shippingDestination);
-            assertEquals("normal-shipping-destination", shippingDestination);
-           
-        } catch (MessageRouterException mre) {
-            System.out.println("Exception was thrown.");
-            mre.printStackTrace();
-            assertTrue(false);
-        }
-    }
-	
-	public static junit.framework.Test suite() {
-		return new JUnit4TestAdapter(BusinessProcessorRoutingUnitTest.class);
-	}
-
-}

Deleted: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/routing/cbr/BusinessProcessorUnitTest.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/routing/cbr/BusinessProcessorUnitTest.java	2008-11-05 12:54:27 UTC (rev 23713)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/routing/cbr/BusinessProcessorUnitTest.java	2008-11-05 13:39:40 UTC (rev 23714)
@@ -1,80 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2006, 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.jboss.internal.soa.esb.services.routing.cbr;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.List;
-
-import junit.framework.JUnit4TestAdapter;
-
-import org.jboss.soa.esb.message.Message;
-import org.jboss.soa.esb.message.format.MessageFactory;
-import org.jboss.soa.esb.message.format.MessageType;
-import org.jboss.soa.esb.message.mapping.ObjectMapper;
-import org.jboss.soa.esb.message.mapping.ObjectMappingException;
-import org.jboss.soa.esb.services.routing.MessageRouterException;
-import org.junit.Test;
-
-/**
- * 
- * @author kurt.stam at redhat.com
- *
- */
-public class BusinessProcessorUnitTest
-{
-	@Test
-	public void discount() throws ObjectMappingException
-	{
-        //new messages
-		Message message = MessageFactory.getInstance().getMessage(MessageType.JAVA_SERIALIZED);
-		Order order = new Order();
-        order.setQuantity(20);
-        order.setUnitPrice(new BigDecimal("20.0"));
-		message.getBody().add("Order", order);
-//      extract the order from the message, so the drl can process it
-        List<String> messagePathList = new ArrayList<String>();
-        messagePathList.add("body.Order");
-        ObjectMapper mapper = new ObjectMapper();
-        List<Object> objectList = mapper.createObjectList(message, messagePathList);
-        //Now send to the rules engine
-		JBossRulesRouter jbossRulesRouter = new JBossRulesRouter();
-        try {
-    		jbossRulesRouter.route("JBossESBPricingRules.drl", false, message, objectList);
-            assertEquals(order.getDiscount(),10.0);
-            assertEquals("10%",message.getBody().get("DiscountObject"));
-           
-        } catch (MessageRouterException mre) {
-            System.out.println("Exception was thrown.");
-            mre.printStackTrace();
-            assertTrue(false);
-        }
-	}
-	
-	public static junit.framework.Test suite() {
-		return new JUnit4TestAdapter(BusinessProcessorUnitTest.class);
-	}
-
-}

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/routing/cbr/DslHelperUnitTest.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/routing/cbr/DslHelperUnitTest.java	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/routing/cbr/DslHelperUnitTest.java	2008-11-05 13:39:40 UTC (rev 23714)
@@ -0,0 +1,265 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* 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.jboss.internal.soa.esb.services.routing.cbr;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import javax.xml.xpath.XPathExpressionException;
+
+import junit.framework.JUnit4TestAdapter;
+
+import org.apache.log4j.Logger;
+import org.jboss.internal.soa.esb.util.StreamUtils;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.message.format.MessageFactory;
+import org.jboss.soa.esb.util.ClassUtil;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Unit test for {@link DslHelper} 
+ * <p/> 
+ * 
+ * @author <a href="mailto:dbevenius at redhat.com">Daniel Bevenius</a>
+ *
+ */
+public class DslHelperUnitTest
+{
+	private Logger log = Logger.getLogger( DslHelperUnitTest.class );
+	
+	// message with xml content in body
+	private static Message msg;
+	
+	// message with namespace context in body 
+	private static Message nsmsg;
+	private static HashMap<String, String> namespaces;
+
+	@Test
+	public void xmlContentExists() throws XPathExpressionException, UnsupportedEncodingException
+	{
+		assertTrue( DslHelper.xmlContentExists( msg, "//*[@productId = 299]" ) );
+		assertTrue( DslHelper.xmlContentExists( msg, "//*[@productId < 1000]" ) );
+		assertFalse( DslHelper.xmlContentExists( msg, "//*[@productId = 2299]" ) );
+	}
+	
+	@Test
+	public void xmlContentExistsWithNamespaces() throws XPathExpressionException, UnsupportedEncodingException
+	{
+		assertTrue( DslHelper.xmlContentExists( nsmsg, "/ord:Order/ord:OrderLines/ord:OrderLine/p:Product", namespaces ) );
+		assertTrue( DslHelper.xmlContentExists( nsmsg, "//p:Product", namespaces ) );
+		
+        HashMap<String, String> oneNamspace = new HashMap<String,String>();
+        oneNamspace.put( "ord", "http://org.jboss.soa.esb/order" );
+		assertTrue( DslHelper.xmlContentExists( nsmsg, "/ord:Order", oneNamspace ) );
+	}
+	
+	@Test
+	public void xmlContentMatches() throws XPathExpressionException, UnsupportedEncodingException
+	{
+		assertTrue( DslHelper.xmlContentMatches( msg, "//*[@productId = 299]" ) );
+		assertTrue( DslHelper.xmlContentMatches( msg, "/Order/OrderLines/OrderLine/Product" ) );
+		assertFalse( DslHelper.xmlContentMatches( msg, "//*[@productId > 1299]" ) );
+	}
+	
+	@Test
+	public void xmlContentMatchesWithNamespaces() throws XPathExpressionException, UnsupportedEncodingException
+	{
+		assertTrue( DslHelper.xmlContentMatches( nsmsg, "/ord:Order/ord:OrderLines/ord:OrderLine/p:Product", namespaces ) );
+	}
+	
+	@Test
+	public void selectAsBoolean() throws UnsupportedEncodingException, XPathExpressionException
+	{
+		assertTrue( DslHelper.selectAsBoolean( msg, "/Order/OrderLines/OrderLine/Product/@productId = 364" ) );
+		assertTrue( DslHelper.selectAsBoolean( msg, "//*[@productId = 299]" ) );
+		assertTrue( DslHelper.selectAsBoolean( msg, "//*[@productId < 1299]" ) );
+		assertFalse( DslHelper.selectAsBoolean( msg, "/Order/OrderLines/OrderLine/Product/@productId = 33" ) );
+	}
+	
+	@Test
+	public void selectAsBooleanWithNamespaces() throws UnsupportedEncodingException, XPathExpressionException
+	{
+		assertTrue( DslHelper.selectAsBoolean( nsmsg, "/ord:Order/ord:OrderLines/ord:OrderLine/p:Product/@productId = 364", namespaces ) );
+	}
+	
+	@Test
+	public void selectAsNumber() throws UnsupportedEncodingException, XPathExpressionException
+	{
+		assertEquals ( 364, DslHelper.selectAsNumber( msg, "//Product/@productId" ).intValue() );
+	}
+	
+	@Test
+	public void selectAsNumberWithNamespaces() throws UnsupportedEncodingException, XPathExpressionException
+	{
+		assertEquals ( 364, DslHelper.selectAsNumber( msg, "//Product/@productId", namespaces ).intValue() );
+	}
+	
+	@Test
+	public void selectAsString() throws UnsupportedEncodingException, XPathExpressionException
+	{
+		assertEquals ( "364", DslHelper.selectAsString( msg, "//Product/@productId" ) );
+	}
+	
+	@Test
+	public void selectAsStringWithNamespaces() throws UnsupportedEncodingException, XPathExpressionException
+	{
+		assertEquals ( "364", DslHelper.selectAsString( nsmsg, "//p:Product/@productId", namespaces ) );
+	}
+	
+	@Test
+	public void selectAsNode() throws UnsupportedEncodingException, XPathExpressionException
+	{
+		assertEquals ( "productId",  DslHelper.selectAsNode( msg, "/Order/OrderLines/OrderLine/Product/@productId").getNodeName() );
+	}
+	
+	@Test
+	public void selectAsNodeWithNamespaces() throws UnsupportedEncodingException, XPathExpressionException
+	{
+		assertEquals ( "productId",  DslHelper.selectAsNode( nsmsg, "/ord:Order/ord:OrderLines/ord:OrderLine/p:Product/@productId", namespaces ).getNodeName() );
+	}
+	
+	@Test
+	public void selectAsNodeList() throws UnsupportedEncodingException, XPathExpressionException
+	{
+		assertEquals ( 42, DslHelper.selectAsNodeList( msg, "//Product/@productId" ).getLength() );
+	}
+	
+	@Test
+	public void selectAsNodeListWithNamespaces() throws UnsupportedEncodingException, XPathExpressionException
+	{
+		assertEquals ( 2, DslHelper.selectAsNodeList( nsmsg, "//p:Product/@productId", namespaces ).getLength() );
+	}
+	
+	@Test
+	public void xmlContentEquals() throws UnsupportedEncodingException, XPathExpressionException
+	{
+		assertTrue( DslHelper.xmlContentEquals( msg, "/Order/OrderLines/OrderLine/Product/@productId", "364" ) );
+		assertFalse( DslHelper.xmlContentEquals( msg, "/Order/OrderLines/OrderLine/Product/@productId", "1" ) );
+	}
+	
+	@Test
+	public void xmlContentEqualsWithNamespaces() throws UnsupportedEncodingException, XPathExpressionException
+	{
+		assertTrue( DslHelper.xmlContentEquals( nsmsg, "/ord:Order/ord:OrderLines/ord:OrderLine/p:Product/@productId", "364", namespaces ) );
+	}
+	
+	@Test
+	public void xmlContentGreaterThan() throws UnsupportedEncodingException, XPathExpressionException
+	{
+		assertTrue( DslHelper.xmlContentGreaterThan( msg, "/Order/OrderLines/OrderLine/Product/@productId", "363" ) );
+		assertFalse( DslHelper.xmlContentGreaterThan( msg, "/Order/OrderLines/OrderLine/Product/@productId", "365" ) );
+		assertFalse( DslHelper.xmlContentGreaterThan( msg, "/Order/OrderLines/OrderLine/Product/@productId", "364" ) );
+	}
+	
+	@Test
+	public void xmlContentGreaterThanWithNamespaces() throws UnsupportedEncodingException, XPathExpressionException
+	{
+		assertTrue( DslHelper.xmlContentGreaterThan( nsmsg, "/ord:Order/ord:OrderLines/ord:OrderLine/p:Product/@productId", "363", namespaces ) );
+	}
+	
+	@Test ( expected = XPathExpressionException.class )
+	public void shouldThrowIfArgumentIsNotAParsableDouble() throws UnsupportedEncodingException, XPathExpressionException
+	{
+		assertTrue( DslHelper.xmlContentGreaterThan( msg, "/Order/OrderLines/OrderLine/Product/@productId", "aaa" ) );
+		assertTrue( DslHelper.xmlContentLessThan( msg, "/Order/OrderLines/OrderLine/Product/@productId", "aaa" ) );
+	}
+	
+	@Test
+	public void xmlContentLessThan() throws UnsupportedEncodingException, XPathExpressionException
+	{
+		assertTrue( DslHelper.xmlContentLessThan( msg, "/Order/OrderLines/OrderLine/Product/@productId", "366" ) );
+		assertTrue( DslHelper.xmlContentLessThan( msg, "/Order/OrderLines/OrderLine/Product/@productId", "365" ) );
+		assertFalse( DslHelper.xmlContentLessThan( msg, "/Order/OrderLines/OrderLine/Product/@productId", "363" ) );
+	}
+	
+	@Test
+    public void xmlContentLessThanWithNamespaces() throws UnsupportedEncodingException, XPathExpressionException
+    {
+        assertTrue( DslHelper.xmlContentLessThan(  nsmsg,  "/ord:Order/ord:OrderLines/ord:OrderLine/p:Product/@productId",  "366", namespaces));
+    }
+	
+	@Test
+	public void xmlContentEqualsPerformanceTest() throws UnsupportedEncodingException, XPathExpressionException
+	{
+		int nrOfCalls = 4000;
+		
+		long startTime = System.nanoTime();
+		for ( int i = 0 ; i < nrOfCalls ; i++ )
+		{
+    		DslHelper.xmlContentEquals( msg, "/Order/OrderLines/OrderLine/Product/@productId", "364" );
+		}
+		long endTime = TimeUnit.NANOSECONDS.toMillis( System.nanoTime() - startTime );
+		log.info( "Timed " + nrOfCalls + " runs : " + endTime + "ms" );
+		assertTrue( nrOfCalls + " of calls should have taken less then 150ms", endTime < 150 );
+	}
+	
+	@Test 
+	public void parseNamespaces()
+	{
+		Map<String,String> namespaces = DslHelper.parseNamespaces( "pro=http://org.jboss.soa.esb/product, ord=http://org.jboss.soa.esb/order" );
+		assertNotNull( namespaces );
+		assertEquals( 2, namespaces.size() );
+		assertTrue( namespaces.containsKey( "pro" ) );
+		assertTrue( namespaces.containsKey( "ord" ) );
+	}
+	
+	@Test ( expected = IllegalArgumentException.class )
+	public void parseNamespacesNegative()
+	{
+		DslHelper.parseNamespaces( null );
+	}
+	
+	@BeforeClass
+	public static void createMessage() throws UnsupportedEncodingException
+	{
+		msg = MessageFactory.getInstance().getMessage();
+		InputStream resourceAsStream = ClassUtil.getResourceAsStream( "/" + "5KB_message.xml", DslHelperUnitTest.class );
+		String contents = StreamUtils.readStreamString( resourceAsStream, "UTF-8" );
+		msg.getBody().add( contents );
+	}
+	
+    @BeforeClass
+    public static void createNamespaceMessage() throws UnsupportedEncodingException
+    {
+        nsmsg = MessageFactory.getInstance().getMessage();
+        InputStream resourceAsStream = ClassUtil.getResourceAsStream( "/" + "5KBNS_message.xml", DslHelperUnitTest.class );
+        String contents = StreamUtils.readStreamString( resourceAsStream, "UTF-8" );
+        nsmsg.getBody().add( contents );
+        
+        namespaces = new HashMap<String,String>();
+        namespaces.put( "ord", "http://org.jboss.soa.esb/order" );
+        namespaces.put( "p", "http://org.jboss.soa.esb/product" );
+    }
+    
+    public static junit.framework.Test suite() {
+        return new JUnit4TestAdapter(DslHelperUnitTest.class);
+    }
+}

Modified: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/routing/cbr/JBossRulesRouterUnitTest.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/routing/cbr/JBossRulesRouterUnitTest.java	2008-11-05 12:54:27 UTC (rev 23713)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/routing/cbr/JBossRulesRouterUnitTest.java	2008-11-05 13:39:40 UTC (rev 23714)
@@ -1,6 +1,6 @@
 /*
  * JBoss, Home of Professional Open Source
- * Copyright 2006, JBoss Inc., and individual contributors as indicated
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
  * by the @authors tag. See the copyright.txt in the distribution for a
  * full listing of individual contributors.
  *
@@ -22,56 +22,266 @@
 package org.jboss.internal.soa.esb.services.routing.cbr;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
+import java.math.BigDecimal;
+import java.net.URI;
+import java.util.ArrayList;
 import java.util.List;
 
 import junit.framework.JUnit4TestAdapter;
 
+import org.jboss.soa.esb.actions.CBRConfigTreeBuilder;
+import org.jboss.soa.esb.helpers.ConfigTree;
 import org.jboss.soa.esb.message.Message;
 import org.jboss.soa.esb.message.format.MessageFactory;
 import org.jboss.soa.esb.message.format.MessageType;
+import org.jboss.soa.esb.message.mapping.ObjectMapper;
+import org.jboss.soa.esb.message.mapping.ObjectMappingException;
 import org.jboss.soa.esb.services.routing.MessageRouterException;
+import org.jboss.soa.esb.services.routing.cbr.ContentBasedRouterFactory;
+import org.jboss.soa.esb.testutils.TestEnvironmentUtil;
+import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 /**
+ * Tests for {@link JBossRulesRouter}.
  * 
  * @author kurt.stam at redhat.com
+ * @author <a href="mailto:dbevenius at redhat.com">Daniel Bevenius</a>
  *
  */
 public class JBossRulesRouterUnitTest
 {
+    //	instance under test
+	private JBossRulesRouter jbrRouter;
+	
 	@Test
-	public void routeSerializedMessage()
+	public void routeSerializedMessage() throws MessageRouterException
 	{
+		Message message = createMessage( MessageType.JAVA_SERIALIZED );
+		ConfigTree configTree = new CBRConfigTreeBuilder( true ).ruleFile( "JBossESBRules.drl").build();
+		jbrRouter.setConfigTree( configTree );
+		
+		List<String> destinationServices = jbrRouter.route("JBossESBRules.drl",false,message,null);
+		assertNotNull(destinationServices);
+		assertTrue(destinationServices.size()>0);
+		assertEquals(destinationServices.iterator().next(),"serialized-destination");
+	}
+	
+	@Test
+	public void routeSerializedMessageDecisionTableStateless() throws MessageRouterException
+	{
+		Message message = createMessage( MessageType.JAVA_SERIALIZED );
+			
+		ConfigTree configTree = new CBRConfigTreeBuilder( true ).decisionTable( "RuleBaseHelper.xls").build();
+		jbrRouter.setConfigTree( configTree );
+		
+		List<String> destinationServices = jbrRouter.route( null, false, message, null);
+			
+		assertNotNull( destinationServices );
+		assertTrue( "One destination should have been added by Drools", destinationServices.size() == 1 );
+		assertEquals( "serialized-destination", destinationServices.get(0).toString() );
+	}
+	
+	@Test
+	public void routeSerializedMessageDecisionTableStateful() throws MessageRouterException
+	{
+		Message message = createMessage( MessageType.JAVA_SERIALIZED );
+			
+		ConfigTree configTree = new CBRConfigTreeBuilder( true ).decisionTable( "RuleBaseHelper.xls").stateful( true ).build();
+		jbrRouter.setConfigTree( configTree );
+			
+		List<String> destinationServices = jbrRouter.route( null, false, message, null);
+		
+		assertNotNull( destinationServices );
+		assertTrue( "One destination should have been added by Drools", destinationServices.size() == 1 );
+		assertEquals( "serialized-destination", destinationServices.get(0).toString() );
+	}
+	
+	@Test
+	public void routeXMLMessage() throws MessageRouterException
+	{
+		Message message = createMessage( MessageType.JBOSS_XML);
+		ConfigTree configTree = new CBRConfigTreeBuilder( true ).ruleFile( "JBossESBRules.drl").build();
+		jbrRouter.setConfigTree( configTree );
+		List<String> destinationServices = jbrRouter.route("JBossESBRules.drl",false,message,null);
+		assertEquals(destinationServices.iterator().next(),"xml-destination");
+	}
+	
+	@Test
+	public void routeXMLMessageUsingXPathMatch() throws MessageRouterException
+	{
+		Message message = createMessage( MessageType.JBOSS_XML);
+		message.getBody().add(("<jbossesb>TEST BODY</jbossesb>").getBytes());
+		ConfigTree configTree = new CBRConfigTreeBuilder( true ).ruleFile( "JBossESBRules.drl").build();
+		jbrRouter.setConfigTree( configTree );
+			
+		List<String> destinationServices = jbrRouter.route("JBossESBRules-XPath.drl","XPathLanguage.dsl",false,message,null);
+		assertEquals(destinationServices.iterator().next(),"XML_XPath_Destination");
+	}
+	
+	@Test
+	public void routeXMLMessageUsingXPathEquals() throws MessageRouterException
+	{
+		Message message = createMessage( MessageType.JBOSS_XML );
+		message.getBody().add(("<Dave>rocks</Dave>").getBytes());
+		
+		ConfigTree configTree = new CBRConfigTreeBuilder( true ).ruleFile( "JBossESBRules.drl").build();
+		jbrRouter.setConfigTree( configTree );
+		
+		List<String> destinationServices = jbrRouter.route("JBossESBRules-XPath.drl","XPathLanguage.dsl",false,message,null);
+		assertEquals(destinationServices.iterator().next(),"XML_XPath_Dave_Destination");
+	}
+	
+	@Test
+	public void routeXMLMessageUsingXPathGreaterThen() throws MessageRouterException
+	{
+		Message message = createMessage( MessageType.JBOSS_XML );
+		message.getBody().add(("<price>1.55</price>").getBytes());
+		
+		ConfigTree configTree = new CBRConfigTreeBuilder( true ).ruleFile( "JBossESBRules.drl").build();
+		jbrRouter.setConfigTree( configTree );
+			
+		List<String> destinationServices = jbrRouter.route("JBossESBRules-XPath.drl","XPathLanguage.dsl",false,message,null);
+		assertEquals(destinationServices.iterator().next(),"XML_XPath_GreaterThan_Destination");
+	}
+	
+	@Test
+	public void routeXMLMessageUsingXPathLessThen()
+	{
+		try {
+			//add new messages
+			Message message = MessageFactory.getInstance().getMessage( MessageType.JBOSS_XML );
+			//set the body inside the Message
+			message.getBody().add(("<price>0.55</price>").getBytes());
+    		ConfigTree configTree = new CBRConfigTreeBuilder( true ).ruleFile( "JBossESBRules.drl").build();
+    		jbrRouter.setConfigTree( configTree );
+			
+			List<String> destinationServices = jbrRouter.route("JBossESBRules-XPath.drl","XPathLanguage.dsl",false,message,null);
+			assertEquals(destinationServices.iterator().next(),"XML_XPath_LessThan_Destination");
+		} catch (MessageRouterException e) {
+			e.printStackTrace();
+		}
+	}
+	
+	@Test ( expected = MessageRouterException.class )
+	public void shouldThrowIfNoRuleSetIsSupplied() throws MessageRouterException
+	{
+		//add new messages
+		Message message = MessageFactory.getInstance().getMessage( MessageType.JBOSS_XML );
+		ConfigTree configTree = new ConfigTree("bad-config");
+		jbrRouter.setConfigTree( configTree );
+			
+		jbrRouter.route( null ,"XPathLanguage.dsl",false,message,null);
+	}
+	
+	@Test ( expected = MessageRouterException.class )
+	public void shouldThrowIfRuleServiceImplIsInvalid() throws MessageRouterException
+	{
+		//add new messages
+		Message message = MessageFactory.getInstance().getMessage( MessageType.JBOSS_XML );
+		ConfigTree configTree = new CBRConfigTreeBuilder( true ).ruleServiceImpl( "bad.Class" ).ruleFile( "JBossESBRules.drl").build();
+		jbrRouter.setConfigTree( configTree );
+			
+		jbrRouter.route( null, "XPathLanguage.dsl", false, message, null);
+	}
+	
+	//	Moved into this class from BusinessProcessRoutingUnitTest
+	//	as that class also used JBossRulesRouter as you can see below
+	@Test
+	public void discount() throws ObjectMappingException
+	{
         //new messages
-		Message message = MessageFactory.getInstance().getMessage(MessageType.JAVA_SERIALIZED);
-		//set some properties inside the Message
-		message.getProperties().setProperty("prop1", "val1");
-		message.getProperties().setProperty("prop2", "val2");
-		//set the body inside the Message
-		message.getBody().add(("TEST BODY").getBytes());
-		//set some object attachments inside the Message
-		message.getAttachment().addItem(new String("TEST ATTACHMENT1"));
-		message.getAttachment().addItem(new String("TEST ATTACHMENT2"));
-		
+		Message message = createMessage( MessageType.JAVA_SERIALIZED );
+		Order order = new Order();
+        order.setQuantity(20);
+        order.setUnitPrice(new BigDecimal("20.0"));
+		message.getBody().add("Order", order);
+        //extract the order from the message, so the drl can process it
+        List<String> messagePathList = new ArrayList<String>();
+        messagePathList.add("body.Order");
+        ObjectMapper mapper = new ObjectMapper();
+        List<Object> objectList = mapper.createObjectList(message, messagePathList);
+        //Now send to the rules engine
 		JBossRulesRouter jbossRulesRouter = new JBossRulesRouter();
+		ConfigTree configTree = new CBRConfigTreeBuilder( true ).ruleFile( "JBossESBPricingRoutingRules.drl").build();
+		jbossRulesRouter.setConfigTree( configTree );
         try {
-    		List<String> destinationServices = jbossRulesRouter.route("JBossESBRules.drl", false, message, null);
-    		assertEquals(destinationServices.iterator().next(),"serialized-destination");
-            System.out.println(message.getBody().get());
+    		List<String> destinations = jbossRulesRouter.route("JBossESBPricingRoutingRules.drl", false, message, objectList);
+            assertEquals(order.getDiscount(),10.0);
+            assertEquals("10%",message.getBody().get("DiscountObject"));
+            String shippingDestination = destinations.iterator().next();
+            System.out.println(shippingDestination);
+            assertEquals("express-shipping-destination", shippingDestination);
+           
         } catch (MessageRouterException mre) {
             System.out.println("Exception was thrown.");
             mre.printStackTrace();
             assertTrue(false);
         }
 	}
+    
+	//	Moved into this class from BusinessProcessRoutingUnitTest
+	//	as that class also used JBossRulesRouter as you can see befinal low
+    @Test
+    public void nodiscount() throws ObjectMappingException
+    {
+        //new messages
+        Message message = MessageFactory.getInstance().getMessage(MessageType.JAVA_SERIALIZED);
+        Order order = new Order();
+        order.setQuantity(2);
+        order.setUnitPrice(new BigDecimal("20.0"));
+        message.getBody().add("Order", order);
+//      extract the order from the message, so the drl can process it
+        List<String> messagePathList = new ArrayList<String>();
+        messagePathList.add("body.Order");
+        ObjectMapper mapper = new ObjectMapper();
+        List<Object> objectList = mapper.createObjectList(message, messagePathList);
+        //Now send to the rules engine
+        JBossRulesRouter jbossRulesRouter = new JBossRulesRouter();
+		ConfigTree configTree = new CBRConfigTreeBuilder( true ).ruleFile( "JBossESBPricingRoutingRules.drl").build();
+		jbossRulesRouter.setConfigTree( configTree );
+        try {
+            List<String> destinations = jbossRulesRouter.route("JBossESBPricingRoutingRules.drl", false, message, objectList);
+            assertEquals(order.getDiscount(),0.0);
+            assertEquals("0%",message.getBody().get("DiscountObject"));
+            String shippingDestination = destinations.iterator().next();
+            System.out.println(shippingDestination);
+            assertEquals("normal-shipping-destination", shippingDestination);
+           
+        } catch (MessageRouterException mre) {
+            System.out.println("Exception was thrown.");
+            mre.printStackTrace();
+            assertTrue(false);
+        }
+    }
 	
-	@Test
-	public void routeXMLMessage()
+	@Before
+	public void setup() throws MessageRouterException
 	{
-		//add new messages
-		Message message = MessageFactory.getInstance().getMessage(MessageType.JBOSS_XML);
+		jbrRouter = (JBossRulesRouter) ContentBasedRouterFactory.getRouter(org.jboss.soa.esb.actions.ContentBasedRouter.DEFAULT_CBR_CLASS);
+		jbrRouter.setConfigTree( new ConfigTree("dummy" ));
+	}
+	
+	@BeforeClass
+	public static void runBeforeAllTests() throws Exception 
+	{
+		try {
+			TestEnvironmentUtil.setESBPropertiesFileToUse();
+		} catch (Exception e) {
+			e.printStackTrace();
+			System.out.println("We should stop testing, since we don't any config properties");
+			assertTrue(false);
+		}
+	}
+	
+	private Message createMessage( final URI type )
+	{
+		//new messages
+		Message message = MessageFactory.getInstance().getMessage( type );
 		//set some properties inside the Message
 		message.getProperties().setProperty("prop1", "val1");
 		message.getProperties().setProperty("prop2", "val2");
@@ -80,16 +290,7 @@
 		//set some object attachments inside the Message
 		message.getAttachment().addItem(new String("TEST ATTACHMENT1"));
 		message.getAttachment().addItem(new String("TEST ATTACHMENT2"));
-	
-		JBossRulesRouter jbossRulesRouter = new JBossRulesRouter();
-        try {
-    		List<String> destinationServices = jbossRulesRouter.route("JBossESBRules.drl", false, message, null);
-    		assertEquals(destinationServices.iterator().next(),"xml-destination");
-        } catch (MessageRouterException mre) {
-            System.out.println("Exception was thrown.");
-            mre.printStackTrace();
-            assertTrue(false);
-        }
+		return message;
 	}
 	
 	public static junit.framework.Test suite() {

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleBaseHelperUnitTest.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleBaseHelperUnitTest.java	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleBaseHelperUnitTest.java	2008-11-05 13:39:40 UTC (rev 23714)
@@ -0,0 +1,121 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * 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.jboss.internal.soa.esb.services.rules;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import java.io.IOException;
+
+import junit.framework.JUnit4TestAdapter;
+import org.drools.RuleBase;
+import org.drools.compiler.DroolsParserException;
+import org.junit.Test;
+
+/**
+ * Unit test for {@link DroolsRuleBaseHelper}
+ * <p/>
+ * 
+ * @author <a href="mailto:dbevenius at redhat.com">Daniel Bevenius</a>
+ *
+ */
+public class DroolsRuleBaseHelperUnitTest
+{
+	// instance under test
+	private DroolsRuleBaseHelper helper = DroolsRuleBaseHelper.getInstance();
+	
+	private final static String NULL_DSL_FILE = null;
+	private final static String NULL_RULE_FILE = null;
+	private final static String NULL_DECISION_TABLE_FILE = null;
+	
+	@Test ( expected = NullPointerException.class )
+	public void shouldThrowIfRuleFileIsNull() throws DroolsParserException, IOException, RuleServiceException
+	{
+		helper.createRuleBaseFromRuleFiles( NULL_RULE_FILE, NULL_DSL_FILE );
+	}
+	
+	@Test
+	public void createRuleBaseFromRuleFiles() throws DroolsParserException, IOException, RuleServiceException
+	{
+		RuleBase ruleBase = helper.createRuleBaseFromRuleFiles( "RuleBaseHelper.drl", NULL_DSL_FILE );
+		
+		assertNotNull( ruleBase );
+		assertTrue( ruleBase.getPackages().length > 0 );
+		assertEquals( "org.jboss.internal.soa.esb.rules" , ruleBase.getPackages()[0].getName());
+	}
+	
+	@Test ( expected = NullPointerException.class )
+	public void shouldThrowIfDecisionTableIsNull() throws DroolsParserException, IOException, RuleServiceException
+	{
+		helper.createRuleBaseFromDecisionTable( NULL_DECISION_TABLE_FILE );
+	}
+	
+	@Test
+	public void createRuleBaseFromDecisionTable() throws DroolsParserException, IOException, RuleServiceException
+	{
+		RuleBase ruleBase = helper.createRuleBaseFromDecisionTable( "RuleBaseHelper.xls" );
+		assertNotNull( ruleBase );
+		assertEquals( "org.jboss.internal.soa.esb.rules", ruleBase.getPackages()[0].getName());
+	}
+	
+	@Test ( expected = NullPointerException.class )
+	public void getRuleAsStringShouldThrowIfRuleFileIsNull() throws IOException, RuleServiceException
+	{
+		String rulesAsString = helper.getRulesAsString( NULL_RULE_FILE, NULL_DSL_FILE );
+		assertNotNull( rulesAsString );
+	}
+	
+	@Test
+	public void getRuleFileAsString() throws IOException, RuleServiceException
+	{
+		String rulesAsString = helper.getRulesAsString( "RuleBaseHelper.drl", NULL_DSL_FILE );
+		assertNotNull( rulesAsString );
+	}
+	
+	@Test
+	public void getSpreadSheetRules() throws IOException, RuleServiceException
+	{
+		String spreadSheetAsString = helper.getSpreadsheetRules( "RuleBaseHelper.xls" );
+		assertNotNull( spreadSheetAsString );
+	}
+	
+	/* 
+	   This test is currently disabled as the file property that exists in RuleBaseHelper.properties
+	   accesses a file on the local file system. This causes problems with the integration build as
+	   the working dir is not the same and when run from eclipse or ant in this modules directory.
+	   The issue here could be fixed by using the dir property in base-build.xml, but that caused
+	   the other modules to fail. Leaving this for now as v5.0 will clean this up./Daniel
+	@Test
+	*/
+	public void loadRuleBaseFromRuleAgent() throws Exception
+	{
+		RuleBase ruleBase = helper.loadRuleBaseFromRuleAgent( "RuleBaseHelper.properties" );
+		assertNotNull( ruleBase );
+		assertEquals( "org.jboss.internal.soa.esb.rules", ruleBase.getPackages()[0].getName());
+	}
+	
+	public static junit.framework.Test suite()
+	{
+		return new JUnit4TestAdapter( DroolsRuleBaseHelperUnitTest.class );
+	}
+	
+}

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleServiceUnitTest.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleServiceUnitTest.java	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleServiceUnitTest.java	2008-11-05 13:39:40 UTC (rev 23714)
@@ -0,0 +1,318 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * 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.jboss.internal.soa.esb.services.rules;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import junit.framework.JUnit4TestAdapter;
+
+import org.drools.RuleBase;
+import org.drools.agent.RuleAgent;
+import org.jboss.internal.soa.esb.services.routing.cbr.Order;
+import org.jboss.internal.soa.esb.util.StreamUtils;
+import org.jboss.soa.esb.ConfigurationException;
+import org.jboss.soa.esb.actions.Counter;
+import org.jboss.soa.esb.lifecycle.LifecycleResourceException;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.message.format.MessageFactory;
+import org.jboss.soa.esb.message.format.MessageType;
+import org.jboss.soa.esb.message.mapping.ObjectMapper;
+import org.jboss.soa.esb.message.mapping.ObjectMappingException;
+import org.jboss.soa.esb.util.ClassUtil;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Unit test for {@link DroolsRuleService}
+ * <p/>
+ * 
+ * @author <a href="mailto:dbevenius at redhat.com">Daniel Bevenius</a>
+ *
+ */
+public class DroolsRuleServiceUnitTest
+{
+	private DroolsRuleService ruleService = new DroolsRuleService();
+	
+	private RuleBase ruleBase;
+	private Message message;
+
+	private Order order;
+
+	private ArrayList<String> messagePathList;
+	
+	@Test
+	public void executeStatelessRules()
+	{
+		Map<String,Object> globals = getGlobalsWithDestAndMessage();
+		message = ruleService.executeStatelessRules( ruleBase, message , globals, null );
+		ArrayList<String> destinations = getDistinations( globals );
+		assertTrue( destinations.size() == 1 );
+	}
+	
+	@Test
+	public void executeStatelessRulesFromDecisionTableReload() throws RuleServiceException
+	{
+		Map<String,Object> globals = getGlobalsWithDest();
+		final String decisionTable = "RuleBaseHelper.xls";
+		message = ruleService.executeStatelessRulesFromDecisionTable( decisionTable, true, message, globals, null );
+		ArrayList<String> destinations = getDistinations( globals );
+		assertTrue( destinations.size() == 1 );
+	}
+	
+	@Test
+	public void executeStatelessRulesFromDecisionTable() throws RuleServiceException
+	{
+		Map<String,Object> globals = getGlobalsWithDest();
+		final String decisionTable = "RuleBaseHelper.xls";
+		message = ruleService.executeStatelessRulesFromDecisionTable( decisionTable, false, message, globals, null );
+		ArrayList<String> destinations = getDistinations( globals );
+		assertTrue( destinations.size() == 1 );
+	}
+	
+	@Test
+	public void executeStatfulRulesFromDecisionTableReload() throws RuleServiceException
+	{
+		Map<String,Object> globals = getGlobalsWithDest();
+		final String decisionTable = "RuleBaseHelper.xls";
+		message = ruleService.executeStatefulRulesFromDecisionTable( decisionTable, true, message, globals, null );
+		ArrayList<String> destinations = getDistinations( globals );
+		assertTrue( destinations.size() == 1 );
+	}
+	
+	@Test
+	public void executeStatfulRulesFromDecisionTable() throws RuleServiceException
+	{
+		Map<String,Object> globals = getGlobalsWithDest();
+		final String decisionTable = "RuleBaseHelper.xls";
+		message = ruleService.executeStatefulRulesFromDecisionTable( decisionTable, false, message, globals, null );
+		ArrayList<String> destinations = getDistinations( globals );
+		assertTrue( destinations.size() == 1 );
+	}
+	
+	@Test
+	public void executeStatefulRules() throws RuleServiceException
+	{
+		Map<String,Object> globals = getGlobalsWithDestAndMessage();
+		message = ruleService.executeStatefulRules( ruleBase, true, message , globals, null );
+		ArrayList<String> destinations = getDistinations( globals );
+		assertTrue( destinations.size() == 1 );
+	}
+	
+	@Test
+	public void executeStatefulRulesDrl() throws RuleServiceException
+	{
+		Map<String,Object> globals = getGlobalsWithDestAndMessage();
+		message = ruleService.executeStatefulRules( "JBossESBRules.drl", null, true, message, globals, null );
+		ArrayList<String> destinations = getDistinations( globals );
+		assertTrue( destinations.size() == 1 );
+	}
+	
+	@Test
+	public void executeStatelessRulesDrlWithDsl() throws RuleServiceException, ConfigurationException, UnsupportedEncodingException
+	{
+		Message msg = MessageFactory.getInstance().getMessage();
+		InputStream resourceAsStream = ClassUtil.getResourceAsStream( "/" + "5KB_message.xml", getClass() );
+		String contents = StreamUtils.readStreamString( resourceAsStream, "UTF-8" );
+		msg.getBody().add( contents );
+		Map<String,Object> globals = getGlobalsWithDest();
+		boolean ruleReload = true;
+		
+		// first run
+		long startTime = System.nanoTime();
+		
+		message = ruleService.executeStatelessRules( "RulesWithDsl.drl", "XPathLanguage.dsl", ruleReload, msg, globals, null );
+		ArrayList<String> destinations = getDistinations( globals );
+		assertTrue( destinations.size() == 1 );
+		
+		long procTime = System.nanoTime() - startTime;
+		long firstRun = TimeUnit.NANOSECONDS.toMillis( procTime ) ;
+		System.out.println( "Timed First run : " +  firstRun + "ms" );
+		
+		// second run
+		startTime = System.nanoTime();
+		
+		message = ruleService.executeStatelessRules( "RulesWithDsl.drl", "XPathLanguage.dsl", ruleReload, msg, globals, null );
+		procTime = System.nanoTime() - startTime;
+		long secondRun = TimeUnit.NANOSECONDS.toMillis( procTime ) ;
+		System.out.println( "Timed Second run : " + secondRun + "ms" );
+		
+		destinations = getDistinations( globals );
+		assertTrue( destinations.size() == 2 );
+	}
+	
+	@Test
+	public void executeStatelessRulesDrlWithDslAndNamespaces() throws RuleServiceException, ConfigurationException, UnsupportedEncodingException
+	{
+		Message msg = MessageFactory.getInstance().getMessage();
+		InputStream resourceAsStream = ClassUtil.getResourceAsStream( "/" + "5KBNS_message.xml", getClass() );
+		String contents = StreamUtils.readStreamString( resourceAsStream, "UTF-8" );
+		msg.getBody().add( contents );
+		Map<String,Object> globals = getGlobalsWithDest();
+		boolean ruleReload = true;
+		
+		message = ruleService.executeStatelessRules( "RulesWithDslNS.drl", "XPathLanguage.dsl", ruleReload, msg, globals, null );
+		ArrayList<String> destinations = getDistinations( globals );
+		assertEquals( 3 , destinations.size() );
+	}
+	
+	@Test
+	public void executeStatefulRulesContinueSession() throws RuleServiceException, ObjectMappingException
+	{
+		Message message = createMessageWithOrder( order );
+		Map<String,Object> globals = getGlobalsWithMessage( message );
+    	ArrayList<String> messagePathList = new ArrayList<String>();
+        messagePathList.add("body.Order");
+        messagePathList.add("body.Counter");
+        
+        List<Object> objectList = new ObjectMapper().createObjectList(message, messagePathList);
+		
+		// process message
+		message = ruleService.executeStatefulRules( "JBossESBPricingRulesStateful.drl", null, true, message, globals, objectList );
+        assertEquals( 20.0, order.getDiscount() );
+        assertEquals( "20%" ,message.getBody().get("DiscountObject"));
+        
+        //	process message again with a counter instance 
+        objectList = new ObjectMapper().createObjectList(message, messagePathList);
+		message = ruleService.continueStatefulRulesExecution( "JBossESBPricingRulesStateful.drl", true, message, globals, objectList );
+		
+        Counter counter = (Counter) message.getBody().get("Counter");
+        
+        assertEquals( 2 , counter.getCounter() );
+	}
+	
+	/* 
+	   This test is currently disabled as the file property that exists in RuleBaseHelper.properties
+	   accesses a file on the local file system. This causes problems with the integration build as
+	   the working dir is not the same and when run from eclipse or ant in this modules directory.
+	   The issue here could be fixed by using the dir property in base-build.xml, but that caused
+	   the other modules to fail. Leaving this for now as v5.0 will clean this up./Daniel
+	@Test
+    */
+	public void executeStatefulRulesFromRuleAgent() throws RuleServiceException
+	{
+		Map<String,Object> globals = getGlobalsWithDest();
+		
+		message = ruleService.executeStatefulRulesFromRuleAgent( "RuleBaseHelper.properties", message , globals, null );
+		
+		ArrayList<String> destinations = getDistinations( globals );
+		assertTrue( destinations.size() == 1 );
+		
+		message = ruleService.executeStatefulRules( ruleBase, true, message , globals, null );
+		assertTrue( destinations.size() == 2 );
+	}
+	
+	/*
+	 	Commented out for the same reason as the previous test.
+	@Test
+	*/
+	public void executeStatefulRulesCheckCached() throws RuleServiceException, LifecycleResourceException
+	{
+		ruleService.getCachedRuleBases().clear();
+		final String ruleAgentProperites = "RuleBaseHelper.properties";
+		Map<String,Object> globals = getGlobalsWithDest();
+		ruleService.executeStatefulRulesFromRuleAgent( ruleAgentProperites, message , globals, null );
+		
+		Map<String, RuleAgent> ruleAgents = ruleService.getCachedRuleAgents();
+		assertEquals( 1,  ruleAgents.size() );
+		RuleAgent ruleAgent = ruleAgents.get( ruleAgentProperites );
+		assertNotNull( ruleAgent );
+		
+		RuleBase rBase = ruleAgent.getRuleBase();
+		assertEquals ( rBase, ruleService.getCachedRuleBases().get( ruleAgentProperites ) );
+		
+		for ( int i = 0 ; i < 10 ; i++ )
+    		ruleService.executeStatefulRulesFromRuleAgent( ruleAgentProperites, message , globals, null );
+		
+		assertEquals( 1,  ruleAgents.size() );
+		assertEquals( 1,  ruleService.getCachedRuleBases().size() );
+		assertEquals ( rBase, ruleService.getCachedRuleBases().get( ruleAgentProperites ) );
+	}
+		
+	//	Test setup methods
+	
+	@Before
+	public void setup() throws RuleServiceException
+	{
+		ruleBase = ruleService.getRuleBaseForFileBasedRules( "JBossESBRules.drl", null, true );
+		message = MessageFactory.getInstance().getMessage();
+		
+		order = new Order();
+        order.setQuantity(20);
+        order.setUnitPrice( new BigDecimal("20.0") );
+        
+        messagePathList = new ArrayList<String>();
+        messagePathList.add("body.Order");
+        messagePathList.add("body.Counter");
+	}
+
+	public static junit.framework.Test suite()
+	{
+		return new JUnit4TestAdapter( DroolsRuleServiceUnitTest.class );
+	}
+	
+	@SuppressWarnings("unchecked")
+	private ArrayList<String> getDistinations( final Map<String,Object> globals )
+	{
+		return (ArrayList<String>) globals.get( "destinations" );
+	}
+	
+	private Map<String,Object> getGlobalsWithDestAndMessage()
+	{
+		Map<String,Object> globals = getGlobalsWithDest();
+		globals.putAll( getGlobalsWithMessage( message ));
+		return globals;
+	}
+	
+	private Map<String,Object> getGlobalsWithDest()
+	{
+		Map<String,Object> globals = new HashMap<String,Object>();
+		ArrayList<String> destinations =  new ArrayList<String>();
+		globals.put("destinations", destinations );
+		return globals;
+	}
+	
+	private Map<String,Object> getGlobalsWithMessage( final Message message )
+	{
+		Map<String,Object> globals = new HashMap<String,Object>();
+		globals.put("message", message );
+		return globals;
+	}
+	
+	private Message createMessageWithOrder( final Order order )
+	{
+		Message message = MessageFactory.getInstance().getMessage(MessageType.JAVA_SERIALIZED);
+		message.getBody().add("Order", order);
+		return message;
+	}
+}

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/BusinessRulesProcessorUnitTest.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/BusinessRulesProcessorUnitTest.java	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/BusinessRulesProcessorUnitTest.java	2008-11-05 13:39:40 UTC (rev 23714)
@@ -0,0 +1,141 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * 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.jboss.soa.esb.actions;
+
+import static org.junit.Assert.assertEquals;
+
+import java.math.BigDecimal;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+
+import junit.framework.JUnit4TestAdapter;
+
+import org.jboss.internal.soa.esb.services.registry.MockRegistry;
+import org.jboss.internal.soa.esb.services.routing.cbr.Order;
+import org.jboss.soa.esb.ConfigurationException;
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.message.format.MessageFactory;
+import org.jboss.soa.esb.message.format.MessageType;
+import org.jboss.soa.esb.message.mapping.ObjectMappingException;
+import org.jboss.soa.esb.services.registry.RegistryException;
+import org.jboss.soa.esb.services.routing.MessageRouterException;
+import org.jboss.soa.esb.services.rules.RuleServicePropertiesNames;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Unit test for {@link BusinessRulesProcessor}
+ * 
+ * @author <a href="mailto:dbevenius at redhat.com">Daniel Bevenius</a>
+ *
+ */
+public class BusinessRulesProcessorUnitTest
+{
+	private Order order;
+	private ArrayList<String> messagePathList;
+	
+	@Test
+	public void processDiscount() throws ObjectMappingException, ConfigurationException, RegistryException, MessageRouterException, ActionProcessingException
+	{
+		Message message = createMessageWithOrder( order );
+        ConfigTree configTree = new CBRConfigTreeBuilder( true ).ruleFile( "JBossESBPricingRulesStateful.drl" ).messagePaths(messagePathList).build();
+		BusinessRulesProcessor processor = new BusinessRulesProcessor( configTree );
+		
+		processor.process( message );
+		
+        assertEquals( 20.0, order.getDiscount() );
+        assertEquals( "20%" ,message.getBody().get("DiscountObject"));
+	}
+	
+	@Test
+	public void processDiscountStateful() throws ObjectMappingException, ConfigurationException, RegistryException, MessageRouterException, ActionProcessingException
+	{
+		Message message = createMessageWithOrder( order );
+        ConfigTree configTree = new CBRConfigTreeBuilder( true ).ruleFile( "JBossESBPricingRulesStateful.drl" ).stateful( true ).messagePaths(messagePathList).build();
+		BusinessRulesProcessor processor = new BusinessRulesProcessor( configTree );
+		
+		// process message
+		processor.process( message );
+        assertEquals( 20.0, order.getDiscount() );
+        assertEquals( "20%" ,message.getBody().get("DiscountObject"));
+        
+        //	now dispose after this call
+        message.getProperties().setProperty( RuleServicePropertiesNames.DISPOSE.getTagName(), Boolean.TRUE );
+        message.getProperties().setProperty( RuleServicePropertiesNames.CONTINUE.getTagName(), Boolean.TRUE );
+		processor.process( message );
+		
+		//	counter is inserted into the working memory by the first rules execution
+		//	from the above process call.
+        Counter counter = (Counter) message.getBody().get("Counter");
+        assertEquals( 2 , counter.getCounter() );
+	}
+	
+	@Test ( expected = ActionProcessingException.class )
+	public void shouldThrowIfDisposePropertyIsNotSet() throws ObjectMappingException, ConfigurationException, RegistryException, MessageRouterException, ActionProcessingException
+	{
+		Message message = createMessageWithOrder( order );
+        ConfigTree configTree = new CBRConfigTreeBuilder( true ).ruleFile( "JBossESBPricingRulesStateful.drl" ).messagePaths(messagePathList).stateful( true ).build();
+		BusinessRulesProcessor processor = new BusinessRulesProcessor( configTree );
+		
+		// process message
+		processor.process( message );
+        assertEquals( 20.0, order.getDiscount() );
+        assertEquals( "20%" ,message.getBody().get("DiscountObject"));
+        
+        //	We don't set 'dispose' which should cause an exception to be thrown...
+        message.getProperties().setProperty( RuleServicePropertiesNames.CONTINUE.getTagName(), Boolean.TRUE );
+		processor.process( message );
+	}
+	
+	public static junit.framework.Test suite() 
+	{
+		return new JUnit4TestAdapter(BusinessRulesProcessorUnitTest.class);
+	}
+	
+	@Before
+	public void setup()
+	{
+		order = new Order();
+        order.setQuantity(20);
+        order.setUnitPrice( new BigDecimal("20.0") );
+        
+        messagePathList = new ArrayList<String>();
+        messagePathList.add("body.Order");
+        messagePathList.add("body.Counter");
+	}
+	
+	@BeforeClass
+	public static void setupMockRegistry() throws URISyntaxException
+	{
+        MockRegistry.install();
+	}
+	
+	private Message createMessageWithOrder( final Order order )
+	{
+		Message message = MessageFactory.getInstance().getMessage(MessageType.JAVA_SERIALIZED);
+		message.getBody().add("Order", order);
+		return message;
+	}
+	
+}

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/CBRConfigTreeBuilder.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/CBRConfigTreeBuilder.java	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/CBRConfigTreeBuilder.java	2008-11-05 13:39:40 UTC (rev 23714)
@@ -0,0 +1,126 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * 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.jboss.soa.esb.actions;
+
+import java.util.List;
+
+import org.jboss.soa.esb.actions.ContentBasedWiretap;
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.listeners.ListenerTagNames;
+import org.jboss.soa.esb.services.rules.RuleServicePropertiesNames;
+
+/**
+ * Builder for CBR ConfigTree instances.
+ * </p>
+ * 
+ * @author <a href="mailto:dbevenius at redhat.com">Daniel Bevenius</a>
+ *
+ */
+public class CBRConfigTreeBuilder
+{
+	//	mandatory
+	private boolean reload;
+ 		
+	//	optional 
+	private String ruleFile;
+	private List<String> messagePathList;
+	private boolean stateful;
+	private String decisionTable;
+	private String ruleAgent;
+	private String ruleServiceImpl;
+	
+		
+	public CBRConfigTreeBuilder( final boolean reload )
+	{
+		this.reload = reload;
+	}
+	
+	public CBRConfigTreeBuilder ruleFile( final String ruleFile )
+	{
+		this.ruleFile = ruleFile;
+		return this;
+	}
+	
+	public CBRConfigTreeBuilder decisionTable( final String decisionTable )
+	{
+		this.decisionTable = decisionTable;
+		return this;
+	}
+	
+	public CBRConfigTreeBuilder ruleAgent( final String ruleAgent )
+	{
+		this.ruleAgent = ruleAgent;
+		return this;
+	}
+		
+	public CBRConfigTreeBuilder messagePaths( List<String> messagePathList )
+	{
+		this.messagePathList = messagePathList;
+		return this;
+	}
+	
+	public CBRConfigTreeBuilder ruleServiceImpl( String ruleServiceImpl )
+	{
+		this.ruleServiceImpl = ruleServiceImpl;
+		return this;
+	}
+	
+	public CBRConfigTreeBuilder stateful( final boolean stateful )
+	{
+		this.stateful = stateful;
+		return this;
+	}
+		
+	public ConfigTree build()
+	{
+        ConfigTree configTree = new ConfigTree("cbr-config");
+        
+        configTree.setAttribute( ListenerTagNames.RULE_RELOAD_TAG, Boolean.toString( reload ) );
+        
+        if ( ruleFile != null )
+            configTree.setAttribute( ListenerTagNames.RULE_SET_TAG, ruleFile );
+        else if ( decisionTable != null )
+            configTree.setAttribute( RuleServicePropertiesNames.DECISION_TABLE.getTagName(), decisionTable );
+        else if ( ruleAgent != null )
+            configTree.setAttribute( RuleServicePropertiesNames.RULE_AGENT_PROPERTIES.getTagName(), ruleAgent );
+        else
+        	throw new IllegalStateException("One of ruleFile, decisionTable or ruleAgent must be set");
+        
+            
+        if ( messagePathList != null )
+        {
+        	for (String messagePath : messagePathList)
+			{
+        		ConfigTree objectPath = new ConfigTree( ContentBasedWiretap.OBJECT_PATH_TAG, configTree );
+        		objectPath.setAttribute( ContentBasedWiretap.OBJECT_PATH, messagePath );
+			}
+        }
+        
+        if ( stateful )
+            configTree.setAttribute( RuleServicePropertiesNames.STATEFUL.getTagName(), Boolean.toString( stateful ) );
+        
+        if ( ruleServiceImpl != null )
+            configTree.setAttribute( RuleServicePropertiesNames.IMPL_CLASS.getTagName(), ruleServiceImpl );
+        
+        return configTree;
+	}
+}

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/ContentBasedRouterUnitTest.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/ContentBasedRouterUnitTest.java	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/ContentBasedRouterUnitTest.java	2008-11-05 13:39:40 UTC (rev 23714)
@@ -0,0 +1,142 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, 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.jboss.soa.esb.actions;
+
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.InputStream;
+import java.net.URI;
+
+import junit.framework.JUnit4TestAdapter;
+
+import org.apache.log4j.Logger;
+import org.jboss.internal.soa.esb.couriers.MockCourier;
+import org.jboss.internal.soa.esb.couriers.MockCourierFactory;
+import org.jboss.internal.soa.esb.services.registry.MockRegistry;
+import org.jboss.soa.esb.actions.ContentBasedRouter;
+import org.jboss.soa.esb.addressing.EPR;
+import org.jboss.soa.esb.client.ServiceInvoker;
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.message.format.MessageFactory;
+import org.jboss.soa.esb.message.format.MessageType;
+import org.jboss.soa.esb.testutils.FileUtil;
+import org.jboss.soa.esb.util.ClassUtil;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test the jBPM command interpreter class
+ *
+ * @author <a href="mailto:kurt.stam at jboss.com">Kurt Stam</a>
+ */
+
+
+public class ContentBasedRouterUnitTest
+{
+	static Logger 				_logger = Logger.getLogger(ContentBasedRouterUnitTest.class);
+    static Message message = null;
+    
+    private static EPR epr1;
+    private static EPR epr2;
+    private static EPR epr3;
+    private static MockCourier courier1;
+    private static MockCourier courier2;
+    private static MockCourier courier3;
+    
+    private static ConfigTree[] actions;
+	
+    public static junit.framework.Test suite()
+    {
+        return new JUnit4TestAdapter(ContentBasedRouterUnitTest.class);
+    }
+    
+    
+    @BeforeClass
+    public static void before() throws Exception {
+        MockCourierFactory.install();
+        MockRegistry.install();
+
+        epr1 = new EPR(new URI("test1"));
+        epr2 = new EPR(new URI("test2"));
+        epr3 = new EPR(new URI("DLS"));
+        courier1 = new MockCourier(true);
+        courier2 = new MockCourier(true);
+        courier3 = new MockCourier(true);
+
+        MockRegistry.register("test", "java", epr1, courier1);
+        MockRegistry.register("test", "xml", epr2, courier2);
+        MockRegistry.register(ServiceInvoker.INTERNAL_SERVICE_CATEGORY, ServiceInvoker.DEAD_LETTER_SERVICE_NAME, epr3, courier3);
+ 
+        message = MessageFactory.getInstance().getMessage(MessageType.JAVA_SERIALIZED);
+        message.getBody().add(("Hello CBR"));
+        
+        InputStream in = ClassUtil.getResourceAsStream("ContentBasedRouterUnitTest.xml", ContentBasedRouterUnitTest.class);
+        String xml = FileUtil.readStream(in);
+        actions = ConfigTree.fromXml(xml).getChildren("action");
+    }
+    
+    @Test
+	public void wrongDestinationName()
+    {
+		try {
+			ContentBasedRouter cbr = new ContentBasedRouter(actions[0]);
+            cbr.process(message);
+            //the config is wrong so we should error here, and try to send the message to the DLS
+            assertTrue(false);
+		} catch (Exception e) {
+            /* As it can't send the message to the DLS the log should say:
+               ERROR [main][ContentBasedWiretap] Destination serialized-destination does not exist your configuration
+               ERROR [main][ContentBasedWiretap] No rule destination(s) were matched, [serialized, xml]. Please fix your configuration and/or routing rules.
+             */
+			assertTrue(true);
+		}
+    }
+    
+    @Test
+    public void correctDestinationName()
+    {
+        try {
+            ContentBasedRouter cbr = new ContentBasedRouter(actions[1]);
+            Message returnMessage = cbr.process(message);
+            //the cbr should return a null message
+            assertNull(returnMessage);
+        } catch (Exception e) {
+            assertTrue(false);
+        }
+    }
+    
+    @Test
+    public void noDestinationMatches()
+    {
+        try {
+            ContentBasedRouter cbr = new ContentBasedRouter(actions[2]);
+            cbr.process(message);
+            //no destination matches, expecting error, and try to send the message to the DLS
+            assertTrue(false);
+        } catch (Exception e) {
+            assertTrue(true);
+        }
+    }
+}
\ No newline at end of file

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/ContentBasedRouterUnitTest.xml
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/ContentBasedRouterUnitTest.xml	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/ContentBasedRouterUnitTest.xml	2008-11-05 13:39:40 UTC (rev 23714)
@@ -0,0 +1,23 @@
+<testActions>
+	<action class="org.jboss.soa.esb.actions.ContentBasedRouter" name="WrongDestinion"
+		ruleSet="JBossESBRules.drl"
+		>
+			<route-to destination-name="serialized"  service-category="test"  service-name="java" /> 
+			<route-to destination-name="xml"         service-category="test"  service-name="xml" /> 
+	</action>
+	
+	<action class="org.jboss.soa.esb.actions.ContentBasedRouter" name="Correct"
+		ruleSet="JBossESBRules.drl"
+		>
+			<route-to destination-name="serialized-destination"  service-category="test"  service-name="java" /> 
+			<route-to destination-name="xml-destination"         service-category="test"  service-name="xml" /> 
+	</action>
+	
+	<action class="org.jboss.soa.esb.actions.ContentBasedRouter" name="MyType"
+		ruleSet="JBossESBRulesNoMatch.drl"
+		>
+			<route-to destination-name="mytype-destination"      service-category="test"  service-name="mytype" /> 
+			<route-to destination-name="xml-destination"         service-category="test"  service-name="xml" /> 
+	</action>
+
+</testActions>

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/ContentBasedWiretapUnitTest.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/ContentBasedWiretapUnitTest.java	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/ContentBasedWiretapUnitTest.java	2008-11-05 13:39:40 UTC (rev 23714)
@@ -0,0 +1,142 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, 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.jboss.soa.esb.actions;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.InputStream;
+import java.net.URI;
+
+import junit.framework.JUnit4TestAdapter;
+
+import org.apache.log4j.Logger;
+import org.jboss.internal.soa.esb.couriers.MockCourier;
+import org.jboss.internal.soa.esb.couriers.MockCourierFactory;
+import org.jboss.internal.soa.esb.services.registry.MockRegistry;
+import org.jboss.soa.esb.actions.ContentBasedWiretap;
+import org.jboss.soa.esb.addressing.EPR;
+import org.jboss.soa.esb.client.ServiceInvoker;
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.message.format.MessageFactory;
+import org.jboss.soa.esb.message.format.MessageType;
+import org.jboss.soa.esb.testutils.FileUtil;
+import org.jboss.soa.esb.util.ClassUtil;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test the jBPM command interpreter class
+ *
+ * @author <a href="mailto:kurt.stam at jboss.com">Kurt Stam</a>
+ */
+
+
+public class ContentBasedWiretapUnitTest
+{
+	static Logger 				_logger = Logger.getLogger(ContentBasedWiretapUnitTest.class);
+    static Message message = null;
+    
+    private static EPR epr1;
+    private static EPR epr2;
+    private static EPR epr3;
+    private static MockCourier courier1;
+    private static MockCourier courier2;
+    private static MockCourier courier3;
+    
+    private static ConfigTree[] actions;
+	
+    public static junit.framework.Test suite()
+    {
+        return new JUnit4TestAdapter(ContentBasedWiretapUnitTest.class);
+    }
+    
+    
+    @BeforeClass
+    public static void before() throws Exception {
+        MockCourierFactory.install();
+        MockRegistry.install();
+
+        epr1 = new EPR(new URI("test1"));
+        epr2 = new EPR(new URI("test2"));
+        epr3 = new EPR(new URI("DLS"));
+        courier1 = new MockCourier(true);
+        courier2 = new MockCourier(true);
+        courier3 = new MockCourier(true);
+
+        MockRegistry.register("test", "java", epr1, courier1);
+        MockRegistry.register("test", "xml", epr2, courier2);
+        MockRegistry.register(ServiceInvoker.INTERNAL_SERVICE_CATEGORY, ServiceInvoker.DEAD_LETTER_SERVICE_NAME, epr3, courier3);
+ 
+        message = MessageFactory.getInstance().getMessage(MessageType.JAVA_SERIALIZED);
+        message.getBody().add(("Hello CBR"));
+        
+        InputStream in = ClassUtil.getResourceAsStream("ContentBasedWiretapUnitTest.xml", ContentBasedWiretapUnitTest.class);
+        String xml = FileUtil.readStream(in);
+        actions = ConfigTree.fromXml(xml).getChildren("action");
+    }
+    
+    @Test
+	public void wrongDestinationName()
+    {
+		try {
+            ContentBasedWiretap cbr = new ContentBasedWiretap(actions[0]);
+            cbr.process(message);
+            //the config is wrong so we should error here, no message to the DLS
+            assertTrue(false);
+		} catch (Exception e) {
+            /* As it can't send the message to the DLS the log should say:
+               ERROR [main][ContentBasedWiretap] Destination serialized-destination does not exist your configuration
+               ERROR [main][ContentBasedWiretap] No rule destination(s) were matched, [serialized, xml]. Please fix your configuration and/or routing rules.
+             */
+			assertTrue(true);
+		}
+    }
+    
+    @Test
+    public void correctDestinationName()
+    {
+        try {
+            ContentBasedWiretap cbr = new ContentBasedWiretap(actions[1]);
+            Message returnMessage = cbr.process(message);
+            //the cbr should return a null message
+            assertNotNull(returnMessage);
+        } catch (Exception e) {
+            assertTrue(false);
+        }
+    }
+    
+    @Test
+    public void noDestinationMatches()
+    {
+        try {
+            ContentBasedWiretap cbr = new ContentBasedWiretap(actions[2]);
+            cbr.process(message);
+            //no destination matches, expecting error, and try to send the message to the DLS
+            assertTrue(false);
+        } catch (Exception e) {
+            assertTrue(true);
+        }
+    }
+}
\ No newline at end of file

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/ContentBasedWiretapUnitTest.xml
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/ContentBasedWiretapUnitTest.xml	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/ContentBasedWiretapUnitTest.xml	2008-11-05 13:39:40 UTC (rev 23714)
@@ -0,0 +1,23 @@
+<testActions>
+	<action class="org.jboss.soa.esb.actions.ContentBasedWiretap" name="WrongDestinion"
+		ruleSet="JBossESBRules.drl"
+		>
+			<route-to destination-name="serialized"  service-category="test"  service-name="java" /> 
+			<route-to destination-name="xml"         service-category="test"  service-name="xml" /> 
+	</action>
+	
+	<action class="org.jboss.soa.esb.actions.ContentBasedWiretap" name="Correct"
+		ruleSet="JBossESBRules.drl"
+		>
+			<route-to destination-name="serialized-destination"  service-category="test"  service-name="java" /> 
+			<route-to destination-name="xml-destination"         service-category="test"  service-name="xml" /> 
+	</action>
+	
+	<action class="org.jboss.soa.esb.actions.ContentBasedWiretap" name="MyType"
+		ruleSet="JBossESBRulesNoMatch.drl"
+		>
+			<route-to destination-name="mytype-destination"      service-category="test"  service-name="mytype" /> 
+			<route-to destination-name="xml-destination"         service-category="test"  service-name="xml" /> 
+	</action>
+
+</testActions>

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/Counter.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/Counter.java	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/Counter.java	2008-11-05 13:39:40 UTC (rev 23714)
@@ -0,0 +1,25 @@
+package org.jboss.soa.esb.actions;
+
+import java.io.Serializable;
+
+public class Counter implements Serializable
+{
+	private static final long serialVersionUID = 1L;
+	
+	int counter;
+	
+	public Counter() {}
+	public Counter(int counter) { this.counter = counter; }
+	
+	public int getCounter()
+	{
+		return counter;
+	}
+	public void setCounter( int counter )
+	{
+		this.counter = counter;
+	}
+	
+	
+
+}

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/MessageFilterUnitTest.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/MessageFilterUnitTest.java	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/MessageFilterUnitTest.java	2008-11-05 13:39:40 UTC (rev 23714)
@@ -0,0 +1,142 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, 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.jboss.soa.esb.actions;
+
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.InputStream;
+import java.net.URI;
+
+import junit.framework.JUnit4TestAdapter;
+
+import org.apache.log4j.Logger;
+import org.jboss.internal.soa.esb.couriers.MockCourier;
+import org.jboss.internal.soa.esb.couriers.MockCourierFactory;
+import org.jboss.internal.soa.esb.services.registry.MockRegistry;
+import org.jboss.soa.esb.actions.MessageFilter;
+import org.jboss.soa.esb.addressing.EPR;
+import org.jboss.soa.esb.client.ServiceInvoker;
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.message.format.MessageFactory;
+import org.jboss.soa.esb.message.format.MessageType;
+import org.jboss.soa.esb.testutils.FileUtil;
+import org.jboss.soa.esb.util.ClassUtil;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test the jBPM command interpreter class
+ *
+ * @author <a href="mailto:kurt.stam at jboss.com">Kurt Stam</a>
+ */
+
+
+public class MessageFilterUnitTest
+{
+	static Logger 				_logger = Logger.getLogger(MessageFilterUnitTest.class);
+    static Message message = null;
+    
+    private static EPR epr1;
+    private static EPR epr2;
+    private static EPR epr3;
+    private static MockCourier courier1;
+    private static MockCourier courier2;
+    private static MockCourier courier3;
+    
+    private static ConfigTree[] actions;
+	
+    public static junit.framework.Test suite()
+    {
+        return new JUnit4TestAdapter(MessageFilterUnitTest.class);
+    }
+    
+    
+    @BeforeClass
+    public static void before() throws Exception {
+        MockCourierFactory.install();
+        MockRegistry.install();
+
+        epr1 = new EPR(new URI("test1"));
+        epr2 = new EPR(new URI("test2"));
+        epr3 = new EPR(new URI("DLS"));
+        courier1 = new MockCourier(true);
+        courier2 = new MockCourier(true);
+        courier3 = new MockCourier(true);
+
+        MockRegistry.register("test", "java", epr1, courier1);
+        MockRegistry.register("test", "xml", epr2, courier2);
+        MockRegistry.register(ServiceInvoker.INTERNAL_SERVICE_CATEGORY, ServiceInvoker.DEAD_LETTER_SERVICE_NAME, epr3, courier3);
+ 
+        message = MessageFactory.getInstance().getMessage(MessageType.JAVA_SERIALIZED);
+        message.getBody().add(("Hello CBR"));
+        
+        InputStream in = ClassUtil.getResourceAsStream("ContentBasedRouterUnitTest.xml", MessageFilterUnitTest.class);
+        String xml = FileUtil.readStream(in);
+        actions = ConfigTree.fromXml(xml).getChildren("action");
+    }
+    
+    @Test
+	public void wrongDestinationName()
+    {
+		try {
+            MessageFilter cbr = new MessageFilter(actions[0]);
+            cbr.process(message);
+            //the config is wrong so we should error here, and try to send the message to the DLS
+            assertTrue(false);
+		} catch (Exception e) {
+            /* As it can't send the message to the DLS the log should say:
+               ERROR [main][ContentBasedWiretap] Destination serialized-destination does not exist your configuration
+               ERROR [main][ContentBasedWiretap] No rule destination(s) were matched, [serialized, xml]. Please fix your configuration and/or routing rules.
+             */
+			assertTrue(true);
+		}
+    }
+    
+    @Test
+    public void correctDestinationName()
+    {
+        try {
+            MessageFilter cbr = new MessageFilter(actions[1]);
+            Message returnMessage = cbr.process(message);
+            //the cbr should return a null message
+            assertNull(returnMessage);
+        } catch (Exception e) {
+            assertTrue(false);
+        }
+    }
+    
+    @Test
+    public void noDestinationMatches()
+    {
+        try {
+            MessageFilter cbr = new MessageFilter(actions[2]);
+            Message returnMessage = cbr.process(message);
+            //the cbr should return a null message, message should be filtered with no errors.
+            assertNull(returnMessage);
+        } catch (Exception e) {
+            assertTrue(false);
+        }
+    }
+}
\ No newline at end of file

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/MessageFilterUnitTest.xml
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/MessageFilterUnitTest.xml	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/MessageFilterUnitTest.xml	2008-11-05 13:39:40 UTC (rev 23714)
@@ -0,0 +1,23 @@
+<testActions>
+	<action class="org.jboss.soa.esb.actions.MessageFilter" name="WrongDestinion"
+		ruleSet="JBossESBRules.drl"
+		>
+			<route-to destination-name="serialized"  service-category="test"  service-name="java" /> 
+			<route-to destination-name="xml"         service-category="test"  service-name="xml" /> 
+	</action>
+	
+	<action class="org.jboss.soa.esb.actions.MessageFilter" name="Correct"
+		ruleSet="JBossESBRules.drl"
+		>
+			<route-to destination-name="serialized-destination"  service-category="test"  service-name="java" /> 
+			<route-to destination-name="xml-destination"         service-category="test"  service-name="xml" /> 
+	</action>
+	
+	<action class="org.jboss.soa.esb.actions.MessageFilter" name="MyType"
+		ruleSet="JBossESBRulesNoMatch.drl"
+		>
+			<route-to destination-name="mytype-destination"      service-category="test"  service-name="mytype" /> 
+			<route-to destination-name="xml-destination"         service-category="test"  service-name="xml" /> 
+	</action>
+
+</testActions>

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/5KBNS_message.xml
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/5KBNS_message.xml	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/5KBNS_message.xml	2008-11-05 13:39:40 UTC (rev 23714)
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Order xmlns="http://org.jboss.soa.esb/order"
+	orderId="1" orderDate="Wed Nov 15 13:45:28 EST 2006" statusCode="0" netAmount="59.97" totalAmount="64.92" tax="4.95">
+	<Customer xmlns="http://org.jboss.soa.esb/customer" userName="user1" firstName="Harry" lastName="Fletcher" state="SD"/>
+	<OrderLines>
+		<OrderLine position="1" quantity="1">
+			<prod:Product xmlns:prod="http://org.jboss.soa.esb/product" productId="364" title="The 40-Year-Old Virgin " price="29.98"/>
+		</OrderLine>
+		<OrderLine position="2" quantity="2">
+			<prod2:Product xmlns:prod2="http://org.jboss.soa.esb/product" productId="364" title="The 40-Year-Old Virgin " price="29.98"/>
+		</OrderLine>
+	</OrderLines>
+</Order>

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/5KB_message.xml
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/5KB_message.xml	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/5KB_message.xml	2008-11-05 13:39:40 UTC (rev 23714)
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Order orderId="1" orderDate="Wed Nov 15 13:45:28 EST 2006" statusCode="0" netAmount="59.97" totalAmount="64.92" tax="4.95">
+	<Customer userName="user1" firstName="Harry" lastName="Fletcher" state="SD"/>
+	<OrderLines>
+		<OrderLine position="1" quantity="1">
+			<Product productId="364" title="The 40-Year-Old Virgin " price="29.98"/>
+		</OrderLine>
+		<OrderLine position="2" quantity="1">
+			<Product productId="299" title="Pulp Fiction" price="29.99"/>
+		</OrderLine>
+		<OrderLine position="1" quantity="1">
+			<Product productId="364" title="The 40-Year-Old Virgin " price="29.98"/>
+		</OrderLine>
+		<OrderLine position="2" quantity="1">
+			<Product productId="299" title="Pulp Fiction" price="29.99"/>
+		</OrderLine>
+		<OrderLine position="1" quantity="1">
+			<Product productId="364" title="The 40-Year-Old Virgin " price="29.98"/>
+		</OrderLine>
+		<OrderLine position="2" quantity="1">
+			<Product productId="299" title="Pulp Fiction" price="29.99"/>
+		</OrderLine>
+		<OrderLine position="1" quantity="1">
+			<Product productId="364" title="The 40-Year-Old Virgin " price="29.98"/>
+		</OrderLine>
+		<OrderLine position="2" quantity="1">
+			<Product productId="299" title="Pulp Fiction" price="29.99"/>
+		</OrderLine>
+		<OrderLine position="1" quantity="1">
+			<Product productId="364" title="The 40-Year-Old Virgin " price="29.98"/>
+		</OrderLine>
+		<OrderLine position="2" quantity="1">
+			<Product productId="299" title="Pulp Fiction" price="29.99"/>
+		</OrderLine>
+		<OrderLine position="1" quantity="1">
+			<Product productId="364" title="The 40-Year-Old Virgin " price="29.98"/>
+		</OrderLine>
+		<OrderLine position="2" quantity="1">
+			<Product productId="299" title="Pulp Fiction" price="29.99"/>
+		</OrderLine>
+		<OrderLine position="1" quantity="1">
+			<Product productId="364" title="The 40-Year-Old Virgin " price="29.98"/>
+		</OrderLine>
+		<OrderLine position="2" quantity="1">
+			<Product productId="299" title="Pulp Fiction" price="29.99"/>
+		</OrderLine>
+		<OrderLine position="1" quantity="1">
+			<Product productId="364" title="The 40-Year-Old Virgin " price="29.98"/>
+		</OrderLine>
+		<OrderLine position="2" quantity="1">
+			<Product productId="299" title="Pulp Fiction" price="29.99"/>
+		</OrderLine>
+		<OrderLine position="1" quantity="1">
+			<Product productId="364" title="The 40-Year-Old Virgin " price="29.98"/>
+		</OrderLine>
+		<OrderLine position="2" quantity="1">
+			<Product productId="299" title="Pulp Fiction" price="29.99"/>
+		</OrderLine>
+		<OrderLine position="1" quantity="1">
+			<Product productId="364" title="The 40-Year-Old Virgin " price="29.98"/>
+		</OrderLine>
+		<OrderLine position="2" quantity="1">
+			<Product productId="299" title="Pulp Fiction" price="29.99"/>
+		</OrderLine>
+		<OrderLine position="1" quantity="1">
+			<Product productId="364" title="The 40-Year-Old Virgin " price="29.98"/>
+		</OrderLine>
+		<OrderLine position="2" quantity="1">
+			<Product productId="299" title="Pulp Fiction" price="29.99"/>
+		</OrderLine>
+		<OrderLine position="1" quantity="1">
+			<Product productId="364" title="The 40-Year-Old Virgin " price="29.98"/>
+		</OrderLine>
+		<OrderLine position="2" quantity="1">
+			<Product productId="299" title="Pulp Fiction" price="29.99"/>
+		</OrderLine>
+		<OrderLine position="1" quantity="1">
+			<Product productId="364" title="The 40-Year-Old Virgin " price="29.98"/>
+		</OrderLine>
+		<OrderLine position="2" quantity="1">
+			<Product productId="299" title="Pulp Fiction" price="29.99"/>
+		</OrderLine>
+		<OrderLine position="1" quantity="1">
+			<Product productId="364" title="The 40-Year-Old Virgin " price="29.98"/>
+		</OrderLine>
+		<OrderLine position="2" quantity="1">
+			<Product productId="299" title="Pulp Fiction" price="29.99"/>
+		</OrderLine>
+		<OrderLine position="1" quantity="1">
+			<Product productId="364" title="The 40-Year-Old Virgin " price="29.98"/>
+		</OrderLine>
+		<OrderLine position="2" quantity="1">
+			<Product productId="299" title="Pulp Fiction" price="29.99"/>
+		</OrderLine>
+		<OrderLine position="1" quantity="1">
+			<Product productId="364" title="The 40-Year-Old Virgin " price="29.98"/>
+		</OrderLine>
+		<OrderLine position="2" quantity="1">
+			<Product productId="299" title="Pulp Fiction" price="29.99"/>
+		</OrderLine>
+		<OrderLine position="1" quantity="1">
+			<Product productId="364" title="The 40-Year-Old Virgin " price="29.98"/>
+		</OrderLine>
+		<OrderLine position="2" quantity="1">
+			<Product productId="299" title="Pulp Fiction" price="29.99"/>
+		</OrderLine>
+		<OrderLine position="1" quantity="1">
+			<Product productId="364" title="The 40-Year-Old Virgin " price="29.98"/>
+		</OrderLine>
+		<OrderLine position="2" quantity="1">
+			<Product productId="299" title="Pulp Fiction" price="29.99"/>
+		</OrderLine>
+		<OrderLine position="1" quantity="1">
+			<Product productId="364" title="The 40-Year-Old Virgin " price="29.98"/>
+		</OrderLine>
+		<OrderLine position="2" quantity="1">
+			<Product productId="299" title="Pulp Fiction" price="29.99"/>
+		</OrderLine>
+		<OrderLine position="1" quantity="1">
+			<Product productId="364" title="The 40-Year-Old Virgin " price="29.98"/>
+		</OrderLine>
+		<OrderLine position="2" quantity="1">
+			<Product productId="299" title="Pulp Fiction" price="29.99"/>
+		</OrderLine>
+		<OrderLine position="1" quantity="1">
+			<Product productId="364" title="The 40-Year-Old Virgin " price="29.98"/>
+		</OrderLine>
+		<OrderLine position="2" quantity="1">
+			<Product productId="299" title="Pulp Fiction" price="29.99"/>
+		</OrderLine>
+	</OrderLines>
+</Order>

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/JBossESBPricingRulesStateful.drl
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/JBossESBPricingRulesStateful.drl	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/JBossESBPricingRulesStateful.drl	2008-11-05 13:39:40 UTC (rev 23714)
@@ -0,0 +1,46 @@
+package com.jboss.soa.esb.routing.cbr
+
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.message.format.MessageType;
+import org.jboss.internal.soa.esb.services.routing.cbr.Order;
+import org.jboss.soa.esb.actions.Counter;
+
+global Message message;
+
+rule "Pricing Rule - low quantity"
+	
+	when
+	    m     : Message ()
+		order : Order( quantity < 10)
+	then
+		#System.out.println("low volume");
+		order.setDiscount(0);
+		m.getBody().add("DiscountObject","0%");
+end
+
+rule "Prioriting Rule - high quantity"
+	when
+	    m     : Message ()
+		order : Order( quantity >= 10)
+		Order( discount == 0 )
+		not Counter()
+	then 
+		System.out.println("high volume");
+		order.setDiscount( 20 );
+		insert( new Counter(1) );
+		m.getBody().add("DiscountObject","20%");
+end
+
+rule "Continue Rule - high quantity"
+	no-loop
+	when
+	    $counter : Counter()
+	    m     : Message ()
+	then 
+		System.out.println("Continue high quantity. Int value == " + $counter.getCounter());
+		Integer inc = $counter.getCounter();
+		inc++;
+		$counter.setCounter( inc );
+		m.getBody().add( "Counter", $counter );
+		System.out.println("Continue high quantity. Inc value == " + $counter.getCounter());
+end
\ No newline at end of file

Modified: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/JBossESBRules.drl
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/JBossESBRules.drl	2008-11-05 12:54:27 UTC (rev 23713)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/JBossESBRules.drl	2008-11-05 13:39:40 UTC (rev 23714)
@@ -7,6 +7,7 @@
 
 #declare any global variables here
 global java.util.List destinations;
+global Message message;
 
 
 rule "Routing Rule - Serialized based message"
@@ -26,4 +27,4 @@
 	then 
 		System.out.println("JBoss_XML"); 
 		destinations.add("xml-destination");
-end
\ No newline at end of file
+end

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/RuleBaseHelper.drl
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/RuleBaseHelper.drl	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/RuleBaseHelper.drl	2008-11-05 13:39:40 UTC (rev 23714)
@@ -0,0 +1,29 @@
+#created on: Oct 30, 2006
+package org.jboss.internal.soa.esb.rules
+
+#list any import classes here.
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.message.format.MessageType;
+
+#declare any global variables here
+global java.util.List destinations;
+
+
+rule "Routing Rule - Serialized based message"
+	
+	when
+		Message( type == MessageType.JAVA_SERIALIZED)
+	then
+		System.out.println("Serialized");
+		destinations.add("serialized-destination");
+		
+end
+
+rule "Routing Rule - XML based message"
+	
+	when
+		Message( type == MessageType.JBOSS_XML)
+	then 
+		System.out.println("JBoss_XML"); 
+		destinations.add("xml-destination");
+end
\ No newline at end of file

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/RuleBaseHelper.properties
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/RuleBaseHelper.properties	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/RuleBaseHelper.properties	2008-11-05 13:39:40 UTC (rev 23714)
@@ -0,0 +1,8 @@
+##
+## RuleAgent configuration file example
+##
+
+newInstance=true
+file=src/test/resources/testrules.pkg
+poll=30
+name=MyConfig
\ No newline at end of file

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/RuleBaseHelper.xls
===================================================================
(Binary files differ)


Property changes on: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/RuleBaseHelper.xls
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/RulesWithDsl.drl
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/RulesWithDsl.drl	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/RulesWithDsl.drl	2008-11-05 13:39:40 UTC (rev 23714)
@@ -0,0 +1,816 @@
+package com.jboss.soa.esb.routing.cbr
+
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.message.format.MessageType;
+import javax.xml.xpath.XPathExpression;
+
+expander XPathLanguage.dsl
+
+global java.util.List destinations;
+
+rule "ProductId1"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "1"
+	then
+		Destination : "regular1";
+end
+
+rule "ProductId2"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "2"
+	then
+		Destination : "regular2";
+end
+
+rule "ProductId3"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "3"
+	then
+		Destination : "regular3";
+end
+
+rule "ProductId4"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "4"
+	then
+		Destination : "regular4";
+end
+
+rule "ProductId5"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "5"
+	then
+		Destination : "regular5";
+end
+
+rule "ProductId6"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "6"
+	then
+		Destination : "regular6";
+end
+
+rule "ProductId7"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "7"
+	then
+		Destination : "regular7";
+end
+
+rule "ProductId8"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "8"
+	then
+		Destination : "regular8";
+end
+
+rule "ProductId9"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "9"
+	then
+		Destination : "regular9";
+end
+
+rule "ProductId10"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "10"
+	then
+		Destination : "regular1";
+end
+
+rule "ProductId11"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "11"
+	then
+		Destination : "regular2";
+end
+
+rule "ProductId12"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "12"
+	then
+		Destination : "regular3";
+end
+
+rule "ProductId13"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "13"
+	then
+		Destination : "regular4";
+end
+
+rule "ProductId14"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "14"
+	then
+		Destination : "regular5";
+end
+
+rule "ProductId15"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "15"
+	then
+		Destination : "regular6";
+end
+
+rule "ProductId16"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "16"
+	then
+		Destination : "regular7";
+end
+
+rule "ProductId17"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "17"
+	then
+		Destination : "regular8";
+end
+
+rule "ProductId18"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "18"
+	then
+		Destination : "regular9";
+end
+
+rule "ProductId19"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "19"
+	then
+		Destination : "regular1";
+end
+
+rule "ProductId20"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "20"
+	then
+		Destination : "regular2";
+end
+
+rule "ProductId21"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "21"
+	then
+		Destination : "regular3";
+end
+
+rule "ProductId22"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "22"
+	then
+		Destination : "regular4";
+end
+
+rule "ProductId23"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "23"
+	then
+		Destination : "regular5";
+end
+
+rule "ProductId24"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "24"
+	then
+		Destination : "regular6";
+end
+
+rule "ProductId25"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "25"
+	then
+		Destination : "regular7";
+end
+
+rule "ProductId26"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "26"
+	then
+		Destination : "regular8";
+end
+
+rule "ProductId27"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "27"
+	then
+		Destination : "regular9";
+end
+
+rule "ProductId28"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "28"
+	then
+		Destination : "regular1";
+end
+
+rule "ProductId29"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "29"
+	then
+		Destination : "regular2";
+end
+
+rule "ProductId30"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "30"
+	then
+		Destination : "regular3";
+end
+
+rule "ProductId31"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "31"
+	then
+		Destination : "regular4";
+end
+
+rule "ProductId32"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "32"
+	then
+		Destination : "regular5";
+end
+
+rule "ProductId33"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "33"
+	then
+		Destination : "regular6";
+end
+
+rule "ProductId34"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "34"
+	then
+		Destination : "regular7";
+end
+
+rule "ProductId35"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "35"
+	then
+		Destination : "regular8";
+end
+
+rule "ProductId36"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "36"
+	then
+		Destination : "regular9";
+end
+
+rule "ProductId37"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "37"
+	then
+		Destination : "regular1";
+end
+
+rule "ProductId38"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "38"
+	then
+		Destination : "regular2";
+end
+
+rule "ProductId39"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "39"
+	then
+		Destination : "regular3";
+end
+
+rule "ProductId40"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "40"
+	then
+		Destination : "regular4";
+end
+
+rule "ProductId41"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "41"
+	then
+		Destination : "regular5";
+end
+
+rule "ProductId42"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "42"
+	then
+		Destination : "regular6";
+end
+
+rule "ProductId43"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "43"
+	then
+		Destination : "regular7";
+end
+
+rule "ProductId44"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "44"
+	then
+		Destination : "regular8";
+end
+
+rule "ProductId45"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "45"
+	then
+		Destination : "regular9";
+end
+
+rule "ProductId46"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "46"
+	then
+		Destination : "regular1";
+end
+
+rule "ProductId47"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "47"
+	then
+		Destination : "regular2";
+end
+
+rule "ProductId48"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "48"
+	then
+		Destination : "regular3";
+end
+
+rule "ProductId49"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "49"
+	then
+		Destination : "regular4";
+end
+
+rule "ProductId50"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "50"
+	then
+		Destination : "regular5";
+end
+
+rule "ProductId51"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "51"
+	then
+		Destination : "regular6";
+end
+
+rule "ProductId52"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "52"
+	then
+		Destination : "regular7";
+end
+
+rule "ProductId53"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "53"
+	then
+		Destination : "regular8";
+end
+
+rule "ProductId54"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "54"
+	then
+		Destination : "regular9";
+end
+
+rule "ProductId55"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "55"
+	then
+		Destination : "regular1";
+end
+
+rule "ProductId56"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "56"
+	then
+		Destination : "regular2";
+end
+
+rule "ProductId57"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "57"
+	then
+		Destination : "regular3";
+end
+
+rule "ProductId58"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "58"
+	then
+		Destination : "regular4";
+end
+
+rule "ProductId59"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "59"
+	then
+		Destination : "regular5";
+end
+
+rule "ProductId60"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "60"
+	then
+		Destination : "regular6";
+end
+
+rule "ProductId61"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "61"
+	then
+		Destination : "regular7";
+end
+
+rule "ProductId62"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "62"
+	then
+		Destination : "regular8";
+end
+
+rule "ProductId63"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "63"
+	then
+		Destination : "regular9";
+end
+
+rule "ProductId64"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "64"
+	then
+		Destination : "regular1";
+end
+
+rule "ProductId65"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "65"
+	then
+		Destination : "regular2";
+end
+
+rule "ProductId66"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "66"
+	then
+		Destination : "regular3";
+end
+
+rule "ProductId67"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "67"
+	then
+		Destination : "regular4";
+end
+
+rule "ProductId68"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "68"
+	then
+		Destination : "regular5";
+end
+
+rule "ProductId69"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "69"
+	then
+		Destination : "regular6";
+end
+
+rule "ProductId70"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "70"
+	then
+		Destination : "regular7";
+end
+
+rule "ProductId71"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "71"
+	then
+		Destination : "regular8";
+end
+
+rule "ProductId72"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "72"
+	then
+		Destination : "regular9";
+end
+
+rule "ProductId73"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "73"
+	then
+		Destination : "regular1";
+end
+
+rule "ProductId74"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "74"
+	then
+		Destination : "regular2";
+end
+
+rule "ProductId75"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "75"
+	then
+		Destination : "regular3";
+end
+
+rule "ProductId76"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "76"
+	then
+		Destination : "regular4";
+end
+
+rule "ProductId77"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "77"
+	then
+		Destination : "regular5";
+end
+
+rule "ProductId78"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "78"
+	then
+		Destination : "regular6";
+end
+
+rule "ProductId79"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "79"
+	then
+		Destination : "regular7";
+end
+
+rule "ProductId80"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "80"
+	then
+		Destination : "regular8";
+end
+
+rule "ProductId81"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "81"
+	then
+		Destination : "regular9";
+end
+
+rule "ProductId82"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "82"
+	then
+		Destination : "regular1";
+end
+
+rule "ProductId83"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "83"
+	then
+		Destination : "regular2";
+end
+
+rule "ProductId84"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "84"
+	then
+		Destination : "regular3";
+end
+
+rule "ProductId85"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "85"
+	then
+		Destination : "regular4";
+end
+
+rule "ProductId86"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "86"
+	then
+		Destination : "regular5";
+end
+
+rule "ProductId87"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "87"
+	then
+		Destination : "regular6";
+end
+
+rule "ProductId88"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "88"
+	then
+		Destination : "regular7";
+end
+
+rule "ProductId89"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "89"
+	then
+		Destination : "regular8";
+end
+
+rule "ProductId90"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "90"
+	then
+		Destination : "regular9";
+end
+
+rule "ProductId91"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "91"
+	then
+		Destination : "regular1";
+end
+
+rule "ProductId92"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "92"
+	then
+		Destination : "regular2";
+end
+
+rule "ProductId93"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "93"
+	then
+		Destination : "regular3";
+end
+
+rule "ProductId94"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "94"
+	then
+		Destination : "regular4";
+end
+
+rule "ProductId95"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "95"
+	then
+		Destination : "regular5";
+end
+
+rule "ProductId96"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "96"
+	then
+		Destination : "regular6";
+end
+
+rule "ProductId97"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "97"
+	then
+		Destination : "regular7";
+end
+
+rule "ProductId98"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "98"
+	then
+		Destination : "regular8";
+end
+
+rule "ProductId99"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "99"
+	then
+		Destination : "regular9";
+end
+
+rule "ProductId299"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "299"
+	then
+		Destination : "regular0";
+end
+
+rule "Default rule"
+	salience 1
+	when
+	then
+		Destination : "regular0";
+end

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/RulesWithDslNS.drl
===================================================================
--- labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/RulesWithDslNS.drl	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/RulesWithDslNS.drl	2008-11-05 13:39:40 UTC (rev 23714)
@@ -0,0 +1,809 @@
+package com.jboss.soa.esb.routing.cbr
+
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.message.format.MessageType;
+import javax.xml.xpath.XPathExpression;
+
+expander XPathLanguage.dsl
+
+global java.util.List destinations;
+
+rule "ProductId1"
+	salience 99
+	when
+		xpathMatch expr "/order:Order/order:OrderLines/order:OrderLine/prod:Product/@productId" use namespaces "order=http://org.jboss.soa.esb/order,prod=http://org.jboss.soa.esb/product"
+	then
+		Destination : "regular1";
+end
+
+rule "ProductId2"
+	salience 99
+	when
+		xpathEquals expr "/order:Order/order:OrderLines/order:OrderLine/prod:Product/@productId", "364" use namespaces "order=http://org.jboss.soa.esb/order,prod=http://org.jboss.soa.esb/product"
+	then
+		Destination : "regular2";
+end
+
+rule "ProductId3"
+	salience 99
+	when
+		xpathGreaterThan expr "/o:Order/o:OrderLines/o:OrderLine/p:Product/@productId", "200" use namespaces "o=http://org.jboss.soa.esb/order,p=http://org.jboss.soa.esb/product"
+	then
+		Destination : "regular3";
+end
+
+rule "ProductId4"
+	salience 99
+	when
+		xpathLessThan expr "/o:Order/o:OrderLines/o:OrderLine/p:Product/@productId", "200" use namespaces "o=http://org.jboss.soa.esb/order,p=http://org.jboss.soa.esb/product"
+	then
+		Destination : "regular4";
+end
+
+rule "ProductId5"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "5"
+	then
+		Destination : "regular5";
+end
+
+rule "ProductId6"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "6"
+	then
+		Destination : "regular6";
+end
+
+rule "ProductId7"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "7"
+	then
+		Destination : "regular7";
+end
+
+rule "ProductId8"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "8"
+	then
+		Destination : "regular8";
+end
+
+rule "ProductId9"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "9"
+	then
+		Destination : "regular9";
+end
+
+rule "ProductId10"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "10"
+	then
+		Destination : "regular1";
+end
+
+rule "ProductId11"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "11"
+	then
+		Destination : "regular2";
+end
+
+rule "ProductId12"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "12"
+	then
+		Destination : "regular3";
+end
+
+rule "ProductId13"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "13"
+	then
+		Destination : "regular4";
+end
+
+rule "ProductId14"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "14"
+	then
+		Destination : "regular5";
+end
+
+rule "ProductId15"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "15"
+	then
+		Destination : "regular6";
+end
+
+rule "ProductId16"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "16"
+	then
+		Destination : "regular7";
+end
+
+rule "ProductId17"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "17"
+	then
+		Destination : "regular8";
+end
+
+rule "ProductId18"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "18"
+	then
+		Destination : "regular9";
+end
+
+rule "ProductId19"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "19"
+	then
+		Destination : "regular1";
+end
+
+rule "ProductId20"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "20"
+	then
+		Destination : "regular2";
+end
+
+rule "ProductId21"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "21"
+	then
+		Destination : "regular3";
+end
+
+rule "ProductId22"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "22"
+	then
+		Destination : "regular4";
+end
+
+rule "ProductId23"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "23"
+	then
+		Destination : "regular5";
+end
+
+rule "ProductId24"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "24"
+	then
+		Destination : "regular6";
+end
+
+rule "ProductId25"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "25"
+	then
+		Destination : "regular7";
+end
+
+rule "ProductId26"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "26"
+	then
+		Destination : "regular8";
+end
+
+rule "ProductId27"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "27"
+	then
+		Destination : "regular9";
+end
+
+rule "ProductId28"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "28"
+	then
+		Destination : "regular1";
+end
+
+rule "ProductId29"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "29"
+	then
+		Destination : "regular2";
+end
+
+rule "ProductId30"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "30"
+	then
+		Destination : "regular3";
+end
+
+rule "ProductId31"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "31"
+	then
+		Destination : "regular4";
+end
+
+rule "ProductId32"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "32"
+	then
+		Destination : "regular5";
+end
+
+rule "ProductId33"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "33"
+	then
+		Destination : "regular6";
+end
+
+rule "ProductId34"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "34"
+	then
+		Destination : "regular7";
+end
+
+rule "ProductId35"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "35"
+	then
+		Destination : "regular8";
+end
+
+rule "ProductId36"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "36"
+	then
+		Destination : "regular9";
+end
+
+rule "ProductId37"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "37"
+	then
+		Destination : "regular1";
+end
+
+rule "ProductId38"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "38"
+	then
+		Destination : "regular2";
+end
+
+rule "ProductId39"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "39"
+	then
+		Destination : "regular3";
+end
+
+rule "ProductId40"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "40"
+	then
+		Destination : "regular4";
+end
+
+rule "ProductId41"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "41"
+	then
+		Destination : "regular5";
+end
+
+rule "ProductId42"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "42"
+	then
+		Destination : "regular6";
+end
+
+rule "ProductId43"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "43"
+	then
+		Destination : "regular7";
+end
+
+rule "ProductId44"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "44"
+	then
+		Destination : "regular8";
+end
+
+rule "ProductId45"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "45"
+	then
+		Destination : "regular9";
+end
+
+rule "ProductId46"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "46"
+	then
+		Destination : "regular1";
+end
+
+rule "ProductId47"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "47"
+	then
+		Destination : "regular2";
+end
+
+rule "ProductId48"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "48"
+	then
+		Destination : "regular3";
+end
+
+rule "ProductId49"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "49"
+	then
+		Destination : "regular4";
+end
+
+rule "ProductId50"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "50"
+	then
+		Destination : "regular5";
+end
+
+rule "ProductId51"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "51"
+	then
+		Destination : "regular6";
+end
+
+rule "ProductId52"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "52"
+	then
+		Destination : "regular7";
+end
+
+rule "ProductId53"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "53"
+	then
+		Destination : "regular8";
+end
+
+rule "ProductId54"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "54"
+	then
+		Destination : "regular9";
+end
+
+rule "ProductId55"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "55"
+	then
+		Destination : "regular1";
+end
+
+rule "ProductId56"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "56"
+	then
+		Destination : "regular2";
+end
+
+rule "ProductId57"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "57"
+	then
+		Destination : "regular3";
+end
+
+rule "ProductId58"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "58"
+	then
+		Destination : "regular4";
+end
+
+rule "ProductId59"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "59"
+	then
+		Destination : "regular5";
+end
+
+rule "ProductId60"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "60"
+	then
+		Destination : "regular6";
+end
+
+rule "ProductId61"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "61"
+	then
+		Destination : "regular7";
+end
+
+rule "ProductId62"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "62"
+	then
+		Destination : "regular8";
+end
+
+rule "ProductId63"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "63"
+	then
+		Destination : "regular9";
+end
+
+rule "ProductId64"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "64"
+	then
+		Destination : "regular1";
+end
+
+rule "ProductId65"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "65"
+	then
+		Destination : "regular2";
+end
+
+rule "ProductId66"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "66"
+	then
+		Destination : "regular3";
+end
+
+rule "ProductId67"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "67"
+	then
+		Destination : "regular4";
+end
+
+rule "ProductId68"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "68"
+	then
+		Destination : "regular5";
+end
+
+rule "ProductId69"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "69"
+	then
+		Destination : "regular6";
+end
+
+rule "ProductId70"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "70"
+	then
+		Destination : "regular7";
+end
+
+rule "ProductId71"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "71"
+	then
+		Destination : "regular8";
+end
+
+rule "ProductId72"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "72"
+	then
+		Destination : "regular9";
+end
+
+rule "ProductId73"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "73"
+	then
+		Destination : "regular1";
+end
+
+rule "ProductId74"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "74"
+	then
+		Destination : "regular2";
+end
+
+rule "ProductId75"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "75"
+	then
+		Destination : "regular3";
+end
+
+rule "ProductId76"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "76"
+	then
+		Destination : "regular4";
+end
+
+rule "ProductId77"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "77"
+	then
+		Destination : "regular5";
+end
+
+rule "ProductId78"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "78"
+	then
+		Destination : "regular6";
+end
+
+rule "ProductId79"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "79"
+	then
+		Destination : "regular7";
+end
+
+rule "ProductId80"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "80"
+	then
+		Destination : "regular8";
+end
+
+rule "ProductId81"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "81"
+	then
+		Destination : "regular9";
+end
+
+rule "ProductId82"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "82"
+	then
+		Destination : "regular1";
+end
+
+rule "ProductId83"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "83"
+	then
+		Destination : "regular2";
+end
+
+rule "ProductId84"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "84"
+	then
+		Destination : "regular3";
+end
+
+rule "ProductId85"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "85"
+	then
+		Destination : "regular4";
+end
+
+rule "ProductId86"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "86"
+	then
+		Destination : "regular5";
+end
+
+rule "ProductId87"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "87"
+	then
+		Destination : "regular6";
+end
+
+rule "ProductId88"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "88"
+	then
+		Destination : "regular7";
+end
+
+rule "ProductId89"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "89"
+	then
+		Destination : "regular8";
+end
+
+rule "ProductId90"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "90"
+	then
+		Destination : "regular9";
+end
+
+rule "ProductId91"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "91"
+	then
+		Destination : "regular1";
+end
+
+rule "ProductId92"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "92"
+	then
+		Destination : "regular2";
+end
+
+rule "ProductId93"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "93"
+	then
+		Destination : "regular3";
+end
+
+rule "ProductId94"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "94"
+	then
+		Destination : "regular4";
+end
+
+rule "ProductId95"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "95"
+	then
+		Destination : "regular5";
+end
+
+rule "ProductId96"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "96"
+	then
+		Destination : "regular6";
+end
+
+rule "ProductId97"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "97"
+	then
+		Destination : "regular7";
+end
+
+rule "ProductId98"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "98"
+	then
+		Destination : "regular8";
+end
+
+rule "ProductId99"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "99"
+	then
+		Destination : "regular9";
+end
+
+rule "ProductId299"
+	salience 100
+	when
+		xpathEquals "/Order/OrderLines/OrderLine/Product/@productId", "299"
+	then
+		Destination : "regular0";
+end

Added: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/testrules.pkg
===================================================================
(Binary files differ)


Property changes on: labs/jbossesb/branches/JBESB_4_2_1_GA_CP/product/services/jbrules/src/test/resources/testrules.pkg
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream




More information about the jboss-svn-commits mailing list