[jboss-svn-commits] JBL Code SVN: r21412 - in labs/jbossesb/branches/JBESB_4_4_GA_CP/product/services/jbrules/src: main/java/org/jboss/internal/soa/esb/services/rules and 2 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Fri Aug 8 10:22:05 EDT 2008


Author: kevin.conner at jboss.com
Date: 2008-08-08 10:22:05 -0400 (Fri, 08 Aug 2008)
New Revision: 21412

Added:
   labs/jbossesb/branches/JBESB_4_4_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/util/
   labs/jbossesb/branches/JBESB_4_4_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/util/RulesContext.java
Modified:
   labs/jbossesb/branches/JBESB_4_4_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/routing/cbr/DslHelper.java
   labs/jbossesb/branches/JBESB_4_4_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleService.java
   labs/jbossesb/branches/JBESB_4_4_GA_CP/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/routing/cbr/DslHelperUnitTest.java
Log:
Add a rules context and change DslHelper to use it for caching: JBESB-1908

Modified: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/routing/cbr/DslHelper.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_4_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/routing/cbr/DslHelper.java	2008-08-08 13:59:23 UTC (rev 21411)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/routing/cbr/DslHelper.java	2008-08-08 14:22:05 UTC (rev 21412)
@@ -23,10 +23,8 @@
 
 import java.io.ByteArrayInputStream;
 import java.io.StringReader;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.WeakHashMap;
 import java.util.Map.Entry;
 
 import javax.xml.xpath.XPath;
@@ -36,6 +34,7 @@
 
 import org.apache.log4j.Logger;
 import org.jboss.internal.soa.esb.assertion.AssertArgument;
+import org.jboss.internal.soa.esb.services.rules.util.RulesContext;
 import org.jboss.soa.esb.helpers.ConfigTree;
 import org.jboss.soa.esb.listeners.message.MessageDeliverException;
 import org.jboss.soa.esb.message.Message;
@@ -59,20 +58,34 @@
 {
 	private static Logger log = Logger.getLogger(DslHelper.class);
 	
+	/**
+	 * The name of the boolean map context.
+	 */
+	private static final String BOOLEAN_MAP = "DslHelper.BooleanMap" ;
+	
+	/**
+	 * The name of the number map.
+	 */
+	private static final String NUMBER_MAP = "DslHelper.NumberMap" ;
+	
+	/**
+	 * The name of the string map.
+	 */
+	private static final String STRING_MAP = "DslHelper.StringMap" ;
+	
+	/**
+	 * The name of the node map.
+	 */
+	private static final String NODE_MAP = "DslHelper.NodeMap" ;
+	
+	/**
+	 * The name of the node list map.
+	 */
+	private static final String NODE_LIST_MAP = "DslHelper.NodeListMap" ;
+	
 	/** XPath instance */
 	private static XPathFactory xpf = XPathFactory.newInstance();
     private static MessagePayloadProxy payloadProxy;
-    
-    /* 
-     * Maps that contain cached XPath results.
-     * K = XPath expression String
-     * V = {@link XPathCacheObject}
-     */
-	private static Map<String,XPathCacheObject<Boolean>> xpathBooleanResults = Collections.synchronizedMap( new WeakHashMap<String,XPathCacheObject<Boolean>>() );
-	private static Map<String,XPathCacheObject<Number>> xpathNumberResults = Collections.synchronizedMap( new WeakHashMap<String,XPathCacheObject<Number>>() );
-	private static Map<String,XPathCacheObject<String>> xpathStringResults = Collections.synchronizedMap( new WeakHashMap<String,XPathCacheObject<String>>() );
-	private static Map<String,XPathCacheObject<Node>> xpathNodeResults = Collections.synchronizedMap( new WeakHashMap<String,XPathCacheObject<Node>>() );
-	private static Map<String,XPathCacheObject<NodeList>> xpathNodeListResults = Collections.synchronizedMap( new WeakHashMap<String,XPathCacheObject<NodeList>>() );
 
     static {
         payloadProxy = new MessagePayloadProxy(new ConfigTree("config"), new String[] {BytesBody.BYTES_LOCATION}, new String[] {BytesBody.BYTES_LOCATION});
@@ -112,16 +125,27 @@
 	 */
     public static Boolean selectAsBoolean(final Message message, final String xpathExp, final Map<String,String> namespaces ) throws XPathExpressionException
 	{
-		XPathCacheObject<Boolean> cachedObject = xpathBooleanResults.get( xpathExp );
-		if ( cacheHit( cachedObject, message ) )
-			return cachedObject.getResult();
+		Map<String, Boolean> booleanMap = (Map<String, Boolean>)RulesContext.getContext(BOOLEAN_MAP) ;
+		if (booleanMap != null)
+		{
+			final Boolean result = booleanMap.get(xpathExp) ;
+			if (result != null)
+			{
+				return result ;
+			}
+		}
+		else
+		{
+			booleanMap = new HashMap<String, Boolean>() ;
+			RulesContext.setContext(BOOLEAN_MAP, booleanMap) ;
+		}
 		
 		XPath xpath = getXPath( namespaces );
 		Boolean value = (Boolean) xpath.evaluate( xpathExp, getInputSource(message), XPathConstants.BOOLEAN);
-		xpathBooleanResults.put( xpathExp, new XPathCacheObject<Boolean>( message.hashCode(), value ) );
+		booleanMap.put(xpathExp, value) ;
 		return value;
 	}
-    
+
     /**
 	 * Uses XPath to select the Number matched by the XPath expression. 
 	 * <p/>
@@ -157,13 +181,24 @@
      */
     public static Number selectAsNumber(final Message message, final String xpathExp, final Map<String,String> namespaces ) throws XPathExpressionException
 	{
-		final XPathCacheObject<Number> cachedObject = xpathNumberResults.get( xpathExp );
-		if ( cacheHit( cachedObject, message ) )
-			return cachedObject.getResult();
+		Map<String, Number> numberMap = (Map<String, Number>)RulesContext.getContext(NUMBER_MAP) ;
+		if (numberMap != null)
+		{
+			final Number result = numberMap.get(xpathExp) ;
+			if (result != null)
+			{
+				return result ;
+			}
+		}
+		else
+		{
+			numberMap = new HashMap<String, Number>() ;
+			RulesContext.setContext(NUMBER_MAP, numberMap) ;
+		}
 		
 		final XPath xpath = getXPath( namespaces );
 		final Number number = (Number) xpath.evaluate( xpathExp, getInputSource(message), XPathConstants.NUMBER);
-		xpathNumberResults.put( xpathExp, new XPathCacheObject<Number>( message.hashCode(), number ) );
+		numberMap.put(xpathExp, number) ;
 		return number;
 	}
     
@@ -202,13 +237,23 @@
      */
     public static String selectAsString(final Message message, final String xpathExp, final Map<String,String> namespaces ) throws XPathExpressionException
     {
-		final XPathCacheObject<String> cachedObject = xpathStringResults.get( xpathExp );
-		if ( cacheHit( cachedObject, message ) )
-			return cachedObject.getResult();
-		
+		Map<String, String> stringMap = (Map<String, String>)RulesContext.getContext(STRING_MAP) ;
+		if (stringMap != null)
+		{
+			final String result = stringMap.get(xpathExp) ;
+			if (result != null)
+			{
+				return result ;
+			}
+		}
+		else
+		{
+			stringMap = new HashMap<String, String>() ;
+			RulesContext.setContext(STRING_MAP, stringMap) ;
+		}
 		final XPath xpath = getXPath( namespaces );
 		final String string = (String) xpath.evaluate( xpathExp, getInputSource(message), XPathConstants.STRING);
-		xpathStringResults.put( xpathExp, new XPathCacheObject<String>( message.hashCode(), string ) );
+		stringMap.put(xpathExp, string) ;
 		return string;
 	}
     
@@ -249,13 +294,23 @@
      */
     public static Node selectAsNode(final Message message, final String xpathExp, final Map<String,String> namespaces ) throws XPathExpressionException
 	{
-		final XPathCacheObject<Node> cachedObject = xpathNodeResults.get( xpathExp );
-		if ( cacheHit( cachedObject, message ) )
-			return cachedObject.getResult();
-		
+		Map<String, Node> nodeMap = (Map<String, Node>)RulesContext.getContext(NODE_MAP) ;
+		if (nodeMap != null)
+		{
+			final Node result = nodeMap.get(xpathExp) ;
+			if (result != null)
+			{
+				return result ;
+			}
+		}
+		else
+		{
+			nodeMap = new HashMap<String, Node>() ;
+			RulesContext.setContext(NODE_MAP, nodeMap) ;
+		}
 		final XPath xpath = getXPath( namespaces );
 		final Node node = (Node) xpath.evaluate( xpathExp, getInputSource(message), XPathConstants.NODE);
-		xpathNodeResults.put( xpathExp, new XPathCacheObject<Node>( message.hashCode(), node ) );
+		nodeMap.put(xpathExp, node) ;
 		return node;
 	}
     
@@ -295,14 +350,24 @@
      */
     public static NodeList selectAsNodeList( final Message message, final String xpathExp, Map<String,String> namespaces ) throws XPathExpressionException
 	{
-		final XPathCacheObject<NodeList> cachedObject = xpathNodeListResults.get( xpathExp );
-		if ( cacheHit( cachedObject, message ) )
-			return cachedObject.getResult();
-		
+		Map<String, NodeList> nodeListMap = (Map<String, NodeList>)RulesContext.getContext(NODE_LIST_MAP) ;
+		if (nodeListMap != null)
+		{
+			final NodeList result = nodeListMap.get(xpathExp) ;
+			if (result != null)
+			{
+				return result ;
+			}
+		}
+		else
+		{
+			nodeListMap = new HashMap<String, NodeList>() ;
+			RulesContext.setContext(NODE_LIST_MAP, nodeListMap) ;
+		}
 		final XPath xpath = getXPath( namespaces );
 		final NodeList nodeList = (NodeList) xpath.evaluate(xpathExp, getInputSource(message), XPathConstants.NODESET);
 		log.info("XPath [" + xpathExp + "], nr of matches : " + nodeList.getLength());
-		xpathNodeListResults.put( xpathExp, new XPathCacheObject<NodeList>( message.hashCode(), nodeList ) );
+		nodeListMap.put(xpathExp, nodeList) ;
 		return nodeList;
 	}
     
@@ -551,15 +616,6 @@
 		}
 		return namespacesMap;
 	}
-    
-	/*
-	 * Checks if the cachedObject was non-null, and if so, checks the message hashCode against
-	 * the cachedObjects messageHashCode.
-	 */
-    private static <T> boolean cacheHit ( final XPathCacheObject<T> cachedObject, final Message message )
-    {
-		return cachedObject != null && cachedObject.getMessageHashCode() == message.hashCode();
-    }
 	
 	private static double parseDouble( final String string ) throws XPathExpressionException
 	{
@@ -619,54 +675,4 @@
 		setNamespaces( xpath, namespaces );
 		return xpath;
     }
-    
-	/**
-	 * XPathCacheObject holds results from XPath evaluations and message object instance hashcodes.
-	 * </p> 
-	 * The intent of this class is for it to be used as the value in a Map:
-	 * <pre>
-	 * {@code  
-	 * Map<String,XPathCacheObject> xpathResults = new WeakHashMap<String,XPathCacheObject>() );
-	 * }</pre><br><br>
-	 * The key would be a String representing the XPath expression which was used to evaluate the result from 
-	 * the Message Object instance represented by the messageHashCode.
-	 * 
-	 */
-	private static class XPathCacheObject<T>
-	{
-		/*
-		 * The hashCode of the Message object used in the XPath evaluation
-		 */
-		private final int messageHashCode;
-		/*
-		 * The result from the XPath evalutaion
-		 */
-		private final T result;
-		
-		/**
-		 * Sole constructor.
-		 * 
-		 * @param messageHashCode -
-		 * 				The hashCode of the Message object used in the XPath evaluation
-		 * @param result -
-		 * 				The result from the XPath evalutaion
-		 */
-		public XPathCacheObject( final int messageHashCode, final T result )
-		{
-			this.messageHashCode = messageHashCode;
-			this.result = result;
-		}
-		
-		public int getMessageHashCode() 
-		{ 
-			return messageHashCode; 
-		}
-		
-		public T getResult() 
-		{ 
-			return result; 
-		}
-	}
-	
 }
-	

Modified: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleService.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_4_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleService.java	2008-08-08 13:59:23 UTC (rev 21411)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/DroolsRuleService.java	2008-08-08 14:22:05 UTC (rev 21412)
@@ -37,6 +37,7 @@
 import org.drools.compiler.DroolsParserException;
 import org.jboss.internal.soa.esb.assertion.AssertArgument;
 import org.jboss.internal.soa.esb.services.routing.cbr.JBRulesCounter;
+import org.jboss.internal.soa.esb.services.rules.util.RulesContext;
 import org.jboss.soa.esb.helpers.ConfigTree;
 import org.jboss.soa.esb.lifecycle.LifecyclePriorities;
 import org.jboss.soa.esb.lifecycle.LifecycleResource;
@@ -585,9 +586,17 @@
 	{
 		
 		final StatelessSession statelessSession = ruleBase.newStatelessSession();
-		final List<Object> facts = getFacts( message, objectList );
-		addGlobalsVariables( statelessSession, globals );
-		statelessSession.execute(facts);
+		RulesContext.clearContext() ;
+		try
+		{
+			final List<Object> facts = getFacts( message, objectList );
+			addGlobalsVariables( statelessSession, globals );
+			statelessSession.execute(facts);
+		}
+		finally
+		{
+			RulesContext.clearContext() ;
+		}
 		return message;
 	}
 	
@@ -617,6 +626,7 @@
 			final List<Object> objectList) 
 	{
         synchronized (ruleBase) {
+            RulesContext.clearContext() ;
             final StatefulSession statefulSession = getStatefulSession( ruleBase );
             try
             {
@@ -627,6 +637,7 @@
             }
             finally
             {
+                RulesContext.clearContext() ;
                 if ( dispose )
                 {
                     statefulSession.dispose();

Added: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/util/RulesContext.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_4_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/util/RulesContext.java	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/util/RulesContext.java	2008-08-08 14:22:05 UTC (rev 21412)
@@ -0,0 +1,94 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.internal.soa.esb.services.rules.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * Class providing access to a rules context for an execution.
+ */
+public class RulesContext 
+{
+    /**
+     * The rules context passed via 
+     */
+    private static final ThreadLocal<Map<String, Object>> CONTEXT = new ThreadLocal<Map<String,Object>>() ;
+    
+    /**
+     * Clear the context associated with the current thread.
+     */
+    public static void clearContext()
+    {
+        CONTEXT.set(null) ;
+    }
+    
+    /**
+     * Get the rules context value with the specified name. 
+     * @param name The name of the context value.
+     * @return The context value or null if not set.
+     */
+    public static Object getContext(final String name)
+    {
+        final Map<String, Object> context = CONTEXT.get() ;
+        return (context != null) ? context.get(name) : null ;
+    }
+    
+    /**
+     * Set the context value.
+     * @param name The name of the context value.
+     * @param value The associated value or null to remove.
+     */
+    public static void setContext(final String name, final Object value)
+    {
+        final Map<String, Object> context = CONTEXT.get() ;
+        if (context != null)
+        {
+            initialiseContext(context, name, value) ;
+        }
+        else
+        {
+            final Map<String, Object> newContext = new HashMap<String, Object>() ;
+            CONTEXT.set(newContext) ;
+            initialiseContext(newContext, name, value) ;
+        }
+    }
+    
+    /**
+     * Initialise the context value.
+     * @param context The current context.
+     * @param name The name of the context value.
+     * @param value The value of the context or null if it is to be removed.
+     */
+    private static void initialiseContext(final Map<String, Object> context, final String name, final Object value)
+    {
+        if (value == null)
+        {
+            context.remove(name) ;
+        }
+        else
+        {
+            context.put(name, value) ;
+        }
+    }
+}


Property changes on: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/rules/util/RulesContext.java
___________________________________________________________________
Name: svn:keywords
   + Rev Date
Name: svn:eol-style
   + native

Modified: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/routing/cbr/DslHelperUnitTest.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_4_GA_CP/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/routing/cbr/DslHelperUnitTest.java	2008-08-08 13:59:23 UTC (rev 21411)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/routing/cbr/DslHelperUnitTest.java	2008-08-08 14:22:05 UTC (rev 21412)
@@ -37,10 +37,13 @@
 import junit.framework.JUnit4TestAdapter;
 
 import org.apache.log4j.Logger;
+import org.jboss.internal.soa.esb.services.rules.util.RulesContext;
 import org.jboss.internal.soa.esb.util.StreamUtils;
 import org.jboss.soa.esb.message.Message;
 import org.jboss.soa.esb.message.format.MessageFactory;
 import org.jboss.soa.esb.util.ClassUtil;
+import org.junit.After;
+import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
@@ -218,7 +221,7 @@
 		}
 		long endTime = TimeUnit.NANOSECONDS.toMillis( System.nanoTime() - startTime );
 		log.info( "Timed " + nrOfCalls + " runs : " + endTime + "ms" );
-		assertTrue( nrOfCalls + " of calls should have taken less then 150ms", endTime < 150 );
+		assertTrue( nrOfCalls + " of calls should have taken less then 150ms, took " + endTime, endTime < 150 );
 	}
 	
 	@Test 
@@ -237,6 +240,13 @@
 		DslHelper.parseNamespaces( null );
 	}
 	
+	@Before
+	@After
+	public void clearContext()
+	{
+		RulesContext.clearContext() ;
+	}
+	
 	@BeforeClass
 	public static void createMessage() throws UnsupportedEncodingException
 	{




More information about the jboss-svn-commits mailing list