[jboss-svn-commits] JBL Code SVN: r20854 - in labs/jbossesb/trunk/product/services/jbrules/src: test/java/org/jboss/internal/soa/esb/services/routing/cbr and 1 other directory.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Tue Jul 1 07:30:05 EDT 2008


Author: beve
Date: 2008-07-01 07:30:04 -0400 (Tue, 01 Jul 2008)
New Revision: 20854

Added:
   labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/routing/cbr/DslHelperUnitTest.java
Modified:
   labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/routing/cbr/DslHelper.java
Log:
Work for JBESB-1504 "CBR using rules has poor performance"


Modified: labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/routing/cbr/DslHelper.java
===================================================================
--- labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/routing/cbr/DslHelper.java	2008-07-01 09:10:44 UTC (rev 20853)
+++ labs/jbossesb/trunk/product/services/jbrules/src/main/java/org/jboss/internal/soa/esb/services/routing/cbr/DslHelper.java	2008-07-01 11:30:04 UTC (rev 20854)
@@ -23,6 +23,9 @@
 
 import java.io.ByteArrayInputStream;
 import java.io.StringReader;
+import java.util.Collections;
+import java.util.Map;
+import java.util.WeakHashMap;
 
 import javax.xml.xpath.XPath;
 import javax.xml.xpath.XPathConstants;
@@ -30,178 +33,330 @@
 import javax.xml.xpath.XPathFactory;
 
 import org.apache.log4j.Logger;
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.listeners.message.MessageDeliverException;
 import org.jboss.soa.esb.message.Message;
 import org.jboss.soa.esb.message.MessagePayloadProxy;
 import org.jboss.soa.esb.message.body.content.BytesBody;
-import org.jboss.soa.esb.helpers.ConfigTree;
-import org.jboss.soa.esb.listeners.message.MessageDeliverException;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
 import org.xml.sax.InputSource;
 
 /**
  * Domain Specific Language helper. Right now this supports the use of XPath, but this class can
  * be beefed up upo to use other technologies as well.
+ * <p/>
  * 
  * @author kstam at redhat.com
+ * @author <a href="mailto:dbevenius at redhat.com">Daniel Bevenius</a>
  *
  */
 public class DslHelper 
 {
 	private static Logger log = Logger.getLogger(DslHelper.class);
+	
 	/** XPath instance */
 	private static XPathFactory xpf = XPathFactory.newInstance();
     private static MessagePayloadProxy payloadProxy;
+    
+    /* 
+     * Maps that contain cached XPath results.
+     * K = XPath expression String
+     * V = {@link XPathCacheObject}
+     */
+	private static Map<String,XPathCacheObject<Boolean>> xpathBooleanResults = Collections.synchronizedMap( new WeakHashMap<String,XPathCacheObject<Boolean>>() );
+	private static Map<String,XPathCacheObject<Number>> xpathNumberResults = Collections.synchronizedMap( new WeakHashMap<String,XPathCacheObject<Number>>() );
+	private static Map<String,XPathCacheObject<String>> xpathStringResults = Collections.synchronizedMap( new WeakHashMap<String,XPathCacheObject<String>>() );
+	private static Map<String,XPathCacheObject<Node>> xpathNodeResults = Collections.synchronizedMap( new WeakHashMap<String,XPathCacheObject<Node>>() );
+	private static Map<String,XPathCacheObject<NodeList>> xpathNodeListResults = Collections.synchronizedMap( new WeakHashMap<String,XPathCacheObject<NodeList>>() );
 
     static {
-        payloadProxy = new MessagePayloadProxy(new ConfigTree("config"),
-                      new String[] {BytesBody.BYTES_LOCATION},
-                      new String[] {BytesBody.BYTES_LOCATION});
+        payloadProxy = new MessagePayloadProxy(new ConfigTree("config"), new String[] {BytesBody.BYTES_LOCATION}, new String[] {BytesBody.BYTES_LOCATION});
     }
-
+    
     /**
-	 * Uses XPath to look for the occurence of a certain tag, specific in the xpath expression.
+	 * Uses XPath to evalutate if the XPath expression is true or false. 
 	 * 
-	 * @param message - the ESB Message which body content will be used.
-	 * @param xpathExp - XPath expression to find a node.
-	 * @return true if the node is found and false in all other cases.
+	 * @param message -
+	 * 				the ESB Message which body content will be used
+	 * @param xpathExp -
+	 * 				XPath expression 
+	 * @return true 
+	 * 				if the XPath expression evalutes to true
 	 * @throws XPathExpressionException
+	 * 				represents an error in an XPath expression
 	 */
-	public static boolean xmlContentMatches(Message message, String xpathExp) throws XPathExpressionException 
+    public static Boolean selectAsBoolean(final Message message, final String xpathExp ) throws XPathExpressionException
 	{
-		if (log.isDebugEnabled()) {
-			log.debug("Trying to match xpath: '" + xpathExp +  "' in message=" + message);
-		}
+		XPathCacheObject<Boolean> cachedObject = xpathBooleanResults.get( xpathExp );
+		if ( cacheHit( cachedObject, message ) )
+			return cachedObject.getResult();
+		
 		XPath xpath = xpf.newXPath();
         InputSource inputSource = getInputSource(message);
-        Object node = xpath.evaluate(xpathExp, inputSource, XPathConstants.NODE);
-		if (log.isDebugEnabled()) {
-			log.debug("Found node=" + node);
-		}
-		return node != null;
+		Boolean value = (Boolean) xpath.evaluate( xpathExp, inputSource, XPathConstants.BOOLEAN);
+		xpathBooleanResults.put( xpathExp, new XPathCacheObject<Boolean>( message.hashCode(), value ) );
+		return value;
 	}
-
+    
+    public static Number selectAsNumber(final Message message, final String xpathExp ) throws XPathExpressionException
+	{
+		XPathCacheObject<Number> cachedObject = xpathNumberResults.get( xpathExp );
+		if ( cacheHit( cachedObject, message ) )
+			return cachedObject.getResult();
+		
+		XPath xpath = xpf.newXPath();
+        InputSource inputSource = getInputSource(message);
+		Number number = (Number) xpath.evaluate( xpathExp, inputSource, XPathConstants.NUMBER);
+		xpathNumberResults.put( xpathExp, new XPathCacheObject<Number>( message.hashCode(), number ) );
+		return number;
+	}
+    
+    public static String selectAsString(final Message message, final String xpathExp ) throws XPathExpressionException
+    {
+		XPathCacheObject<String> cachedObject = xpathStringResults.get( xpathExp );
+		if ( cacheHit( cachedObject, message ) )
+			return cachedObject.getResult();
+		
+		XPath xpath = xpf.newXPath();
+        InputSource inputSource = getInputSource(message);
+		String string = (String) xpath.evaluate( xpathExp, inputSource, XPathConstants.STRING);
+		xpathStringResults.put( xpathExp, new XPathCacheObject<String>( message.hashCode(), string ) );
+		return string;
+	}
+    
+    public static Node selectAsNode(final Message message, final String xpathExp ) throws XPathExpressionException
+	{
+		XPathCacheObject<Node> cachedObject = xpathNodeResults.get( xpathExp );
+		if ( cacheHit( cachedObject, message ) )
+			return cachedObject.getResult();
+		
+		XPath xpath = xpf.newXPath();
+        InputSource inputSource = getInputSource(message);
+		Node node = (Node) xpath.evaluate( xpathExp, inputSource, XPathConstants.NODE);
+		xpathNodeResults.put( xpathExp, new XPathCacheObject<Node>( message.hashCode(), node ) );
+		return node;
+	}
+    
+    public static NodeList selectAsNodeList( final Message message, final String xpathExp ) throws XPathExpressionException
+	{
+		XPathCacheObject<NodeList> cachedObject = xpathNodeListResults.get( xpathExp );
+		if ( cacheHit( cachedObject, message ) )
+			return cachedObject.getResult();
+		
+		XPath xpath = xpf.newXPath();
+        InputSource inputSource = getInputSource(message);
+		NodeList nodeList = (NodeList) xpath.evaluate(xpathExp, inputSource, XPathConstants.NODESET);
+		log.info("XPath [" + xpathExp + "], nr of matches : " + nodeList.getLength());
+		xpathNodeListResults.put( xpathExp, new XPathCacheObject<NodeList>( message.hashCode(), nodeList ) );
+		return nodeList;
+	}
+    
     /**
-	 * Uses XPath to look for the occurence of a certain tag, specific in the xpath expression.
+	 * Uses XPath to look for the occurence of a certain node, specified in the XPath expression.
+	 * This can be used to find out if the Message object contains the node specified by the XPath
+	 * expression. 
+	 * 
+	 * 
+	 * @param message - 
+	 * 				the ESB Message which body content will be used.
+	 * @param xpathExp -
+	 * 				XPath expression to find a node.
+	 * @return true 
+	 * 				if the node is found and false in all other cases.
+	 * @throws XPathExpressionException
+	 * 				represents an error in an XPath expression
+	 */
+	public static boolean xmlContentMatches(final Message message, final String xpathExp) throws XPathExpressionException 
+	{
+        return selectAsNode( message, xpathExp ) != null ;
+	}
+	
+    /**
+	 * Uses XPath to look for any occurence of a certain tag, specific in the xpath expression.
+	 * This can be used to find out if the Message object contains the node specified by the XPath
+	 * Note, that this method cannot be used with a boolean expression, use {@link #selectAsBoolean(Message, String)}
+	 * for that.
 	 *
-	 * @param message - the ESB Message which body content will be used.
-	 * @param xpathExp - XPath expression to find a node.
-	 * @param value - used to compare against the result found using the XPath expression.
-	 * @return true if equal, false in all other cases.
+	 * @param message - 
+	 * 				the ESB Message which body content will be used.
+	 * @param xpathExp -
+	 * 				XPath expression to find a node.
+	 * @return true 
+	 * 				if one or more nodes are found and false in all other cases.
 	 * @throws XPathExpressionException
+	 * 				represents an error in an XPath expression
 	 */
-	public static boolean xmlContentEquals(Message message, String xpathExp, String value) throws XPathExpressionException
+	public static boolean xmlContentExists(final Message message, final String xpathExp) throws XPathExpressionException
 	{
-		if (log.isDebugEnabled()) {
-			log.debug("Trying to match xpath: '" + xpathExp +  "' in message=" + message.getBody().get());
-		}
-		XPath xpath = xpf.newXPath();
-        InputSource inputSource = getInputSource(message);
-		String nodeValue = (String) xpath.evaluate(xpathExp, inputSource, XPathConstants.STRING);
-		if (log.isDebugEnabled()) {
-			log.debug("Found nodeValue=" + nodeValue + " which is matched to given value=" + value);
-		}
-		return value.equals(nodeValue);
+		NodeList nodeList = selectAsNodeList( message, xpathExp );
+		return nodeList == null ? false : nodeList.getLength() > 0 ;
 	}
-
+	
+	/**
+	 * Uses XPath to look for the occurence of a certain tag, specific in the xpath expression.
+	 * </p>
+	 * Note that {@link #selectAsBoolean(Message, String)} can be used instead of this method
+	 * and the XPath equality operator can be used in the XPath expression:
+	 * <br> 
+	 * <pre>{@code
+	 * String xpathExp = "/Order/OrderLines/OrderLine/Product/@productId = 364";
+	 * }</pre>
+	 * <br> 
+	 * 
+	 * @param message - 
+	 * 			the ESB Message which body content will be used.
+	 * @param xpathExp -
+	 * 			XPath expression to find a node.
+	 * @return true -
+	 * 			if the node is found and false in all other cases.
+	 * @throws XPathExpressionException
+	 * 			represents an error in an XPath expression
+	 */
+	public static boolean xmlContentEquals(final Message message, final String xpathExp, final String value ) throws XPathExpressionException
+	{
+		String xpathResult = selectAsString( message, xpathExp );
+		return xpathResult == null ? false : xpathResult.equals( value );
+	}
+	
     /**
 	 * Uses XPath to look for the occurence of a certain tag, specific in the xpath expression.
 	 *
-	 * @param message - the ESB Message which body content will be used.
-	 * @param xpathExp - XPath expression to find a node.
-	 * @param value - used to compare against the result found using the XPath expression.
-	 * @return true if node (returned by the xpath expression) is greater than the current value, false in all other cases.
+	 * @param message - 
+	 * 				the ESB Message which body content will be used.
+	 * @param xpathExp -
+	 * 				XPath expression to find a node.
+	 * @return true 
+	 * 				if the node is found and false in all other cases.
 	 * @throws XPathExpressionException
+	 * 				represents an error in an XPath expression
 	 */
-	public static boolean xmlContentGreaterThan(Message message, String xpathExp, String value) throws XPathExpressionException
+	public static boolean xmlContentGreaterThan( final Message message, final String xpathExp, final String value) throws XPathExpressionException
 	{
-		String nodeValue=null;
-		double doubleValue=0;
-		double doubleNodeValue=0;
+		final String xpathResult = (String) selectAsString( message, xpathExp );
 
-		if (log.isDebugEnabled()) {
-			log.debug("Trying to match xpath: '" + xpathExp +  "' in message=" + message.getBody().get());
-		}
-		XPath xpath = xpf.newXPath();
-		InputSource inputSource = getInputSource(message);	
-		nodeValue = (String) xpath.evaluate(xpathExp, inputSource, XPathConstants.STRING);if (log.isDebugEnabled()) {
-			log.debug("Found nodeValue=" + nodeValue + " which is matched to given value=" + value);
-		}
-		if (nodeValue!=null && !"".equals(nodeValue)) {
-
-			try {
-				doubleValue = Double.parseDouble(value);
-			} catch (NumberFormatException ne) {
-				log.equals("Could not parse value=" + doubleValue + " to double");
-			}
-			try {
-				doubleNodeValue = Double.parseDouble(nodeValue);
-			} catch (NumberFormatException ne) {
-				log.equals("Could not parse nodeValue=" + doubleNodeValue + " to double");
-			}
-			if (doubleNodeValue > doubleValue) {
-				return true;
-			}
-		}
-		return false;
+		if ( xpathResult != null && !"".equals( xpathResult ) ) 
+			return parseDouble( xpathResult ) > parseDouble( value );
+		else
+    		return false;
 	}
 
     /**
 	 * Uses XPath to look for the occurence of a certain tag, specific in the xpath expression.
 	 *
-	 * @param message - the ESB Message which body content will be used.
-	 * @param xpathExp - XPath expression to find a node.
-	 * @param value - used to compare against the result found using the XPath expression.
-	 * @return true if node (returned by the xpath expression) is less than the current value, false in all other cases.
+	 * @param message - 
+	 * 				the ESB Message which body content will be used.
+	 * @param xpathExp -
+	 * 				XPath expression to find a node.
+	 * @return true 
+	 * 				if the node is found and false in all other cases.
 	 * @throws XPathExpressionException
+	 * 				represents an error in an XPath expression
 	 */
-	public static boolean xmlContentLessThan(Message message, String xpathExp, String value) throws XPathExpressionException
+	public static boolean xmlContentLessThan( final Message message, final String xpathExp, final String value ) throws XPathExpressionException
 	{
-		String nodeValue=null;
-		double doubleValue=0;
-		double doubleNodeValue=0;
-
-		if (log.isDebugEnabled()) {
-			log.debug("Trying to match xpath: '" + xpathExp +  "' in message=" + message.getBody().get());
+		final String xpathResult = (String) selectAsString( message, xpathExp );
+			
+		if ( xpathResult != null && !"".equals( xpathResult ) ) 
+			return parseDouble( xpathResult ) < parseDouble( value );
+		else
+    		return false;
+	}
+	
+	/*
+	 * Checks if the cachedObject was non-null, and if so, checks the message hashCode against
+	 * the cachedObjects messageHashCode.
+	 */
+    private static <T> boolean cacheHit ( final XPathCacheObject<T> cachedObject, final Message message )
+    {
+		return cachedObject != null && cachedObject.getMessageHashCode() == message.hashCode();
+    }
+	
+	private static double parseDouble( final String string ) throws XPathExpressionException
+	{
+		try 
+		{
+			return Double.parseDouble( string );
+		} 
+		catch (NumberFormatException e) 
+		{
+			throw new XPathExpressionException("Could not parse value [" + string + "] to double" );
 		}
-		XPath xpath = xpf.newXPath();
-		InputSource inputSource = getInputSource(message);
-		nodeValue = (String) xpath.evaluate(xpathExp, inputSource, XPathConstants.STRING);if (log.isDebugEnabled()) {
-			log.debug("Found nodeValue=" + nodeValue + " which is matched to given value=" + value);
-		}
-		if (nodeValue!=null && !"".equals(nodeValue)) {
-
-			try {
-				doubleValue = Double.parseDouble(value);
-			} catch (NumberFormatException ne) {
-				log.equals("Could not parse value=" + doubleValue + " to double");
-			}
-			try {
-				doubleNodeValue = Double.parseDouble(nodeValue);
-			} catch (NumberFormatException ne) {
-				log.equals("Could not parse nodeValue=" + doubleNodeValue + " to double");
-			}
-			if (doubleNodeValue < doubleValue) {
-				return true;
-			}
-		}
-		return false;
 	}
 
-    private static InputSource getInputSource(Message message) throws XPathExpressionException {
+    private static InputSource getInputSource(Message message) throws XPathExpressionException 
+    {
         Object payload;
 
-        try {
+        try 
+        {
             payload = payloadProxy.getPayload(message);
-        } catch (MessageDeliverException e) {
+        } 
+        catch (MessageDeliverException e) 
+        {
             throw new XPathExpressionException(e);
         }
 
-        if(payload instanceof byte[]) {
+        if(payload instanceof byte[]) 
+        {
             return new InputSource(new ByteArrayInputStream((byte[]) payload));
-        } else if(payload instanceof String) {
+        } 
+        else if(payload instanceof String) 
+        {
             return new InputSource(new StringReader((String) payload));
-        } else {
+        } 
+        else 
+        {
             throw new XPathExpressionException("Unsupport expression input object type: " + payload.getClass().getName());
         }
     }
+    
+	/**
+	 * 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; 
+		}
+	}
 }
 	

Added: labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/routing/cbr/DslHelperUnitTest.java
===================================================================
--- labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/routing/cbr/DslHelperUnitTest.java	                        (rev 0)
+++ labs/jbossesb/trunk/product/services/jbrules/src/test/java/org/jboss/internal/soa/esb/services/routing/cbr/DslHelperUnitTest.java	2008-07-01 11:30:04 UTC (rev 20854)
@@ -0,0 +1,156 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.internal.soa.esb.services.routing.cbr;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.concurrent.TimeUnit;
+
+import javax.xml.xpath.XPathExpressionException;
+
+import org.jboss.internal.soa.esb.util.StreamUtils;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.message.format.MessageFactory;
+import org.jboss.soa.esb.util.ClassUtil;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Unit test for {@link DslHelper} 
+ * <p/> 
+ * 
+ * @author <a href="mailto:dbevenius at redhat.com">Daniel Bevenius</a>
+ *
+ */
+public class DslHelperUnitTest
+{
+	private static Message msg;
+
+	@Test
+	public void xmlContentExists() throws XPathExpressionException, UnsupportedEncodingException
+	{
+		assertTrue( DslHelper.xmlContentExists( msg, "//*[@productId = 299]" ) );
+		assertTrue( DslHelper.xmlContentExists( msg, "//*[@productId < 1000]" ) );
+		assertFalse( DslHelper.xmlContentExists( msg, "//*[@productId = 2299]" ) );
+	}
+	
+	@Test
+	public void xmlContentMatches() throws XPathExpressionException, UnsupportedEncodingException
+	{
+		assertTrue( DslHelper.xmlContentMatches( msg, "//*[@productId = 299]" ) );
+		assertTrue( DslHelper.xmlContentMatches( msg, "/Order/OrderLines/OrderLine/Product" ) );
+		assertFalse( DslHelper.xmlContentMatches( msg, "//*[@productId > 1299]" ) );
+	}
+	
+	@Test
+	public void selectAsBoolean() throws UnsupportedEncodingException, XPathExpressionException
+	{
+		assertTrue( DslHelper.selectAsBoolean( msg, "/Order/OrderLines/OrderLine/Product/@productId = 364" ) );
+		assertTrue( DslHelper.selectAsBoolean( msg, "//*[@productId = 299]" ) );
+		assertTrue( DslHelper.selectAsBoolean( msg, "//*[@productId < 1299]" ) );
+		assertFalse( DslHelper.selectAsBoolean( msg, "/Order/OrderLines/OrderLine/Product/@productId = 33" ) );
+	}
+	
+	@Test
+	public void selectAsNumber() throws UnsupportedEncodingException, XPathExpressionException
+	{
+		assertEquals ( 364, DslHelper.selectAsNumber( msg, "//Product/@productId" ).intValue() );
+	}
+	
+	@Test
+	public void selectAsString() throws UnsupportedEncodingException, XPathExpressionException
+	{
+		assertEquals ( "364", DslHelper.selectAsString( msg, "//Product/@productId" ) );
+	}
+	
+	@Test
+	public void selectAsNode() throws UnsupportedEncodingException, XPathExpressionException
+	{
+		assertEquals ( "productId",  DslHelper.selectAsNode( msg, "/Order/OrderLines/OrderLine/Product/@productId").getNodeName() );
+	}
+	
+	@Test
+	public void selectAsNodeList() throws UnsupportedEncodingException, XPathExpressionException
+	{
+		assertEquals ( 42, DslHelper.selectAsNodeList( msg, "//Product/@productId" ).getLength() );
+	}
+	
+	@Test
+	public void xmlContentEquals() throws UnsupportedEncodingException, XPathExpressionException
+	{
+		assertTrue( DslHelper.xmlContentEquals( msg, "/Order/OrderLines/OrderLine/Product/@productId", "364" ) );
+		assertFalse( DslHelper.xmlContentEquals( msg, "/Order/OrderLines/OrderLine/Product/@productId", "1" ) );
+	}
+	
+	@Test
+	public void xmlContentGreaterThan() throws UnsupportedEncodingException, XPathExpressionException
+	{
+		assertTrue( DslHelper.xmlContentGreaterThan( msg, "/Order/OrderLines/OrderLine/Product/@productId", "363" ) );
+		assertFalse( DslHelper.xmlContentGreaterThan( msg, "/Order/OrderLines/OrderLine/Product/@productId", "365" ) );
+		assertFalse( DslHelper.xmlContentGreaterThan( msg, "/Order/OrderLines/OrderLine/Product/@productId", "364" ) );
+	}
+	
+	@Test ( expected = XPathExpressionException.class )
+	public void shouldThrowIfArgumentIsNotAParsableDouble() throws UnsupportedEncodingException, XPathExpressionException
+	{
+		assertTrue( DslHelper.xmlContentGreaterThan( msg, "/Order/OrderLines/OrderLine/Product/@productId", "aaa" ) );
+		assertTrue( DslHelper.xmlContentLessThan( msg, "/Order/OrderLines/OrderLine/Product/@productId", "aaa" ) );
+	}
+	
+	@Test
+	public void xmlContentLessThan() throws UnsupportedEncodingException, XPathExpressionException
+	{
+		assertTrue( DslHelper.xmlContentLessThan( msg, "/Order/OrderLines/OrderLine/Product/@productId", "366" ) );
+		assertTrue( DslHelper.xmlContentLessThan( msg, "/Order/OrderLines/OrderLine/Product/@productId", "365" ) );
+		assertFalse( DslHelper.xmlContentLessThan( msg, "/Order/OrderLines/OrderLine/Product/@productId", "363" ) );
+	}
+	
+	@Test
+	public void xmlContentEqualsPerformanceTest() throws UnsupportedEncodingException, XPathExpressionException
+	{
+		int nrOfCalls = 4000;
+		
+		long startTime = System.nanoTime();
+		for ( int i = 0 ; i < nrOfCalls ; i++ )
+		{
+    		DslHelper.xmlContentEquals( msg, "/Order/OrderLines/OrderLine/Product/@productId", "364" );
+		}
+		long endTime = TimeUnit.NANOSECONDS.toMillis( System.nanoTime() - startTime );
+		System.out.println( "Timed " + nrOfCalls + " runs : " + endTime + "ms" );
+		assertTrue( nrOfCalls + " of calls should have taken less then 150ms", endTime < 150 );
+		
+	}
+	
+	@BeforeClass
+	public static void createMessage() throws UnsupportedEncodingException
+	{
+		msg = MessageFactory.getInstance().getMessage();
+		InputStream resourceAsStream = ClassUtil.getResourceAsStream( "/" + "5KB_message.xml", DslHelperUnitTest.class );
+		String contents = StreamUtils.readStreamString( resourceAsStream, "UTF-8" );
+		msg.getBody().add( contents );
+	}
+	
+}




More information about the jboss-svn-commits mailing list