[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