Skip to content

Commit

Permalink
CAMEL-4594: Fixed issue with using saxon for xpath splitting. Fixed i…
Browse files Browse the repository at this point in the history
…ssue with XPathFactory not thread safe. As well re-using default factory if possible.

git-svn-id: https://svn.apache.org/repos/asf/camel/trunk@1190303 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
davsclaus committed Oct 28, 2011
1 parent 382c6db commit 53d17b2
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
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;
Expand Down Expand Up @@ -83,11 +82,12 @@
*/
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
Expand Down Expand Up @@ -373,32 +373,14 @@ public XPathBuilder factory(XPathFactory xpathFactory) {
// 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) {
Expand Down Expand Up @@ -699,7 +681,8 @@ protected Object doInEvaluateAs(XPathExpression xpathExpression, Exchange exchan
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());
Expand Down Expand Up @@ -850,12 +833,42 @@ private MessageVariableResolver getVariableResolver() {
}

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
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.junit.Ignore;
import org.junit.Test;

/**
Expand All @@ -27,7 +26,6 @@
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);
Expand Down

0 comments on commit 53d17b2

Please sign in to comment.