You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2011/10/28 15:28:27 UTC

svn commit: r1190303 - in /camel/trunk: camel-core/src/main/java/org/apache/camel/builder/xml/XPathBuilder.java components/camel-saxon/src/test/java/org/apache/camel/builder/saxon/SaxonXPathSplitTest.java

Author: davsclaus
Date: Fri Oct 28 13:28:27 2011
New Revision: 1190303

URL: http://svn.apache.org/viewvc?rev=1190303&view=rev
Log:
CAMEL-4594: Fixed issue with using saxon for xpath splitting. Fixed issue with XPathFactory not thread safe. As well re-using default factory if possible.

Modified:
    camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/XPathBuilder.java
    camel/trunk/components/camel-saxon/src/test/java/org/apache/camel/builder/saxon/SaxonXPathSplitTest.java

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/XPathBuilder.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/XPathBuilder.java?rev=1190303&r1=1190302&r2=1190303&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/XPathBuilder.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/XPathBuilder.java Fri Oct 28 13:28:27 2011
@@ -44,7 +44,6 @@ import org.xml.sax.InputSource;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.Expression;
-import org.apache.camel.Message;
 import org.apache.camel.Predicate;
 import org.apache.camel.RuntimeExpressionException;
 import org.apache.camel.Service;
@@ -83,11 +82,12 @@ import static org.apache.camel.builder.x
  */
 public class XPathBuilder implements Expression, Predicate, NamespaceAware, Service {
     private static final transient Logger LOG = LoggerFactory.getLogger(XPathBuilder.class);
+    private static XPathFactory defaultXPathFactory;
+
     private final Queue<XPathExpression> pool = new ConcurrentLinkedQueue<XPathExpression>();
     private final String text;
     private final ThreadLocal<MessageVariableResolver> variableResolver = new ThreadLocal<MessageVariableResolver>();
     private final ThreadLocal<Exchange> exchange = new ThreadLocal<Exchange>();
-
     private XPathFactory xpathFactory;
     private Class<?> documentType = Document.class;
     // For some reason the default expression of "a/b" on a document such as
@@ -373,32 +373,14 @@ public class XPathBuilder implements Exp
     // Properties
     // -------------------------------------------------------------------------
     public XPathFactory getXPathFactory() throws XPathFactoryConfigurationException {
-        if (xpathFactory == null) {
-            if (objectModelUri != null) {
-                LOG.info("Using objectModelUri " + objectModelUri + " when creating XPathFactory");
-                xpathFactory = XPathFactory.newInstance(objectModelUri);
-                return xpathFactory;
-            }
-
-            // read system property and see if there is a factory set
-            Properties properties = System.getProperties();
-            for (Map.Entry prop : properties.entrySet()) {
-                String key = (String) prop.getKey();
-                if (key.startsWith(XPathFactory.DEFAULT_PROPERTY_NAME)) {
-                    String uri = ObjectHelper.after(key, ":");
-                    if (uri != null) {
-                        LOG.info("Using system property " + key + " with value: " + prop.getValue() + " when creating XPathFactory");
-                        xpathFactory = XPathFactory.newInstance(uri);
-                        return xpathFactory;
-                    }
-                }
-            }
+        if (xpathFactory != null) {
+            return xpathFactory;
+        }
 
-            LOG.debug("Creating default XPathFactory");
-            xpathFactory = XPathFactory.newInstance();
+        if (defaultXPathFactory == null) {
+            initDefaultXPathFactory();
         }
-        
-        return xpathFactory;
+        return defaultXPathFactory;
     }
 
     public void setXPathFactory(XPathFactory xpathFactory) {
@@ -699,7 +681,8 @@ public class XPathBuilder implements Exp
         return answer;
     }
 
-    protected XPathExpression createXPathExpression() throws XPathExpressionException, XPathFactoryConfigurationException {
+    protected synchronized XPathExpression createXPathExpression() throws XPathExpressionException, XPathFactoryConfigurationException {
+        // XPathFactory is not thread safe
         XPath xPath = getXPathFactory().newXPath();
 
         xPath.setNamespaceContext(getNamespaceContext());
@@ -850,12 +833,42 @@ public class XPathBuilder implements Exp
     }
 
     public void start() throws Exception {
+        if (xpathFactory == null) {
+            initDefaultXPathFactory();
+        }
     }
 
     public void stop() throws Exception {
         pool.clear();
     }
 
+    protected synchronized void initDefaultXPathFactory() throws XPathFactoryConfigurationException {
+        if (defaultXPathFactory == null) {
+            if (objectModelUri != null) {
+                defaultXPathFactory = XPathFactory.newInstance(objectModelUri);
+                LOG.info("Using objectModelUri " + objectModelUri + " when created XPathFactory {}", defaultXPathFactory);
+            }
+
+            if (defaultXPathFactory == null) {
+                // read system property and see if there is a factory set
+                Properties properties = System.getProperties();
+                for (Map.Entry prop : properties.entrySet()) {
+                    String key = (String) prop.getKey();
+                    if (key.startsWith(XPathFactory.DEFAULT_PROPERTY_NAME)) {
+                        String uri = ObjectHelper.after(key, ":");
+                        if (uri != null) {
+                            defaultXPathFactory = XPathFactory.newInstance(uri);
+                            LOG.info("Using system property {} with value {} when created XPathFactory {}", new Object[]{key, uri, defaultXPathFactory});
+                        }
+                    }
+                }
+            }
+
+            defaultXPathFactory = XPathFactory.newInstance();
+            LOG.info("Created default XPathFactory {}", defaultXPathFactory);
+        }
+    }
+
     /**
      * On completion class which cleanup thread local resources
      */

Modified: camel/trunk/components/camel-saxon/src/test/java/org/apache/camel/builder/saxon/SaxonXPathSplitTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-saxon/src/test/java/org/apache/camel/builder/saxon/SaxonXPathSplitTest.java?rev=1190303&r1=1190302&r2=1190303&view=diff
==============================================================================
--- camel/trunk/components/camel-saxon/src/test/java/org/apache/camel/builder/saxon/SaxonXPathSplitTest.java (original)
+++ camel/trunk/components/camel-saxon/src/test/java/org/apache/camel/builder/saxon/SaxonXPathSplitTest.java Fri Oct 28 13:28:27 2011
@@ -18,7 +18,6 @@ package org.apache.camel.builder.saxon;
 
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.test.junit4.CamelTestSupport;
-import org.junit.Ignore;
 import org.junit.Test;
 
 /**
@@ -27,7 +26,6 @@ import org.junit.Test;
 public class SaxonXPathSplitTest extends CamelTestSupport {
 
     @Test
-    @Ignore("This test fails")
     public void testSaxonXPathSplit() throws Exception {
         getMockEndpoint("mock:london").expectedMessageCount(1);
         getMockEndpoint("mock:paris").expectedMessageCount(1);