[jboss-svn-commits] JBL Code SVN: r27480 - in labs/jbossesb/trunk/product: services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/routing/cbr and 11 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Fri Jul 3 04:49:57 EDT 2009


Author: beve
Date: 2009-07-03 04:49:57 -0400 (Fri, 03 Jul 2009)
New Revision: 27480

Added:
   labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleInfoBuilder.java
   labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleInfoImpl.java
   labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/StatefulRuleInfoImpl.java
   labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/util/RuleConfigUtil.java
   labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/soa/esb/services/rules/RuleInfo.java
   labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/soa/esb/services/rules/StatefulRuleInfo.java
   labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/rules/RuleInfoImplUnitTest.java
   labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/rules/util/RuleConfigUtilUnitTest.java
   labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/soa/esb/services/
   labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/soa/esb/services/rules/
   labs/jbossesb/trunk/product/services/jbrules/src/test/resources/PricingRulesStatefulEntryPoint.drl
Modified:
   labs/jbossesb/trunk/product/samples/quickstarts/business_ruleservice_stateful/OrderDiscountOnMultipleOrders.drl
   labs/jbossesb/trunk/product/samples/quickstarts/business_ruleservice_stateful/jboss-esb.xml
   labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/routing/cbr/JBossRulesRouter.java
   labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleService.java
   labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleServiceCallHelper.java
   labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/soa/esb/actions/BusinessRulesProcessor.java
   labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/soa/esb/actions/ContentBasedWiretap.java
   labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/soa/esb/services/rules/RuleService.java
   labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/routing/cbr/JBossRulesRouterUnitTest.java
   labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleServiceUnitTest.java
   labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/BusinessRulesProcessorUnitTest.java
   labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/CBRConfigTreeBuilder.java
   labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/ContentBasedWiretapUnitTest.java
Log:
Work for https://jira.jboss.org/jira/browse/JBESB-2273 "Extend BusinessRulesProcessor action to support entry-point"


Modified: labs/jbossesb/trunk/product/samples/quickstarts/business_ruleservice_stateful/OrderDiscountOnMultipleOrders.drl
===================================================================
--- labs/jbossesb/trunk/product/samples/quickstarts/business_ruleservice_stateful/OrderDiscountOnMultipleOrders.drl	2009-07-03 08:39:30 UTC (rev 27479)
+++ labs/jbossesb/trunk/product/samples/quickstarts/business_ruleservice_stateful/OrderDiscountOnMultipleOrders.drl	2009-07-03 08:49:57 UTC (rev 27480)
@@ -16,7 +16,7 @@
 rule "Apply 10% discount to customer if totalPrice of all their orders is over 100"	
 	dialect "mvel"		
     when
-		$c : Customer()
+		$c : Customer() from entry-point "CustomerEntryPoint"
 		$i : Number(intValue >= 100) from accumulate ( OrderHeader( customer.userName == $c.userName, $totalAmount : totalAmount), 
 		                                                            sum( $totalAmount ) );
     then
@@ -26,7 +26,7 @@
 
 rule "apply customer discount to latest order"
 	when
-		$c : Customer()
+		$c : Customer() from entry-point "CustomerEntryPoint"
 		$o : OrderHeader(customer.userName == $c.userName)
 	then
 		$o.setOrderDiscount($c.getOrderDiscount());

Modified: labs/jbossesb/trunk/product/samples/quickstarts/business_ruleservice_stateful/jboss-esb.xml
===================================================================
--- labs/jbossesb/trunk/product/samples/quickstarts/business_ruleservice_stateful/jboss-esb.xml	2009-07-03 08:39:30 UTC (rev 27479)
+++ labs/jbossesb/trunk/product/samples/quickstarts/business_ruleservice_stateful/jboss-esb.xml	2009-07-03 08:49:57 UTC (rev 27480)
@@ -52,7 +52,7 @@
 					<property name="stateful" value="true" />
 					<property name="object-paths">
 						<object-path esb="body.TheOrderHeader" />
-						<object-path esb="body.TheCustomer" />
+						<object-path esb="body.TheCustomer" entry-point="CustomerEntryPoint" />
 					</property>
 				</action>
 

Modified: labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/routing/cbr/JBossRulesRouter.java
===================================================================
--- labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/routing/cbr/JBossRulesRouter.java	2009-07-03 08:39:30 UTC (rev 27479)
+++ labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/routing/cbr/JBossRulesRouter.java	2009-07-03 08:49:57 UTC (rev 27480)
@@ -27,6 +27,7 @@
 import java.util.Map;
 
 import org.apache.log4j.Logger;
+import org.drools.lang.DRLParser.entry_point_key_return;
 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;
@@ -89,8 +90,7 @@
 
 	/**
 	 * Route the message, where the routing rules are supplied as part of the
-	 * message itself. We don't support this yet, as I don't see the need right
-	 * now. However when the need arises, this is where it goes.
+	 * message itself. 
 	 * 
 	 * @param ruleSet -
 	 *            String reference to a file which contains a ruleSet.

Modified: labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleService.java
===================================================================
--- labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleService.java	2009-07-03 08:39:30 UTC (rev 27479)
+++ labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleService.java	2009-07-03 08:49:57 UTC (rev 27480)
@@ -23,17 +23,21 @@
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.Map.Entry;
 import java.util.concurrent.ConcurrentHashMap;
 
+import org.apache.log4j.Logger;
 import org.drools.RuleBase;
 import org.drools.StatefulSession;
 import org.drools.StatelessSession;
-import org.drools.WorkingMemory;
+import org.drools.WorkingMemoryEntryPoint;
 import org.drools.agent.RuleAgent;
+import org.drools.common.EventFactHandle;
+import org.drools.common.InternalFactHandle;
 import org.drools.compiler.DroolsParserException;
 import org.jboss.internal.soa.esb.assertion.AssertArgument;
 import org.jboss.internal.soa.esb.services.rules.util.RulesContext;
@@ -43,48 +47,59 @@
 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.RuleInfo;
 import org.jboss.soa.esb.services.rules.RuleService;
+import org.jboss.soa.esb.services.rules.StatefulRuleInfo;
 
 /**
  * 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 
+public class DroolsRuleService implements RuleService
 {
-	/**
+    private static Logger log = Logger.getLogger(DroolsRuleService.class);
+
+    /**
 	 * The lifecycle resource factory for RuleBases.
 	 */
 	private static final LifecycleResourceFactory<Map<String, RuleBase>> lifecycleRuleBaseFactory = new LifecycleRuleBaseFactory();
-	
+
+    /**
+	 * The lifecycle resource factory for RuleAgents.
+	 */
 	private static final LifecycleResourceFactory<Map<String, RuleAgent>> lifecycleRuleAgentFactory = new LifecycleRuleAgentFactory();
+
 	/**
+	 * The lifecycle resource factory rule sets.
+	 */
+	private static final LifecycleResourceFactory<Map<String, String>> lifecycleRuleSetFactory = new LifecycleRuleSetFactory();
+
+	/**
 	 * 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.
+	 * The lifecycle resource for ruleset.
 	 */
-	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);
 
 	/**
 	 * 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 -
@@ -100,26 +115,43 @@
 	 * @param objectList -
 	 *            a list with additional objects (typically pulled from the
 	 *            message) to be inserted into working memory
-	 * 
+	 *
 	 * @return Message with updated objects.
+	 * @deprecated Please use {@link #executeStatelessRules(RuleInfo, Message)} instead.
 	 */
-	public Message executeStatelessRules(
-			final String ruleSet, 
+	@Deprecated
+    public Message executeStatelessRules(
+			final String ruleSet,
 			final String dsl,
-			final boolean ruleReload, 
-			Message message, 
+			final boolean ruleReload,
+			Message message,
 			final Map<String,Object> globals,
-			final List<Object> objectList) throws RuleServiceException 
+			final List<Object> objectList) throws RuleServiceException
 	{
 		AssertArgument.isNotNullAndNotEmpty( ruleSet, "ruleSet" );
-		
+
 		RuleBase ruleBase = getRuleBaseForFileBasedRules(ruleSet, dsl, ruleReload);
 		return executeStatelessRules(ruleBase, message, globals, objectList);
 	}
 
 	/**
+	 * Execute rules using the Stateless rule engine API.
+	 *
+	 * @param ruleInfo The {@link RuleInfo} object contain processing instructions for the rule engine. Must not be null.
+	 * @param message The ESB Message object.
+	 *
+	 */
+	public Message executeStatelessRules(final RuleInfo ruleInfo, final Message message) throws RuleServiceException
+	{
+		AssertArgument.isNotNull(ruleInfo, "ruleInfo" );
+		final RuleBase ruleBase = getRuleBaseForFileBasedRules(ruleInfo.getRuleSource(), ruleInfo.getDslSource(), ruleInfo.getReload());
+		return executeStatelessRules(ruleBase, message, ruleInfo.getGlobals(), ruleInfo.getDefaultFacts());
+	}
+
+
+	/**
 	 * 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 -
@@ -129,69 +161,96 @@
 	 *            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 
-	 * 
+	 * @param objectList - a list with additional objects (typically pulled from the message) to be inserted into
+	 *            working memory
+	 *
 	 * @return Message with updated objects.
+	 * @deprecated Please use {@link #executeStatelessRulesFromDecisionTable(RuleInfo, Message)} instead.
 	 */
-	public Message executeStatelessRulesFromDecisionTable(
+	@Deprecated
+    public Message executeStatelessRulesFromDecisionTable(
 			final String decisionTable,
-			final boolean ruleReload, 
-			Message message, 
+			final boolean ruleReload,
+			Message message,
 			final Map<String,Object> globals,
-			final List<Object> objectList) throws RuleServiceException 
+			final List<Object> objectList) throws RuleServiceException
 	{
 		AssertArgument.isNotNullAndNotEmpty( decisionTable, "decisionTable" );
-		
+
 		RuleBase ruleBase = getRuleBaseForDecisionTable( decisionTable, ruleReload );
 		return executeStatelessRules( ruleBase, message, globals, objectList );
 	}
 
+	public Message executeStatelessRulesFromDecisionTable(final RuleInfo ruleInfo, final Message message) throws RuleServiceException
+	{
+		AssertArgument.isNotNull(ruleInfo, "ruleInfo" );
+		RuleBase ruleBase = getRuleBaseForDecisionTable(ruleInfo.getRuleSource(), ruleInfo.getReload());
+		return executeStatelessRules(ruleBase, message, ruleInfo.getGlobals(), ruleInfo.getDefaultFacts());
+
+	}
+
 	/**
 	 * 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 
-	 * 
+	 * @param objectList - a list with additional objects (typically pulled from the message) to be inserted into
+	 *            working memory
+	 *
 	 * @return Message with updated objects.
+	 * @deprecated Please use {@link #executeStatelessRulesFromRuleAgent(RuleInfo, Message)} instead.
 	 */
-	public Message executeStatelessRulesFromRuleAgent(
-			final String ruleAgentProperties, 
-			Message message, 
+	@Deprecated
+    public Message executeStatelessRulesFromRuleAgent(
+			final String ruleAgentProperties,
+			Message message,
 			final Map<String,Object> globals,
-			final List<Object> objectList) throws RuleServiceException 
+			final List<Object> objectList) throws RuleServiceException
 	{
 		AssertArgument.isNotNullAndNotEmpty( ruleAgentProperties, "ruleAgentProperties" );
-		
-		try 
+
+		try
 		{
     		final RuleBase ruleBase = getRuleBaseForRuleAgent( ruleAgentProperties ) ;
 			return executeStatelessRules(ruleBase, message, globals, objectList);
-		} 
-		catch ( final IOException e) 
+		}
+		catch ( final IOException e)
 		{
 			throw new RuleServiceException( "Could not read the ruleAgentProperties file [" + ruleAgentProperties + "]", e);
-		} 
-		catch ( final RuleServiceException e) 
+		}
+		catch ( final Exception e)
 		{
-			throw e;
-		} 
-		catch ( final Exception e) 
-		{
 			throw new RuleServiceException( "RuleAgent could not get the RuleBase. " + e.getMessage(), e);
 		}
 	}
 
+	public Message executeStatelessRulesFromRuleAgent(final RuleInfo ruleInfo, final Message message) throws RuleServiceException
+	{
+		AssertArgument.isNotNull(ruleInfo, "ruleInfo" );
+		try
+        {
+            final RuleBase ruleBase = getRuleBaseForRuleAgent(ruleInfo.getRuleSource());
+            return executeStatelessRules(ruleBase, message, ruleInfo.getGlobals(), ruleInfo.getDefaultFacts());
+        }
+        catch ( final IOException e)
+        {
+            throw new RuleServiceException( "Could not read the ruleAgentProperties file [" + ruleInfo.getRuleSource() + "]", e);
+        }
+        catch ( final Exception e)
+        {
+            throw new RuleServiceException( "RuleAgent could not get the RuleBase. " + e.getMessage(), e);
+        }
+
+	}
+
 	/**
 	 * 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 -
@@ -204,28 +263,54 @@
 	 *            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 
-	 * 
+	 * @param objectList - a list with additional objects (typically pulled from the message) to be inserted into
+	 *            working memory
+	 *
 	 * @return Message with updated objects.
+	 * @deprecated Please use {@link #executeStatefulRules(RuleInfo, Message)} instead.
 	 */
-	public Message executeStatefulRules(
-			final String ruleSet, 
+	@Deprecated
+    public Message executeStatefulRules(
+			final String ruleSet,
 			final String dsl,
-			final boolean ruleReload, 
+			final boolean ruleReload,
 			Message message,
 			final Map<String,Object> globals,
-			final List<Object> objectList) throws RuleServiceException 
+			final List<Object> objectList) throws RuleServiceException
 	{
 		AssertArgument.isNotNullAndNotEmpty( ruleSet, "ruleSet" );
-		
-		RuleBase ruleBase = getRuleBaseForFileBasedRules( ruleSet, dsl, ruleReload );
-		return executeStatefulRules( ruleBase, false, message, globals, objectList );
+
+		final RuleInfoBuilder builder = new RuleInfoBuilder(ruleSet);
+		builder.dslSource(dsl);
+		builder.reload(ruleReload);
+		builder.globals(globals);
+		builder.defaultFacts(objectList);
+		StatefulRuleInfoImpl ruleInfo = new StatefulRuleInfoImpl(builder.build(), false);
+
+		RuleBase ruleBase = getRuleBaseForFileBasedRules( ruleInfo.getRuleSource(), ruleInfo.getDslSource(), ruleInfo.getReload());
+		return executeStatefulRules(ruleBase, ruleInfo, message);
 	}
 
 	/**
+	 * Execute rules using a certain ruleSet and domain specific language using the Stateful rule engine API
+	 *
+	 * @param info {@link StatefulRuleInfo} containing the execution information for the Rule engine.
+	 * @param msg The ESB Message object.
+	 * @return {@link Message} The ESB Message Object.
+	 *
+	 * @throws RuleServiceException If a problem occurs while trying to create the Drools RuleBase or if an exception
+	 *                             occurs during execution
+	 */
+	public Message executeStatefulRules(final StatefulRuleInfo info, final Message msg) throws RuleServiceException
+    {
+		AssertArgument.isNotNull(info, "ruleInfo" );
+		final RuleBase ruleBase = getRuleBaseForFileBasedRules(info.getRuleSource(), info.getDslSource(), info.getReload());
+		return executeStatefulRules(ruleBase, info, msg);
+    }
+
+    /**
 	 * 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 -
@@ -235,71 +320,123 @@
 	 *            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 
-	 * 
+	 * @param objectList - a list with additional objects (typically pulled from the message) to be inserted into
+	 *            working memory
+	 *
 	 * @return Message with updated objects.
+	 * @deprecated Please use {@link #executeStatefulRulesFromDecisionTable(RuleInfo, Message)} instead.
 	 */
-	public Message executeStatefulRulesFromDecisionTable(
+	@Deprecated
+    public Message executeStatefulRulesFromDecisionTable(
 			final String decisionTable,
-			final boolean ruleReload, 
+			final boolean ruleReload,
 			Message message,
 			final Map<String,Object> globals,
-			final List<Object> objectList) throws RuleServiceException 
+			final List<Object> objectList) throws RuleServiceException
 	{
 		AssertArgument.isNotNullAndNotEmpty( decisionTable, "decisionTable" );
-		
-		final RuleBase ruleBase = getRuleBaseForDecisionTable(decisionTable, ruleReload);
-		
-		return executeStatefulRules(ruleBase, false, message, globals, objectList);
+
+		final RuleInfoBuilder builder = new RuleInfoBuilder(decisionTable);
+		builder.reload(ruleReload);
+		builder.globals(globals);
+		builder.defaultFacts(objectList);
+		StatefulRuleInfoImpl ruleInfo = new StatefulRuleInfoImpl(builder.build(), false);
+
+		final RuleBase ruleBase = getRuleBaseForDecisionTable(ruleInfo.getRuleSource(), ruleInfo.getReload());
+
+		return executeStatefulRules(ruleBase, ruleInfo, message);
 	}
 
 	/**
+	 * Execute rules from a decision table using the Stateful rule engine API
+	 *
+	 * @param info {@link StatefulRuleInfo} containing the execution information for the Rule engine.
+	 * @param msg The ESB Message object.
+	 * @return {@link Message} The ESB Message Object.
+	 *
+	 * @throws RuleServiceException If a problem occurs while trying to create the Drools RuleBase or if an exception
+	 * @deprecated Please use {@link #executeStatefulRulesFromRuleAgent(RuleInfo, Message)} instead.
+	 */
+	@Deprecated
+    public Message executeStatefulRulesFromDecisionTable(StatefulRuleInfo ruleInfo, Message msg) throws RuleServiceException
+    {
+		final RuleBase ruleBase = getRuleBaseForDecisionTable(ruleInfo.getRuleSource(), ruleInfo.getReload());
+		return executeStatefulRules(ruleBase, ruleInfo, msg);
+    }
+
+    /**
 	 * 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 
-	 * 
+	 * @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, 
+			final String ruleAgentProperties,
 			Message message,
 			final Map<String,Object> globals,
-			final List<Object> objectList) throws RuleServiceException 
+			final List<Object> objectList) throws RuleServiceException
 	{
 		AssertArgument.isNotNullAndNotEmpty( ruleAgentProperties, "ruleAgentProperties" );
-		
-		try 
+
+		try
 		{
-    		final RuleBase ruleBase = getRuleBaseForRuleAgent( ruleAgentProperties ) ;
-			
-			return executeStatefulRules(ruleBase, false, message, globals, objectList);
-		} 
-		catch (IOException e) 
+    		final RuleInfoBuilder builder = new RuleInfoBuilder(ruleAgentProperties);
+    		builder.globals(globals);
+    		builder.defaultFacts(objectList);
+    		StatefulRuleInfoImpl ruleInfo = new StatefulRuleInfoImpl(builder.build(), false);
+
+    		final RuleBase ruleBase = getRuleBaseForRuleAgent(ruleInfo.getRuleSource()) ;
+
+			return executeStatefulRules(ruleBase, ruleInfo, message);
+		}
+		catch (IOException e)
 		{
 			throw new RuleServiceException( "Could not read the ruleAgentProperties. " + e.getMessage(), e);
-		} 
-		catch (RuleServiceException e) 
+		}
+		catch (RuleServiceException e)
 		{
 			throw e;
-		} 
-		catch (Exception e) 
+		}
+		catch (Exception e)
 		{
 			throw new RuleServiceException( "RuleAgent could not get the RuleBase. " + e.getMessage(), e);
 		}
 	}
-	
-	/**
+
+	public Message executeStatefulRulesFromRuleAgent(StatefulRuleInfo ruleInfo, Message msg) throws RuleServiceException
+    {
+	    try
+        {
+            final RuleBase ruleBase = getRuleBaseForRuleAgent(ruleInfo.getRuleSource()) ;
+
+            return executeStatefulRules(ruleBase, ruleInfo, msg);
+        }
+        catch (IOException e)
+        {
+            throw new RuleServiceException( "Could not read the ruleAgentProperties. " + e.getMessage(), e);
+        }
+        catch (RuleServiceException e)
+        {
+            throw e;
+        }
+        catch (Exception e)
+        {
+            throw new RuleServiceException( "RuleAgent could not get the RuleBase. " + e.getMessage(), e);
+        }
+    }
+
+    /**
 	 * 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.
@@ -309,42 +446,64 @@
 	 *            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 
-	 * 
+	 * @param objectList - a list with additional objects (typically pulled from the message) to be inserted into
+	 *            working memory
+	 *
 	 * @return Message with updated objects.
+	 * @deprecated Please use {@link #continueStatefulRulesExecution(StatefulRuleInfo, Message)} instead.
 	 */
-	public Message continueStatefulRulesExecution(
+	@Deprecated
+    public Message continueStatefulRulesExecution(
 			final String rules,
-			final boolean dispose, 
-			Message message, 
+			final boolean dispose,
+			Message message,
 			final Map<String,Object> globals,
-			final List<Object> objectList) throws RuleServiceException 
+			final List<Object> objectList) throws RuleServiceException
 	{
 		AssertArgument.isNotNullAndNotEmpty( rules, "rules" );
-		
-		try 
+
+		try
 		{
 			final Map<String, RuleBase> ruleBases = lifecycleRuleBases.getLifecycleResource();
+    		final RuleInfoBuilder builder = new RuleInfoBuilder(rules);
+    		builder.globals(globals);
+    		builder.defaultFacts(objectList);
+    		StatefulRuleInfo ruleInfo = new StatefulRuleInfoImpl(builder.build(), dispose);
+
 			final RuleBase ruleBase = ruleBases.get( rules );
-			
-			return executeStatefulRules( ruleBase, dispose, message, globals, objectList );
-		} 
-		catch (Exception e) 
+
+			return executeStatefulRules(ruleBase, ruleInfo, message);
+		}
+		catch (Exception e)
 		{
 			throw new RuleServiceException( "Could not continue rule execution. " + e.getMessage(), e);
 		}
 	}
-	
-	public void setConfigTree( final ConfigTree configTree ) 
+
+    public Message continueStatefulRulesExecution(StatefulRuleInfo info, Message msg) throws RuleServiceException
+    {
+		try
+		{
+			final Map<String, RuleBase> ruleBases = lifecycleRuleBases.getLifecycleResource();
+			final RuleBase ruleBase = ruleBases.get(info.getRuleSource());
+
+			return executeStatefulRules(ruleBase, info, msg);
+		}
+		catch (Exception e)
+		{
+			throw new RuleServiceException( "Could not continue rule execution. " + e.getMessage(), e);
+		}
+    }
+
+	public void setConfigTree( final ConfigTree configTree )
 	{
 	}
-	
+
 	//	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 -
@@ -353,15 +512,15 @@
 	 * @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 ruleSet,
 			final String dsl,
-			final boolean ruleReload) throws RuleServiceException 
+			final boolean ruleReload) throws RuleServiceException
 	{
-		try 
+		try
 		{
 			final DroolsRuleBaseHelper rbHelper = DroolsRuleBaseHelper.getInstance();
 
@@ -394,45 +553,44 @@
                 }
 
                 return ruleBase;
-            }            
-		} 
-		catch (final LifecycleResourceException e) 
+            }
+		}
+		catch (final LifecycleResourceException e)
 		{
 			throw new RuleServiceException("Could not load lifecycle data. " + e.getMessage(), e);
-		} 
-		catch (final IOException e) 
+		}
+		catch (final IOException e)
 		{
 			throw new RuleServiceException("Could not read the rules. " + e.getMessage(), e);
-		} 
-		catch (final DroolsParserException e) 
+		}
+		catch (final DroolsParserException e)
 		{
 			throw new RuleServiceException("Could not parse the rules. " + e.getMessage(), 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 
+
+		try
 		{
             Map<String, RuleBase> ruleBases = getCachedRuleBases();
 
             synchronized (ruleBases) {
                 RuleBase ruleBase = ruleBases.get( decisionTable );
-                if ( ruleReload || ruleBase == null ) 
+                if ( ruleReload || ruleBase == null )
                 {
                     ruleBase = DroolsRuleBaseHelper.getInstance().createRuleBaseFromDecisionTable(decisionTable);
                     ruleBases.put( decisionTable, ruleBase );
@@ -440,23 +598,23 @@
                 return ruleBase;
             }
         }
-		catch (final IOException e) 
+		catch (final IOException e)
 		{
 			throw new RuleServiceException("Could not read the rules from [" + decisionTable + "]", e);
-		} 
-		catch (final DroolsParserException e) 
+		}
+		catch (final DroolsParserException e)
 		{
 			throw new RuleServiceException("Could not parse the rules in [" + decisionTable + "]", e);
-		} 
+		}
 		catch (final LifecycleResourceException e)
 		{
 			throw new RuleServiceException("Caught a LifecycleResourceException :", e);
 		}
 	}
-	
+
 	/**
 	 * Execute rules using using the Stateless API
-	 * 
+	 *
 	 * @param rulebase -
 	 *          the rulebase to use
 	 * @param message -
@@ -466,17 +624,17 @@
 	 * 			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 RuleBase ruleBase,
 			final Message message,
 			final Map<String,Object> globals,
-			final List<Object> objectList) 
+			final List<Object> objectList)
 	{
-		
+
 		final StatelessSession statelessSession = ruleBase.newStatelessSession();
 		RulesContext.clearContext() ;
 		try
@@ -491,55 +649,94 @@
 		}
 		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.	
+	 * 			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
-	 * 
+	 * @param entryPointMap -
+	 * 			a map with additional objects to be inserted into working memory or
+	 *          into the named WorkingMemoryEntryPoint. Any objects included in the
+	 *          {@link #DEFAULT_ENTRY_POINT} name will be inserted into the normal
+	 *          working memory. The rest will lookup the entry point working memory
+	 *          and insert the objects into the those working memories.
 	 * @return Message -
 	 * 			a possibly updated Message object. The message object is available
 	 * 			to Rules and my be updated by them.
+	 * @throws RuleServiceException
 	 */
 	Message executeStatefulRules(
-			final RuleBase ruleBase, 
-			final boolean dispose,
-			final Message message, 
-			final Map<String,Object> globals,
-			final List<Object> objectList) 
+			final RuleBase ruleBase,
+			final StatefulRuleInfo ruleInfo,
+			final Message message) throws RuleServiceException
 	{
-        synchronized (ruleBase) {
+        synchronized (ruleBase)
+        {
             RulesContext.clearContext() ;
+
             final StatefulSession statefulSession = getStatefulSession( ruleBase );
             try
             {
-                addGlobalsVariables( statefulSession, globals );
-                final List<Object> facts = getFacts( message, objectList );
-                insertObjectsIntoWorkingMemory( facts, statefulSession );
+                addGlobalsVariables(statefulSession, ruleInfo.getGlobals());
+
+                // Always insert the ESB Message object.
+                InternalFactHandle handle = (InternalFactHandle) statefulSession.insert(message);
+                if (log.isDebugEnabled())
+                {
+                    if (handle.isEvent())
+                    {
+                        EventFactHandle ef = (EventFactHandle) handle;
+                        log.debug("Event :" +  ef.getObject().getClass().getName() + ", startTimeStamp: " + ef.getStartTimestamp());
+                    }
+                }
+
+                // Always insert the Default facts
+                final List<Object> defaultFacts = ruleInfo.getDefaultFacts();
+                for (Object object : defaultFacts)
+                {
+                    statefulSession.insert(object);
+                }
+
+                // Insert any object that that did not specify an entry-point into the main working memory.
+                if (ruleInfo.getFacts() != null)
+                {
+                    for (Entry<String, List<Object>> entry : ruleInfo.getFacts().entrySet())
+                    {
+                        String entryPointName = entry.getKey();
+                        // Insert object that have explicitely specifed an entry-point.
+                        WorkingMemoryEntryPoint wmep = statefulSession.getWorkingMemoryEntryPoint(entryPointName);
+                        if (wmep == null)
+                        {
+                            throw new RuleServiceException("The entry-point '" + entryPointName + "' was not found in the current stateful session. Please double check your rules source");
+                        }
+                        for (Object object : entry.getValue())
+                        {
+                            wmep.insert(object);
+                        }
+                    }
+                }
+                // Fire rules.
                 statefulSession.fireAllRules();
             }
             finally
             {
                 RulesContext.clearContext() ;
-                if ( dispose )
+                if ( ruleInfo.dispose() )
                 {
                     statefulSession.dispose();
                 }
             }
         }
-		
         return message;
 	}
-	
+
 	private List<Object> getFacts(final Message message, final List<Object> objectList )
 	{
 		final List<Object> facts = new ArrayList<Object>();
@@ -548,7 +745,7 @@
 			facts.addAll( objectList );
 		return facts;
 	}
-	
+
 	/*
 	 * Checks whether the ruleBase has an existing session, and returns
 	 * that session, otherwise a new session is created.
@@ -561,7 +758,7 @@
             return existingSession ? statefulSessions[0] : ruleBase.newStatefulSession();
         }
     }
-	
+
 	/*
 	 * Will set the passed-in elements in the globals Map as global
 	 * variables.
@@ -576,7 +773,7 @@
             }
         }
 	}
-	
+
 	/*
 	 * Will set the passed-in elements in the globals Map as global
 	 * variables.
@@ -592,18 +789,7 @@
 			}
 		}
 	}
-	
-	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();
@@ -613,51 +799,48 @@
 			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>> {
+	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 
+		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.
-		 * 
+		 * Destroy a resource object which is associated with the specified lifecycle identity.
+		 *
 		 * @param resource
 		 *            The lifecycle resource.
 		 * @param lifecycleIdentity
@@ -666,35 +849,53 @@
 		 * @throws LifecycleResourceException
 		 *             for errors during destroy.
 		 */
-		public void destroyLifecycleResource(
-				final Map<String, RuleBase> resource,
-				final String lifecycleIdentity)
-				throws LifecycleResourceException 
+		public void destroyLifecycleResource( final Map<String, RuleBase> resource, final String lifecycleIdentity) throws LifecycleResourceException
 		{
-			//	NoOp
+		    if (resource != null)
+		    {
+		        final Collection<RuleBase> values = resource.values();
+		        for (RuleBase ruleBase : values)
+                {
+                    log.info("destroying stateful session for " + lifecycleIdentity);
+    		        disposeStatefulSessions(ruleBase.getStatefulSessions());
+                }
+		        resource.clear();
+		    }
 		}
 	}
-	
-	public static class LifecycleRuleAgentFactory implements LifecycleResourceFactory<Map<String, RuleAgent>> {
+
+	private static void disposeStatefulSessions(final StatefulSession[] sessions)
+	{
+	    if (sessions == null)
+	        return;
+
+        for (StatefulSession statefulSession : sessions)
+        {
+            statefulSession.dispose();
+        }
+	}
+
+	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 
+        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
@@ -703,33 +904,39 @@
          * @throws LifecycleResourceException
          *             for errors during destroy.
          */
-        public void destroyLifecycleResource( final Map<String, RuleAgent> resource, final String lifecycleIdentity) throws LifecycleResourceException 
+        public void destroyLifecycleResource( final Map<String, RuleAgent> resource, final String lifecycleIdentity) throws LifecycleResourceException
         {
-        	//	NoOp
+            if (resource != null)
+            {
+                final Collection<RuleAgent> values = resource.values();
+                for (RuleAgent ruleAgent : values)
+                {
+                    log.info("destroying stateful session for " + lifecycleIdentity);
+    		        disposeStatefulSessions(ruleAgent.getRuleBase().getStatefulSessions());
+                }
+                resource.clear();
+            }
         }
     }
 
 	/**
 	 * The lifecycle resource factory for rule sets.
-	 * 
+	 *
 	 * @author kevin
 	 */
-	public static class LifecycleRuleSetFactory implements
-			LifecycleResourceFactory<Map<String, String>> 
+	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 
+		public Map<String, String> createLifecycleResource( final String lifecycleIdentity) throws LifecycleResourceException
 		{
 			return new ConcurrentHashMap<String, String>();
 		}
@@ -737,7 +944,7 @@
 		/**
 		 * Destroy a resource object which is associated with the specified
 		 * lifecycle identity.
-		 * 
+		 *
 		 * @param resource
 		 *            The lifecycle resource.
 		 * @param lifecycleIdentity
@@ -746,13 +953,12 @@
 		 * @throws LifecycleResourceException
 		 *             for errors during destroy.
 		 */
-		public void destroyLifecycleResource(
-				final Map<String, String> resource,
-				final String lifecycleIdentity)
-				throws LifecycleResourceException 
+		public void destroyLifecycleResource( final Map<String, String> resource, final String lifecycleIdentity) throws LifecycleResourceException
 		{
-			// NoOp
+		    if (resource != null)
+		    {
+		        resource.clear();
+		    }
 		}
 	}
-	
 }

Added: labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleInfoBuilder.java
===================================================================
--- labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleInfoBuilder.java	                        (rev 0)
+++ labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleInfoBuilder.java	2009-07-03 08:49:57 UTC (rev 27480)
@@ -0,0 +1,173 @@
+/*
+ * JBoss, Home of Professional Open Source Copyright 2009, 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.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.jboss.internal.soa.esb.assertion.AssertArgument;
+import org.jboss.internal.soa.esb.services.rules.RuleInfoImpl;
+import org.jboss.soa.esb.services.rules.RuleInfo;
+
+/**
+ * 
+ * @author <a href="mailto:dbevenius at jboss.com">Daniel Bevenius</a>
+ * @since 4.6
+ *
+ */
+public class RuleInfoBuilder
+{
+    String ruleSource;
+    String ruleType;
+    boolean reload;
+    String dslSource;
+        
+    Map<String, Object> globals;
+    Map<String, List<Object>> factsMap;
+    List<Object> defaultFacts;
+    
+    public RuleInfoBuilder(final String ruleSource)
+    {
+        AssertArgument.isNotNullAndNotEmpty(ruleSource, "ruleSource");
+        this.ruleSource = ruleSource;
+    }
+
+    public RuleInfoBuilder ruleType(final String type)
+    {
+        ruleType = type;
+        return this;
+    }
+
+    public RuleInfoBuilder dslSource(final String dsl)
+    {
+        if (dslSource != null)
+        {
+            throw new IllegalArgumentException("dslSource has already been set to '" + dslSource + "'");
+        }
+        dslSource = dsl;
+        return this;
+    }
+
+    public RuleInfoBuilder reload(final boolean reload)
+    {
+        this.reload = reload;
+        return this;
+    }
+
+    public RuleInfoBuilder global(final String name, final Object object)
+    {
+        if (this.globals == null)
+        {
+            this.globals = new HashMap<String, Object>();
+        }
+        this.globals.put(name, object);
+        return this;
+    }
+
+    public RuleInfoBuilder fact(final String name, final Object object)
+    {
+        if (this.factsMap == null)
+        {
+            this.factsMap = new HashMap<String, List<Object>>();
+        }
+
+        List<Object> list = factsMap.get(name);
+        if (list == null)
+        {
+            list = new ArrayList<Object>();
+            factsMap.put(name, list);
+        }
+
+        list.add(object);
+        return this;
+    }
+    
+    public RuleInfo build()
+    {
+        if (factsMap == null)
+            factsMap = Collections.emptyMap();
+        if (defaultFacts == null)
+            defaultFacts = Collections.emptyList();
+        
+        return new RuleInfoImpl(this);
+        
+    }
+
+    public RuleInfoBuilder facts(Map<String, List<Object>> facts)
+    {
+        if (facts != null)
+        {
+            if (factsMap == null)
+            {
+                factsMap = facts;
+            }
+            else
+            {
+                factsMap.putAll(facts);
+            }
+        }
+        return this;
+    }
+    
+    public RuleInfoBuilder defaultFact(final Object object)
+    {
+        if (object != null)
+        {
+            if (defaultFacts == null)
+            {
+                defaultFacts = new ArrayList<Object>();
+            }
+            defaultFacts.add(object);
+        }
+        return this;
+    }
+    
+    public RuleInfoBuilder defaultFacts(List<Object> facts)
+    {
+        if (facts != null)
+        {
+            for (Object object : facts)
+            {
+                defaultFact(object);
+            }
+        }
+        return this;
+    }
+
+    public void globals(Map<String, Object> globals)
+    {
+        if (globals == null)
+            return;
+        
+        if (this.globals == null)
+        {
+            this.globals = globals;
+        }
+        else
+        {
+            this.globals.putAll(globals);
+        }
+    }
+
+}
\ No newline at end of file

Added: labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleInfoImpl.java
===================================================================
--- labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleInfoImpl.java	                        (rev 0)
+++ labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleInfoImpl.java	2009-07-03 08:49:57 UTC (rev 27480)
@@ -0,0 +1,147 @@
+/*
+ * JBoss, Home of Professional Open Source Copyright 2009, 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.util.List;
+import java.util.Map;
+
+import org.jboss.soa.esb.services.rules.RuleInfo;
+import org.jboss.soa.esb.services.rules.RuleService;
+
+
+/**
+ * RuleInfoImpl contains rule execution configuration parameters that 
+ * are passed to the {@link RuleService}.
+ * 
+ * @author <a href="mailto:dbevenius at jboss.com">Daniel Bevenius</a>
+ * @since 4.6
+ */
+public class RuleInfoImpl implements RuleInfo
+{
+    /**
+	 * String reference to a file which contains rules.
+     */
+    private final String ruleSource;
+    
+    /**
+     * The type of rules source.
+     */
+    private final String ruleType;
+    
+    /**
+	 * A String that points to a file containing a Domain Specific Language (DSL).
+     */
+    private final String dslSource;
+    
+    /**
+	 * If set to true, a ruleSet update should result in reloading the ruleSet.
+     */
+    private final boolean reload;
+    
+    /**
+	 * Map of globals variables that should be set in the working memory
+     */
+    private final Map<String, Object> globals;
+    
+    /**
+     * Facts indexed by thier entry point name.
+     */
+    private final Map<String, List<Object>> factsMap;
+    
+    /**
+     * Facts that are "un-named" and targeted at the default rule working memory.
+     */
+    private final List<Object> defaultFacts;
+    
+    /**
+     * Sole constructor intended to be called from the {@link Builder}.
+     * 
+     * @param builder This classes {@link Builder}.
+     */
+    RuleInfoImpl(final RuleInfoBuilder builder)
+    {
+        ruleSource = builder.ruleSource;
+        ruleType = builder.ruleType;
+        dslSource = builder.dslSource;
+        globals = builder.globals;
+        factsMap = builder.factsMap;
+        reload = builder.reload;
+        defaultFacts = builder.defaultFacts;
+    }
+
+    /* (non-Javadoc)
+     * @see org.jboss.soa.esb.services.rules.RuleInfo#getRuleSource()
+     */
+    public String getRuleSource()
+    {
+        return ruleSource;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.jboss.soa.esb.services.rules.RuleInfo#getRuleType()
+     */
+    public String getRuleType()
+    {
+        return ruleType;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.jboss.soa.esb.services.rules.RuleInfo#getDslSource()
+     */
+    public String getDslSource()
+    {
+        return dslSource;
+    }
+
+    /* (non-Javadoc)
+     * @see org.jboss.soa.esb.services.rules.RuleInfo#getReload()
+     */
+    public boolean getReload()
+    {
+        return reload;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.jboss.soa.esb.services.rules.RuleInfo#getGlobals()
+     */
+    public Map<String, Object> getGlobals()
+    {
+        return globals;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.jboss.soa.esb.services.rules.RuleInfo#getFacts()
+     */
+    public Map<String, List<Object>> getFacts()
+    {
+        return factsMap;
+    }
+    
+    public List<Object> getDefaultFacts()
+    {
+        return defaultFacts;
+    }
+
+    public String toString()
+    {
+        return String.format("%s [ruleSource=%s, dslSource=%s, reload=%b, globals=%s, facts=%s, defaultFacts=%s", getClass().getSimpleName(), ruleSource, dslSource, reload, globals, factsMap, defaultFacts);
+    }
+}

Modified: labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleServiceCallHelper.java
===================================================================
--- labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleServiceCallHelper.java	2009-07-03 08:39:30 UTC (rev 27479)
+++ labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/RuleServiceCallHelper.java	2009-07-03 08:49:57 UTC (rev 27480)
@@ -52,6 +52,18 @@
 	{
 		throw new AssertionError();
 	}
+    
+	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 
+	{
+	   return executeRulesService(ruleSet, ruleLanguage, ruleReload, message, objectList, globals, null, configTree);
+	}
 	
 	/**
 	 * This helper method delegates to the configured RuleService implementation.
@@ -91,6 +103,7 @@
 			Message message, 
 			final List<Object> objectList,
 			final Map<String, Object> globals,
+			final Map<String, List<Object>> entryPointMap,
 			final ConfigTree configTree ) throws RuleServiceException 
 	{
 		final String ruleServiceImpl = configTree.getAttribute( IMPL_CLASS.getTagName(), "org.jboss.internal.soa.esb.services.rules.DroolsRuleService" );

Added: labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/StatefulRuleInfoImpl.java
===================================================================
--- labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/StatefulRuleInfoImpl.java	                        (rev 0)
+++ labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/StatefulRuleInfoImpl.java	2009-07-03 08:49:57 UTC (rev 27480)
@@ -0,0 +1,88 @@
+/*
+ * JBoss, Home of Professional Open Source Copyright 2009, 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.util.List;
+import java.util.Map;
+
+import org.jboss.soa.esb.services.rules.RuleInfo;
+import org.jboss.soa.esb.services.rules.RuleService;
+import org.jboss.soa.esb.services.rules.StatefulRuleInfo;
+
+/**
+ * StatefulRuleInfoImpl contains stateful rule execution configuration parameters that 
+ * are passed to the {@link RuleService}.
+ * 
+ * @author <a href="mailto:dbevenius at jboss.com">Daniel Bevenius</a>
+ * @since 4.6
+ */
+public class StatefulRuleInfoImpl implements StatefulRuleInfo
+{
+    private final RuleInfo ruleInfo;
+    private boolean dispose;
+    
+    public StatefulRuleInfoImpl(final RuleInfo ruleInfo, final boolean dispose)
+    {
+        this.ruleInfo = ruleInfo;
+        this.dispose = dispose;
+    }
+    
+    public boolean dispose()
+    {
+        return dispose;
+    }
+
+    public String getDslSource()
+    {
+        return ruleInfo.getDslSource();
+    }
+
+    public Map<String, List<Object>> getFacts()
+    {
+        return ruleInfo.getFacts();
+    }
+
+    public Map<String, Object> getGlobals()
+    {
+        return ruleInfo.getGlobals();
+    }
+
+    public boolean getReload()
+    {
+        return ruleInfo.getReload();
+    }
+
+    public String getRuleSource()
+    {
+        return ruleInfo.getRuleSource();
+    }
+
+    public String getRuleType()
+    {
+        return ruleInfo.getRuleType();
+    }
+    
+    public List<Object> getDefaultFacts()
+    {
+        return ruleInfo.getDefaultFacts();
+    }
+    
+}


Property changes on: labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/StatefulRuleInfoImpl.java
___________________________________________________________________
Name: svn:mergeinfo
   + 

Added: labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/util/RuleConfigUtil.java
===================================================================
--- labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/util/RuleConfigUtil.java	                        (rev 0)
+++ labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/util/RuleConfigUtil.java	2009-07-03 08:49:57 UTC (rev 27480)
@@ -0,0 +1,84 @@
+/*
+ * JBoss, Home of Professional Open Source Copyright 2009, 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.util;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.jboss.internal.soa.esb.assertion.AssertArgument;
+import org.jboss.internal.soa.esb.services.rules.RuleServiceException;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.message.mapping.ObjectMapper;
+import org.jboss.soa.esb.message.mapping.ObjectMappingException;
+
+/**
+ * Utit methods for handling Rules related configuration operations.
+ * 
+ * @author <a href="mailto:dbevenius at jboss.com">Daniel Bevenius</a>
+ *
+ */
+public class RuleConfigUtil
+{
+    private RuleConfigUtil()
+    {
+    }
+    
+    /**
+     * Extracts the Object instances specified in the object names of the entryPointMap argument from the ESB Message Object.
+     * 
+     * @param entryPointMap Map of that contains object names as it's values. These are the objects that should be extracted from the ESB Message.
+     * @param message The ESB Message object.
+     * @return Map<String, List<Object> The same contents as the passed in Map but instead of a List of Strings the values are a List of Objects which
+     *                                 have been extracted from the ESB Message object.
+     * @throws RuleServiceException
+     */
+    public static Map<String, List<Object>> extractObjectsFromMessage(final Map<String, List<String>> entryPointMap, final Message message) throws RuleServiceException
+    {
+        AssertArgument.isNotNull(entryPointMap, "entryPointMap");
+        AssertArgument.isNotNull(message, "message");
+        try
+        {
+            final Map<String, List<Object>> newEntryPointMap = new HashMap<String, List<Object>>();
+            
+            ObjectMapper objectMapper = new ObjectMapper();
+            for (Entry<String, List<String>> entry : entryPointMap.entrySet())
+            {
+                final String entryPointName = entry.getKey();
+                final List<Object> extractedObjects = new ArrayList<Object>();
+                for (String objectName : entry.getValue())
+                {
+                    Object objectFromMessage = objectMapper.getObjectFromMessage(message, objectName);
+                    extractedObjects.add(objectFromMessage);
+                }
+                newEntryPointMap.put(entryPointName, extractedObjects);
+            }
+            return newEntryPointMap;
+        } 
+        catch (final ObjectMappingException e)
+        {
+            throw new RuleServiceException("Exception while trying to extract the objects '" + entryPointMap + "' from the message", e);
+        }
+    }
+    
+}

Modified: labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/soa/esb/actions/BusinessRulesProcessor.java
===================================================================
--- labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/soa/esb/actions/BusinessRulesProcessor.java	2009-07-03 08:39:30 UTC (rev 27479)
+++ labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/soa/esb/actions/BusinessRulesProcessor.java	2009-07-03 08:49:57 UTC (rev 27480)
@@ -19,26 +19,35 @@
  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  */
-
-/**
- * Routes the Message argument to a fixed list of services ([category,name]) 
- * @author kstam at jboss.com
- * @since Version 4.2
- */
 package org.jboss.soa.esb.actions;
 
-import java.util.HashMap;
+import static org.jboss.soa.esb.listeners.ListenerTagNames.RULE_RELOAD_TAG;
+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.DISPOSE;
+import static org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.IMPL_CLASS;
+import static org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.RULE_AGENT_PROPERTIES;
+import static org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.STATEFUL;
+
 import java.util.List;
-import java.util.Map;
 
-import org.jboss.internal.soa.esb.services.rules.RuleServiceCallHelper;
+import org.apache.log4j.Logger;
+import org.jboss.internal.soa.esb.services.rules.DroolsRuleService;
+import org.jboss.internal.soa.esb.services.rules.RuleInfoBuilder;
 import org.jboss.internal.soa.esb.services.rules.RuleServiceException;
+import org.jboss.internal.soa.esb.services.rules.RuleServiceFactory;
+import org.jboss.internal.soa.esb.services.rules.StatefulRuleInfoImpl;
+import org.jboss.internal.soa.esb.services.rules.util.RuleConfigUtil;
 import org.jboss.soa.esb.ConfigurationException;
 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.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.RuleInfo;
+import org.jboss.soa.esb.services.rules.RuleService;
+import org.jboss.soa.esb.services.rules.StatefulRuleInfo;
 
 /**
  * BusinessRulesProcessor extends {@link ContentBasedRouter} but does not perform any routing, it only 
@@ -68,19 +77,90 @@
  * </lu>
  * </br>
  * 
- * 
  * @author John Doe
  * @author <a href="mailto:dbevenius at redhat.com">Daniel Bevenius</a>
  *
  */
 public class BusinessRulesProcessor extends ContentBasedRouter
 {
+    /**
+     * Logger.
+     */
+    private Logger log = Logger.getLogger(BusinessRulesProcessor.class);
+    
+    /**
+     * The {@link RuleService} implementation to use.
+     */
+    private RuleService ruleService;
+    
+    /**
+     * True if a ruleSet is being used. 
+     */
+    private boolean useRuleSet;
+
+    /** 
+     * The decision table to be use, if configured.
+     */
+    private String decisionTable;
+    private boolean useDecisionTable;
+
+    /** 
+     * The rule agent to be use, if configured.
+     */
+    private String ruleAgent;
+    private boolean useRuleAgent;
+    
+    /**
+     * ConfigTree representing the xml configuration.
+     */
 	private ConfigTree configTree;
-	
-	public BusinessRulesProcessor(ConfigTree config) throws ConfigurationException, RegistryException, MessageRouterException
+
+	/**
+	 * Should this be a stateful rules execution.
+	 */
+    private Boolean stateful;
+
+	public BusinessRulesProcessor(final ConfigTree config) throws ConfigurationException, RegistryException, MessageRouterException
 	{
         super(config);
         this.configTree = config;
+        
+        // Create the RuleService implementation.
+		final String ruleServiceImpl = configTree.getAttribute(IMPL_CLASS.getTagName(), DroolsRuleService.class.getName());
+		try
+        {
+            ruleService = RuleServiceFactory.getRuleService( ruleServiceImpl );
+    		ruleService.setConfigTree( configTree );
+        } 
+		catch (RuleServiceException e)
+        {
+		    throw new ConfigurationException("Could not create RuleService", e);
+        }
+		
+		useRuleSet = _ruleSet != null;
+		if (useRuleSet == false)
+		{
+    		// Extract the decicion table from the configuration(if configured).
+    		decisionTable = configTree.getAttribute( DECISION_TABLE.getTagName() );
+    		useDecisionTable = decisionTable != null;
+    		
+    		if (useDecisionTable == false)
+    		{
+        		// Extract the ruleAgent from the configuration(if configured).
+                ruleAgent = configTree.getAttribute( RULE_AGENT_PROPERTIES.getTagName() );
+                useRuleAgent = true;
+        
+                if(log.isDebugEnabled()) 
+                {
+                    if (ruleAgent != null && _ruleReload) 
+                    {
+                        log.debug("'" + RULE_RELOAD_TAG + "' is specified on the same configuration as a Rule Agent configuration is specified.  Ignoring the '" + RULE_RELOAD_TAG + "' configuration.");
+                    }
+                }
+            }
+		}
+        
+		stateful = Boolean.valueOf( configTree.getAttribute( STATEFUL.getTagName()) );
 	}
 	/** 
      * Inspect the content of the message using a rule set 
@@ -93,8 +173,8 @@
 	{
         try 
         {
-            List<Object> objectList = _mapper.createObjectList(message, _messagePathList);
-            message = executeRulesService( message, objectList );
+            final List<Object> objectList = _mapper.createObjectList(message, _messagePathList);
+            return executeRulesService( message, objectList );
         } 
         catch (final ObjectMappingException e) 
         {
@@ -104,7 +184,6 @@
         {
             throw new ActionProcessingException( e.getMessage(), e);
         }
-		return message;
 	}
 	
 	/**
@@ -114,11 +193,132 @@
 	 * @throws RuleServiceException 
 	 * @throws MessageRouterException
 	 */
-	Message executeRulesService( final Message message, final List<Object> objectList) throws RuleServiceException 
+	Message executeRulesService(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 )  ;
+	    final String ruleSource = determineRuleSource();
+		RuleInfoBuilder builder = new RuleInfoBuilder(ruleSource);
+		builder.dslSource(_ruleLanguage);
+		builder.global("message", message);
+		builder.reload(_ruleReload);
+		builder.facts(RuleConfigUtil.extractObjectsFromMessage(entryPointMap, message));
+		builder.defaultFacts(objectList);
+		
+		final RuleInfo ruleInfo = builder.build();
+		
+		if (stateful)
+		{
+		    return executeStateful(ruleInfo, message);
+		}
+		else
+		{
+		    return executeStateless(ruleInfo, message);
+		}
 	}
-    
+	
+	private Message executeStateless(final RuleInfo ruleInfo, final Message message) throws RuleServiceException
+	{
+	    if (useRuleSet)
+	    {
+            return ruleService.executeStatelessRules(ruleInfo, message);
+	    }
+        else if (useDecisionTable)
+        {
+            return ruleService.executeStatelessRulesFromDecisionTable(ruleInfo, message);
+        }
+        else if (useRuleAgent)
+        {
+            return ruleService.executeStatelessRulesFromRuleAgent(ruleInfo, message);
+        }
+        else
+        {
+    		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 Message executeStateful(final RuleInfo ruleInfo, final Message message) throws RuleServiceException
+	{
+	    final boolean dispose = getDisposeProperty(message);
+        StatefulRuleInfo statefulRuleInfo = new StatefulRuleInfoImpl(ruleInfo, dispose);
+            
+        final Boolean continueStateful = (Boolean) message.getProperties().getProperty( CONTINUE.getTagName(), Boolean.FALSE );
+        if (continueStateful)
+        {
+            checkDisposePropertyIsSpecified(message);
+            return ruleService.continueStatefulRulesExecution(statefulRuleInfo, message);
+        }
+        else
+        {
+            if (useRuleSet)
+            {
+                return ruleService.executeStatefulRules(statefulRuleInfo, message);
+            }
+            else if (useDecisionTable)
+            {
+                return ruleService.executeStatefulRulesFromDecisionTable(statefulRuleInfo, message);
+            }
+            else if (useRuleAgent)
+            {
+                return ruleService.executeStatefulRulesFromRuleAgent(statefulRuleInfo, message);
+            }
+            else
+            {
+        		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 Message 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 String determineRuleSource()
+	{
+	    if (useRuleSet)
+	    {
+	        return _ruleSet;
+	    }
+	    else if (useDecisionTable)
+	    {
+	        return decisionTable;
+	    }
+	    else 
+	    {
+	        return ruleAgent;
+	    }
+	}
+	
+	private static boolean getDisposeProperty( final Message message ) throws RuleServiceException
+    {
+        Object dispose = message.getProperties().getProperty(DISPOSE.getTagName());
+        return (dispose != null);
+    }
+	
+	private static void checkDisposePropertyIsSpecified( 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.");
+        }
+    }
+	
+	boolean isUseRuleSet()
+	{
+	    return useRuleSet;
+	}
+	
+	boolean isUseDecisionTable()
+	{
+	    return useDecisionTable;
+	}
+	
+	boolean isUseRuleAgent()
+	{
+	    return useRuleAgent;
+	}
+	
 }

Modified: labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/soa/esb/actions/ContentBasedWiretap.java
===================================================================
--- labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/soa/esb/actions/ContentBasedWiretap.java	2009-07-03 08:39:30 UTC (rev 27479)
+++ labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/soa/esb/actions/ContentBasedWiretap.java	2009-07-03 08:49:57 UTC (rev 27480)
@@ -27,6 +27,7 @@
 import java.util.Map;
 
 import org.apache.log4j.Logger;
+import org.jboss.internal.soa.esb.services.rules.RuleInfoBuilder;
 import org.jboss.soa.esb.ConfigurationException;
 import org.jboss.soa.esb.Service;
 import org.jboss.soa.esb.helpers.ConfigTree;
@@ -102,6 +103,8 @@
     public static final String OBJECT_PATH_TAG = "object-path";
 
     public static final String OBJECT_PATH = "esb";
+    
+    public static final String ENTRY_POINT = "entry-point";
 
     public static final String DEFAULT_CBR_CLASS = "org.jboss.internal.soa.esb.services.routing.cbr.JBossRulesRouter";
 
@@ -234,19 +237,36 @@
             }
         }
         _messagePathList = new ArrayList<String>();
+        entryPointMap = new HashMap<String, List<String>>();
         ConfigTree[] objectList = _config.getChildren(OBJECT_PATH_TAG);
         if (objectList != null) {
             for (ConfigTree curr : objectList) {
                 try {
-                    String objectPath = curr.getRequiredAttribute(OBJECT_PATH);
-                    _messagePathList.add(objectPath);
+                    final String objectPath = curr.getRequiredAttribute(OBJECT_PATH);
+                    final String entryPoint = curr.getAttribute(ENTRY_POINT);
+                    if (entryPoint != null)
+                    {
+                        List<String> list = entryPointMap.get(entryPoint);
+                        if (list == null)
+                        {
+                            list = new ArrayList<String>();
+                            // Add the list to the entrypoint map indexed by the entry-point name.
+                            entryPointMap.put(entryPoint, list);
+                        }
+                        // Add the object path to the entry-point list.
+                        list.add(objectPath);
+                    }
+                    else
+                    {
+                        _messagePathList.add(objectPath);
+                    }
                 }
                 catch (Exception e) {
-                    throw new ConfigurationException(
-                            "Problems with object path list", e);
+                    throw new ConfigurationException( "Problems with object path list", e);
                 }
             }
         }
+        
 
     }
 
@@ -265,6 +285,8 @@
     protected boolean _ruleReload;
 
     protected List<String> _messagePathList;
+    
+    protected Map<String, List<String>> entryPointMap;
 
     protected ObjectMapper _mapper;
 

Added: labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/soa/esb/services/rules/RuleInfo.java
===================================================================
--- labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/soa/esb/services/rules/RuleInfo.java	                        (rev 0)
+++ labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/soa/esb/services/rules/RuleInfo.java	2009-07-03 08:49:57 UTC (rev 27480)
@@ -0,0 +1,87 @@
+/*
+ * JBoss, Home of Professional Open Source Copyright 2009, 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;
+
+/**
+ * RuleInfoImpl contains rule execution configuration parameters that
+ * are passed to the {@link RuleService}.
+ *
+ * @author <a href="mailto:dbevenius at jboss.com">Daniel Bevenius</a>
+ * @since 4.6
+ *
+ */
+public interface RuleInfo
+{
+    /**
+	 * Source of the Rules.
+	 *
+	 * @return {@code String} The rule source.
+     */
+    String getRuleSource();
+
+    /**
+	 * The type of rule
+	 *
+	 * @return {@code String} The type of rule.
+     */
+    String getRuleType();
+
+    /**
+	 * The Domain Specific Language (dsl) for the the rules source.
+	 *
+	 * @return {@code String} The dsl source.
+     */
+    String getDslSource();
+
+    /**
+     * Determines if the rules should be reloaded upon execution.
+     *
+	 * @return {@code boolean} True if rules should be reloaded.
+     */
+    boolean getReload();
+
+    /**
+     * Facts that will be inserted into the working memory.
+     *
+     * @return {@code List<Object>}  List of Object that will be inserted as facts in the working memory.
+     */
+    List<Object> getDefaultFacts();
+
+    /**
+     * Global that will be inserted into the working memory (as globals).
+     *
+     * @return {@code <Map<String, Object>} Map of objects that will be inserted as globals in the working memory.
+     */
+    Map<String, Object> getGlobals();
+
+    /**
+     * Facts that will be inserted into working memory. These fact are indexed by a name which can be used
+     * to support concepts as Entry Points.
+     *
+     * @return {@code <Map<String, List<Object>>} Map of lists that will be inserted as facts in the working memory,
+     *                                          separated by the name. Used to support concepts like Entry Points.
+     */
+    Map<String, List<Object>> getFacts();
+
+}
\ No newline at end of file

Modified: labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/soa/esb/services/rules/RuleService.java
===================================================================
--- labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/soa/esb/services/rules/RuleService.java	2009-07-03 08:39:30 UTC (rev 27479)
+++ labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/soa/esb/services/rules/RuleService.java	2009-07-03 08:49:57 UTC (rev 27480)
@@ -58,6 +58,7 @@
 	 *            working memory 
 	 * 
 	 * @return Message with updated objects.
+	 * @deprecated Please use {@link #executeStatelessRules(RuleInfo, Message)} instead.
 	 */
 	public Message executeStatelessRules(
 			String ruleSet, 
@@ -66,7 +67,9 @@
 			Message message, 
 			Map<String,Object> globals, 
 			List<Object> objectList) throws RuleServiceException;
-
+	
+	public Message executeStatelessRules(final RuleInfo ruleInfo, final Message message) throws RuleServiceException;
+	
 	/**
 	 * Execute rules from a decision table using the Stateless rule engine API
 	 * 
@@ -81,6 +84,7 @@
 	 *            working memory 
 	 * 
 	 * @return Message with updated objects.
+	 * @deprecated Please use {@link #executeStatelessRulesFromDecisionTable(RuleInfo, Message)} instead.
 	 */
 	public Message executeStatelessRulesFromDecisionTable(
 			String decisionTable,
@@ -88,7 +92,9 @@
 			Message message, 
 			Map<String,Object> globals, 
 			List<Object> objectList) throws RuleServiceException;
-
+	
+	public Message executeStatelessRulesFromDecisionTable(final RuleInfo ruleInfo, final Message message) 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
@@ -101,12 +107,15 @@
 	 *            working memory 
 	 * 
 	 * @return Message with updated objects.
+	 * @deprecated Please use {@link #executeStatelessRulesFromRuleAgent(RuleInfo, Message)} instead.
 	 */
 	public Message executeStatelessRulesFromRuleAgent(
 			String ruleAgentProperties, 
 			Message message, 
 			Map<String,Object> globals, 
 			List<Object> objectList) throws RuleServiceException;
+	
+	public Message executeStatelessRulesFromRuleAgent(final RuleInfo ruleInfo, final Message message) throws RuleServiceException;
 
 	/**
 	 * Execute rules using a certain ruleSet and domain specific language using the Stateful rule engine API
@@ -127,6 +136,7 @@
 	 *            working memory 
 	 * 
 	 * @return Message with updated objects.
+	 * @deprecated Please use {@link #executeStatefulRules(RuleInfo, Message)} instead.
 	 */
 	public Message executeStatefulRules(
 			String ruleSet, 
@@ -135,6 +145,10 @@
 			Message message,
 			Map<String,Object> globals,
 			List<Object> objectList) throws RuleServiceException;
+	
+	public Message executeStatefulRules(final StatefulRuleInfo info, final Message msg) throws RuleServiceException;
+	
+	
 
 	/**
 	 * Execute rules from a decision table using the Stateful rule engine API
@@ -152,6 +166,7 @@
 	 *            working memory 
 	 * 
 	 * @return Message with updated objects.
+	 * @deprecated Please use {@link #executeStatefulRulesFromDecisionTable(RuleInfo, Message)} instead.
 	 */
 	public Message executeStatefulRulesFromDecisionTable(
 			String decisionTable,
@@ -159,6 +174,8 @@
 			Message message, 
 			Map<String,Object> globals,
 			List<Object> objectList) throws RuleServiceException;
+	
+	public Message executeStatefulRulesFromDecisionTable(final StatefulRuleInfo info, final Message msg) throws RuleServiceException;
 
 	/**
 	 * Execute rules using a rule package retrieved via the Rule Agent from a URL of local file system
@@ -174,12 +191,15 @@
 	 *            working memory 
 	 * 
 	 * @return Message with updated objects.
+	 * @deprecated Please use {@link #executeStatefulRulesFromRuleAgent(RuleInfo, Message)} instead.
 	 */
 	public Message executeStatefulRulesFromRuleAgent(
 			String ruleAgentProperties, 
 			Message message,
 			Map<String,Object> globals,
 			List<Object> objectList) throws RuleServiceException;
+	
+	public Message executeStatefulRulesFromRuleAgent(final StatefulRuleInfo info, final Message msg) throws RuleServiceException;
 
 	/**
 	 * Continue executing rules where the working memory already exists.
@@ -197,6 +217,7 @@
 	 *            working memory 
 	 * 
 	 * @return Message with updated objects.
+	 * @deprecated Please use {@link #continueStatefulRulesExecution(StatefulRuleInfo, Message)} instead.
 	 */
 	public Message continueStatefulRulesExecution(
 			String rules,
@@ -205,4 +226,6 @@
 			Map<String,Object> globals, 
 			List<Object> objectList) throws RuleServiceException;
 	
+	public Message continueStatefulRulesExecution(final StatefulRuleInfo info, final Message msg) throws RuleServiceException;
+	
 }

Added: labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/soa/esb/services/rules/StatefulRuleInfo.java
===================================================================
--- labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/soa/esb/services/rules/StatefulRuleInfo.java	                        (rev 0)
+++ labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/soa/esb/services/rules/StatefulRuleInfo.java	2009-07-03 08:49:57 UTC (rev 27480)
@@ -0,0 +1,40 @@
+/*
+ * JBoss, Home of Professional Open Source Copyright 2009, 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;
+
+/**
+ * RuleInfoImpl contains stateful related rule execution configuration parameters that
+ * are passed to the {@link RuleService}.
+ *
+ * @author <a href="mailto:dbevenius at jboss.com">Daniel Bevenius</a>
+ * @since 4.6
+ *
+ */
+public interface StatefulRuleInfo extends RuleInfo
+{
+    /**
+     * If dispose is true the stateful working memory should be disposed of.
+     * Not disposing a working memory you lead to memory leaks.
+     *
+     * @return {@code boolean} If the working memory should be disposed of (cleaned up).
+     */
+    boolean dispose();
+}

Modified: labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/routing/cbr/JBossRulesRouterUnitTest.java
===================================================================
--- labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/routing/cbr/JBossRulesRouterUnitTest.java	2009-07-03 08:39:30 UTC (rev 27479)
+++ labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/routing/cbr/JBossRulesRouterUnitTest.java	2009-07-03 08:49:57 UTC (rev 27480)
@@ -48,7 +48,7 @@
 
 /**
  * Tests for {@link JBossRulesRouter}.
- * 
+ *
  * @author kurt.stam at redhat.com
  * @author <a href="mailto:dbevenius at redhat.com">Daniel Bevenius</a>
  *
@@ -57,50 +57,50 @@
 {
     //	instance under test
 	private JBossRulesRouter jbrRouter;
-	
+
 	@Test
 	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
 	{
@@ -110,7 +110,7 @@
 		List<String> destinationServices = jbrRouter.route("JBossESBRules.drl",false,message,null);
 		assertEquals(destinationServices.iterator().next(),"xml-destination");
 	}
-	
+
 	@Test
 	public void routeXMLMessageUsingXPathMatch() throws MessageRouterException
 	{
@@ -118,37 +118,37 @@
 		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()
 	{
@@ -159,14 +159,14 @@
 			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
 	{
@@ -174,10 +174,10 @@
 		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
 	{
@@ -185,10 +185,10 @@
 		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
@@ -211,19 +211,19 @@
 		jbossRulesRouter.setConfigTree( configTree );
         try {
     		List<String> destinations = jbossRulesRouter.route("JBossESBPricingRoutingRules.drl", false, message, objectList);
-            assertEquals(order.getDiscount(),10.0);
+            assertEquals(order.getDiscount(),10.0, 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
@@ -246,28 +246,28 @@
 		jbossRulesRouter.setConfigTree( configTree );
         try {
             List<String> destinations = jbossRulesRouter.route("JBossESBPricingRoutingRules.drl", false, message, objectList);
-            assertEquals(order.getDiscount(),0.0);
+            assertEquals(order.getDiscount(),0.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);
         }
     }
-	
+
 	@Before
 	public void setup() throws MessageRouterException
 	{
 		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 
+	public static void runBeforeAllTests() throws Exception
 	{
 		try {
 			TestEnvironmentUtil.setESBPropertiesFileToUse();
@@ -277,7 +277,7 @@
 			assertTrue(false);
 		}
 	}
-	
+
 	private Message createMessage( final URI type )
 	{
 		//new messages
@@ -292,7 +292,7 @@
 		message.getAttachment().addItem(new String("TEST ATTACHMENT2"));
 		return message;
 	}
-	
+
 	public static junit.framework.Test suite() {
 		return new JUnit4TestAdapter(JBossRulesRouterUnitTest.class);
 	}

Modified: labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleServiceUnitTest.java
===================================================================
--- labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleServiceUnitTest.java	2009-07-03 08:39:30 UTC (rev 27479)
+++ labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleServiceUnitTest.java	2009-07-03 08:49:57 UTC (rev 27480)
@@ -23,7 +23,6 @@
 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;
@@ -38,17 +37,17 @@
 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.common.Environment;
 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.rules.StatefulRuleInfo;
 import org.jboss.soa.esb.util.ClassUtil;
 import org.junit.Before;
 import org.junit.Test;
@@ -56,21 +55,21 @@
 /**
  * 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()
 	{
@@ -79,8 +78,20 @@
 		ArrayList<String> destinations = getDistinations( globals );
 		assertTrue( destinations.size() == 1 );
 	}
-	
+
 	@Test
+    public void executeStatelessRulesWithRuleInfo() throws RuleServiceException
+    {
+	    RuleInfoBuilder builder = new RuleInfoBuilder("JBossESBRules.drl");
+		Map<String,Object> globals = getGlobalsWithDestAndMessage();
+	    builder.globals(globals);
+
+        message = ruleService.executeStatelessRules(builder.build(), message);
+        ArrayList<String> destinations = getDistinations( globals );
+        assertTrue( destinations.size() == 1 );
+    }
+
+	@Test
 	public void executeStatelessRulesFromDecisionTableReload() throws RuleServiceException
 	{
 		Map<String,Object> globals = getGlobalsWithDest();
@@ -89,8 +100,21 @@
 		ArrayList<String> destinations = getDistinations( globals );
 		assertTrue( destinations.size() == 1 );
 	}
-	
+
 	@Test
+    public void executeStatelessRulesFromDecisionTableReloadWithRuleInfo() throws RuleServiceException
+    {
+	    RuleInfoBuilder builder = new RuleInfoBuilder("RuleBaseHelper.xls");
+        Map<String,Object> globals = getGlobalsWithDest();
+	    builder.globals(globals);
+	    builder.reload(true);
+
+        message = ruleService.executeStatelessRulesFromDecisionTable(builder.build(), message);
+        ArrayList<String> destinations = getDistinations( globals );
+        assertTrue( destinations.size() == 1 );
+    }
+
+	@Test
 	public void executeStatelessRulesFromDecisionTable() throws RuleServiceException
 	{
 		Map<String,Object> globals = getGlobalsWithDest();
@@ -99,8 +123,21 @@
 		ArrayList<String> destinations = getDistinations( globals );
 		assertTrue( destinations.size() == 1 );
 	}
-	
+
 	@Test
+    public void executeStatelessRulesFromDecisionTableWithRuleInfo() throws RuleServiceException
+    {
+	    RuleInfoBuilder builder = new RuleInfoBuilder("RuleBaseHelper.xls");
+        Map<String,Object> globals = getGlobalsWithDest();
+	    builder.globals(globals);
+	    builder.reload(false);
+
+        message = ruleService.executeStatelessRulesFromDecisionTable(builder.build(), message);
+        ArrayList<String> destinations = getDistinations( globals );
+        assertTrue( destinations.size() == 1 );
+    }
+
+	@Test
 	public void executeStatfulRulesFromDecisionTableReload() throws RuleServiceException
 	{
 		Map<String,Object> globals = getGlobalsWithDest();
@@ -109,7 +146,7 @@
 		ArrayList<String> destinations = getDistinations( globals );
 		assertTrue( destinations.size() == 1 );
 	}
-	
+
 	@Test
 	public void executeStatfulRulesFromDecisionTable() throws RuleServiceException
 	{
@@ -119,16 +156,16 @@
 		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 );
+		message = ruleService.executeStatefulRules( "JBossESBRules.drl", null, true, message , globals, null );
 		ArrayList<String> destinations = getDistinations( globals );
 		assertTrue( destinations.size() == 1 );
 	}
-	
+
 	@Test
 	public void executeStatefulRulesDrl() throws RuleServiceException
 	{
@@ -137,7 +174,7 @@
 		ArrayList<String> destinations = getDistinations( globals );
 		assertTrue( destinations.size() == 1 );
 	}
-	
+
 	@Test
 	public void executeStatelessRulesDrlWithDsl() throws RuleServiceException, ConfigurationException, UnsupportedEncodingException
 	{
@@ -147,30 +184,30 @@
 		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
 	{
@@ -180,12 +217,12 @@
 		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
 	{
@@ -194,35 +231,82 @@
     	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.0, order.getDiscount(), 0 );
         assertEquals( "20%" ,message.getBody().get("DiscountObject"));
-        
-        //	process message again with a counter instance 
+
+        //	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() );
 	}
-	
+
+	@Test
+    public void continueSessionWithEntryPoint() throws RuleServiceException, ObjectMappingException, InterruptedException
+    {
+        Message message = createMessageWithOrder(order);
+        long timestamp = System.currentTimeMillis();
+        message.getProperties().setProperty(Environment.MESSAGE_ENTRY_TIME, timestamp);
+
+        final RuleInfoBuilder builder = new RuleInfoBuilder("PricingRulesStatefulEntryPoint.drl");
+		builder.global("message", message);
+		final ObjectMapper objectMapper = new ObjectMapper();
+		builder.defaultFact(objectMapper.getObjectFromMessage(message, "body.Counter"));
+		builder.defaultFact(message);
+
+		// OrderEntryPoint that matches the entry-point name in PricingRulesStatfulEntryPoint.drl.
+		builder.fact("OrderEntryPoint", objectMapper.getObjectFromMessage(message, "body.Order"));
+        // process message
+		StatefulRuleInfo statefulInfo = new StatefulRuleInfoImpl(builder.build(), true);
+        message = ruleService.executeStatefulRules(statefulInfo, message);
+
+        assertEquals( 20.0, order.getDiscount(), 0 );
+        assertEquals( "20%" ,message.getBody().get("DiscountObject"));
+
+    }
+
+	@Test (expected = RuleServiceException.class)
+    public void shouldThrowIfEntryPointDoesNotExistInSession() throws RuleServiceException, ObjectMappingException
+    {
+        Message message = createMessageWithOrder( order );
+        long timestamp = System.currentTimeMillis();
+        message.getProperties().setProperty(Environment.MESSAGE_ENTRY_TIME, timestamp);
+
+        final ArrayList<String> messagePathList = new ArrayList<String>();
+        messagePathList.add("body.Order");
+        messagePathList.add("body.Counter");
+
+        final RuleInfoBuilder builder = new RuleInfoBuilder("PricingRulesStatefulEntryPoint.drl");
+        builder.global("message", message);
+        final ObjectMapper objectMapper = new ObjectMapper();
+		builder.defaultFact(objectMapper.getObjectFromMessage(message, "body.Counter"));
+
+        // Non Existing entry-point name.
+        builder.fact("Bajja", objectMapper.getObjectFromMessage(message, "body.Order"));
+        // process message
+		StatefulRuleInfo statefulInfo = new StatefulRuleInfoImpl(builder.build(), true);
+        ruleService.executeStatefulRules(statefulInfo, message);
+    }
+
 	//	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");
@@ -232,20 +316,20 @@
 	{
 		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>();
@@ -253,14 +337,14 @@
 		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);

Added: labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/rules/RuleInfoImplUnitTest.java
===================================================================
--- labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/rules/RuleInfoImplUnitTest.java	                        (rev 0)
+++ labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/rules/RuleInfoImplUnitTest.java	2009-07-03 08:49:57 UTC (rev 27480)
@@ -0,0 +1,111 @@
+/*
+ * JBoss, Home of Professional Open Source Copyright 2009, 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.*;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.JUnit4TestAdapter;
+
+import org.jboss.internal.soa.esb.services.rules.RuleInfoBuilder;
+import org.jboss.internal.soa.esb.services.rules.RuleInfoImpl;
+import org.jboss.soa.esb.services.rules.RuleInfo;
+import org.junit.Test;
+
+/**
+ * Unit test for {@link RuleInfoImpl}.
+ * 
+ * @author <a href="mailto:dbevenius at jboss.com">Daniel Bevenius</a>
+ *
+ */
+public class RuleInfoImplUnitTest
+{
+    @Test
+    public void ruleSet()
+    {
+        final RuleInfoBuilder builder = new RuleInfoBuilder("dummy.drl");
+        final RuleInfo info = builder.ruleType("DRL").build();;
+        assertEquals("dummy.drl", info.getRuleSource());
+        assertEquals("DRL", info.getRuleType());
+    }
+    
+    @Test (expected = IllegalArgumentException.class)
+    public void ruleSetNull()
+    {
+        new RuleInfoBuilder(null);
+    }
+    
+    @Test
+    public void fact()
+    {
+        final RuleInfoBuilder builder = new RuleInfoBuilder("dummy.drl");
+        final RuleInfo info = builder.fact("one", "first").build();;
+        Map<String, List<Object>> facts = info.getFacts();
+        assertTrue(facts.get("one").contains("first"));
+    }
+    
+    @Test
+    public void factEmpty()
+    {
+        RuleInfo info = new RuleInfoBuilder("dummy.drl").build();
+        Map<String, List<Object>> facts = info.getFacts();
+        assertTrue(facts.isEmpty());
+    }
+    
+    @Test
+    public void facts()
+    {
+        final RuleInfoBuilder builder = new RuleInfoBuilder("dummy.drl");
+        Map<String, List<Object>> facts = new HashMap<String, List<Object>>();
+        facts.put("one", Arrays.asList(new Object[] {"first"}));
+        builder.facts(facts);
+        
+        final RuleInfo info = builder.build();
+        facts = info.getFacts();
+        assertTrue(facts.get("one").contains("first"));
+        assertTrue(facts.get("one").contains("first"));
+    }
+    
+    @Test
+    public void globals()
+    {
+        final RuleInfoBuilder builder = new RuleInfoBuilder("dummy.drl");
+        HashMap<String, Object> globals = new HashMap<String, Object>();
+        globals.put("message", "msgObject");
+        
+        builder.globals(globals);
+        final RuleInfo info = builder.build();
+        Map<String, Object> g = info.getGlobals();
+        assertTrue(g.containsKey("message"));
+        assertTrue(g.containsValue("msgObject"));
+        
+    }
+    
+    public static junit.framework.Test suite()
+    {
+        return new JUnit4TestAdapter(RuleInfoImplUnitTest.class);
+    }
+
+}

Added: labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/rules/util/RuleConfigUtilUnitTest.java
===================================================================
--- labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/rules/util/RuleConfigUtilUnitTest.java	                        (rev 0)
+++ labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/rules/util/RuleConfigUtilUnitTest.java	2009-07-03 08:49:57 UTC (rev 27480)
@@ -0,0 +1,76 @@
+/*
+ * JBoss, Home of Professional Open Source Copyright 2009, 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.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.JUnit4TestAdapter;
+
+import org.jboss.internal.soa.esb.services.rules.RuleServiceException;
+import org.jboss.soa.esb.ConfigurationException;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.message.format.MessageFactory;
+import org.jboss.soa.esb.services.registry.RegistryException;
+import org.jboss.soa.esb.services.routing.MessageRouterException;
+import org.junit.Test;
+
+/**
+ * Unit test for {@link RuleConfigUtil}.
+ * 
+ * @author <a href="mailto:dbevenius at jboss.com">Daniel Bevenius</a>
+ *
+ */
+public class RuleConfigUtilUnitTest
+{
+    @Test
+    public void extractObjectsFromMessage() throws ConfigurationException, RegistryException, MessageRouterException, RuleServiceException
+    {
+        final Message message = MessageFactory.getInstance().getMessage();
+        message.getBody().add("TestString", "bajja");
+        
+        final Map<String, List<String>> entryPointMap = new HashMap<String, List<String>>();
+        final ArrayList<String> objectNames = new ArrayList<String>();
+        objectNames.add("body.TestString");
+        entryPointMap.put("entryPoint1", objectNames);
+        
+        final Map<String, List<Object>> entryPoints = RuleConfigUtil.extractObjectsFromMessage(entryPointMap, message);
+        
+        assertNotNull(entryPoints);
+        assertEquals(1, entryPoints.size());
+        assertTrue(entryPoints.containsKey("entryPoint1"));
+        final List<Object> objects = entryPoints.get("entryPoint1");
+        System.out.println(objects);
+        assertTrue(objects.contains("bajja"));
+    }
+    
+    public static junit.framework.Test suite()
+    {
+        return new JUnit4TestAdapter(RuleConfigUtilUnitTest.class);
+    }
+
+}

Modified: labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/BusinessRulesProcessorUnitTest.java
===================================================================
--- labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/BusinessRulesProcessorUnitTest.java	2009-07-03 08:39:30 UTC (rev 27479)
+++ labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/BusinessRulesProcessorUnitTest.java	2009-07-03 08:49:57 UTC (rev 27480)
@@ -21,11 +21,14 @@
  */
 package org.jboss.soa.esb.actions;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.*;
 
 import java.math.BigDecimal;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 import junit.framework.JUnit4TestAdapter;
 
@@ -46,7 +49,7 @@
 
 /**
  * Unit test for {@link BusinessRulesProcessor}
- * 
+ *
  * @author <a href="mailto:dbevenius at redhat.com">Daniel Bevenius</a>
  *
  */
@@ -54,88 +57,147 @@
 {
 	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.0, order.getDiscount(), 0);
         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.0, order.getDiscount(), 0);
         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.0, order.getDiscount(), 0 );
         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() 
+
+	@Test
+    public void processDiscountWithEntryPoint() throws ObjectMappingException, ConfigurationException, RegistryException, MessageRouterException, ActionProcessingException
+    {
+		Order order = new Order();
+        order.setQuantity(20);
+        order.setUnitPrice( new BigDecimal("20.0") );
+
+        Message message = MessageFactory.getInstance().getMessage();
+        message.getBody().add("Order", order);
+
+        final ArrayList<String> defaultFacts = new ArrayList<String>();
+        defaultFacts.add("body.Counter");
+
+        final ArrayList<String> orderEntryPoints = new ArrayList<String>();
+        orderEntryPoints.add("body.Order");
+
+        Map<String, List<String>> entryPointFacts = new HashMap<String, List<String>>();
+        entryPointFacts.put("OrderEntryPoint", orderEntryPoints);
+        CBRConfigTreeBuilder builder = new CBRConfigTreeBuilder(true).ruleFile("PricingRulesStatefulEntryPoint.drl");
+        builder.messagePaths(defaultFacts).entryPoints(entryPointFacts);
+        ConfigTree config = builder.stateful(true).build();
+        BusinessRulesProcessor processor = new BusinessRulesProcessor(config);
+
+        processor.process( message );
+
+        assertEquals( 20.0, order.getDiscount(), 0 );
+        assertEquals( "20%" ,message.getBody().get("DiscountObject"));
+    }
+
+	@Test
+	public void isUseRuleSet() throws ConfigurationException, RegistryException, MessageRouterException
 	{
+        ConfigTree config = new CBRConfigTreeBuilder(true).ruleFile("test.dsl").build();
+        BusinessRulesProcessor processor = new BusinessRulesProcessor(config);
+        assertTrue(processor.isUseRuleSet());
+        assertFalse(processor.isUseRuleAgent());
+        assertFalse(processor.isUseDecisionTable());
+	}
+
+	@Test
+    public void isUseDecisionTable() throws ConfigurationException, RegistryException, MessageRouterException
+    {
+        ConfigTree config = new CBRConfigTreeBuilder(true).decisionTable("test.exl").build();
+        BusinessRulesProcessor processor = new BusinessRulesProcessor(config);
+        assertTrue(processor.isUseDecisionTable());
+        assertFalse(processor.isUseRuleSet());
+        assertFalse(processor.isUseRuleAgent());
+    }
+
+	@Test
+	public void isUseRuleAgent() throws ConfigurationException, RegistryException, MessageRouterException
+	{
+        ConfigTree config = new CBRConfigTreeBuilder(true).ruleAgent("testRuleAgentFile.properties").build();
+        BusinessRulesProcessor processor = new BusinessRulesProcessor(config);
+        assertTrue(processor.isUseRuleAgent());
+        assertFalse(processor.isUseRuleSet());
+        assertFalse(processor.isUseDecisionTable());
+	}
+
+	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;
 	}
-	
+
 }

Modified: labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/CBRConfigTreeBuilder.java
===================================================================
--- labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/CBRConfigTreeBuilder.java	2009-07-03 08:39:30 UTC (rev 27479)
+++ labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/CBRConfigTreeBuilder.java	2009-07-03 08:49:57 UTC (rev 27480)
@@ -22,6 +22,9 @@
 package org.jboss.soa.esb.actions;
 
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
 
 import org.jboss.soa.esb.actions.ContentBasedWiretap;
 import org.jboss.soa.esb.helpers.ConfigTree;
@@ -43,6 +46,7 @@
 	//	optional 
 	private String ruleFile;
 	private List<String> messagePathList;
+	private Map<String, List<String>> entryPointFacts;
 	private boolean stateful;
 	private String decisionTable;
 	private String ruleAgent;
@@ -78,6 +82,12 @@
 		return this;
 	}
 	
+	public CBRConfigTreeBuilder entryPoints( final Map<String, List<String>> entryPointFacts )
+	{
+		this.entryPointFacts = entryPointFacts;
+		return this;
+	}
+	
 	public CBRConfigTreeBuilder ruleServiceImpl( String ruleServiceImpl )
 	{
 		this.ruleServiceImpl = ruleServiceImpl;
@@ -115,6 +125,22 @@
 			}
         }
         
+        if ( entryPointFacts != null )
+        {
+            Set<Entry<String, List<String>>> entrySet = entryPointFacts.entrySet();
+            for (Entry<String, List<String>> entry : entrySet)
+            {
+                final String entryPointName = entry.getKey();
+                List<String> value = entry.getValue();
+                for (String path : value)
+                {
+            		ConfigTree objectPath = new ConfigTree( ContentBasedWiretap.OBJECT_PATH_TAG, configTree );
+            		objectPath.setAttribute( ContentBasedWiretap.OBJECT_PATH, path );
+            		objectPath.setAttribute( ContentBasedWiretap.ENTRY_POINT, entryPointName );
+                }
+            }
+        }
+        
         if ( stateful )
             configTree.setAttribute( RuleServicePropertiesNames.STATEFUL.getTagName(), Boolean.toString( stateful ) );
         

Modified: labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/ContentBasedWiretapUnitTest.java
===================================================================
--- labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/ContentBasedWiretapUnitTest.java	2009-07-03 08:39:30 UTC (rev 27479)
+++ labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/soa/esb/actions/ContentBasedWiretapUnitTest.java	2009-07-03 08:49:57 UTC (rev 27480)
@@ -22,11 +22,16 @@
 
 package org.jboss.soa.esb.actions;
 
+import static org.junit.Assert.*;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 import java.io.InputStream;
 import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 import junit.framework.JUnit4TestAdapter;
 
@@ -34,13 +39,15 @@
 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.ConfigurationException;
 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.services.registry.RegistryException;
+import org.jboss.soa.esb.services.routing.MessageRouterException;
 import org.jboss.soa.esb.testutils.FileUtil;
 import org.jboss.soa.esb.util.ClassUtil;
 import org.junit.BeforeClass;
@@ -139,4 +146,38 @@
             assertTrue(true);
         }
     }
+    
+    @Test
+    public void extractEntryPointsFromConfig() throws ConfigurationException, RegistryException, MessageRouterException
+    {
+        final Map<String, List<String>> entryPointsMap = new HashMap<String, List<String>>();
+        
+        final List<String> paths1 = new ArrayList<String>();
+        final String orderPath = "body.Order";
+        paths1.add(orderPath);
+        
+        final List<String> paths2 = new ArrayList<String>();
+        final String counterPath = "body.Counter";
+        paths2.add(counterPath);
+        
+        entryPointsMap.put("EntryPoint1", paths1);
+        entryPointsMap.put("EntryPoint2", paths2);
+        
+        final ConfigTree config = new CBRConfigTreeBuilder(true).ruleFile("JBossESBPricingRulesStateful.drl").entryPoints(entryPointsMap).build();
+        // Will call checkMyParams which will populate the maps below using the contents from the ConfigTree.
+        final ContentBasedRouter contentBasedRouter = new ContentBasedRouter(config);
+        
+        final Map<String, List<String>> entryPoints = contentBasedRouter.entryPointMap;
+        final List<String> entryPoint1 = entryPoints.get("EntryPoint1");
+        final List<String> entryPoint2 = entryPoints.get("EntryPoint2");
+        
+        assertNotNull(entryPoint1);
+        assertNotNull(entryPoint2);
+        assertEquals(1, entryPoint1.size());
+        assertEquals(1, entryPoint2.size());
+        assertTrue(entryPoint1.contains(orderPath));
+        assertTrue(entryPoint2.contains(counterPath));
+        assertFalse(contentBasedRouter._messagePathList.contains(orderPath));
+        assertFalse(contentBasedRouter._messagePathList.contains(counterPath));
+    }
 }
\ No newline at end of file

Added: labs/jbossesb/trunk/product/services/jbrules/src/test/resources/PricingRulesStatefulEntryPoint.drl
===================================================================
--- labs/jbossesb/trunk/product/services/jbrules/src/test/resources/PricingRulesStatefulEntryPoint.drl	                        (rev 0)
+++ labs/jbossesb/trunk/product/services/jbrules/src/test/resources/PricingRulesStatefulEntryPoint.drl	2009-07-03 08:49:57 UTC (rev 27480)
@@ -0,0 +1,50 @@
+package com.jboss.soa.esb.routing.cbr
+
+import org.jboss.soa.esb.message.Message;
+import org.jboss.internal.soa.esb.services.routing.cbr.Order;
+import org.jboss.soa.esb.actions.Counter;
+import org.jboss.internal.soa.esb.message.format.serialized.MessageImpl
+
+global Message message;
+
+declare MessageImpl
+    @role( event )
+    @timestamp( properties.getProperty("org.jboss.soa.esb.message.time.dob") )
+end
+
+rule "Pricing Rule - low quantity"
+	
+	when
+	    $m     : Message ()
+		$order : Order( quantity < 10) from entry-point "OrderEntryPoint"
+	then
+		$order.setDiscount(0);
+		$m.getBody().add("DiscountObject","0%");
+end
+
+rule "Prioriting Rule - high quantity"
+	when
+	    $m     : Message ()
+		$order : Order( quantity >= 10) from entry-point "OrderEntryPoint"
+		Order( discount == 0 ) from entry-point "OrderEntryPoint"
+		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




More information about the jboss-svn-commits mailing list