This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/master by this push:
new 3c11d29 CAMEL-15645: camel-saxon - Eager initialize and pre-compiled
expression/builder.
3c11d29 is described below
commit 3c11d296047ec21136172895bbe09ac8a430dea6
Author: Claus Ibsen <[email protected]>
AuthorDate: Tue Oct 6 14:14:58 2020 +0200
CAMEL-15645: camel-saxon - Eager initialize and pre-compiled
expression/builder.
---
.../camel/component/xquery/XQueryBuilder.java | 126 ++++++++++-----------
.../camel/component/xquery/XQueryEndpoint.java | 17 ++-
.../camel/language/xquery/XQueryLanguage.java | 1 -
.../camel/builder/saxon/ParameterDynamicTest.java | 16 ++-
.../org/apache/camel/builder/saxon/XQueryTest.java | 14 ++-
.../xquery/XQueryStripWhitespaceTest.java | 4 +
.../apache/camel/language/xpath/XPathLanguage.java | 1 -
7 files changed, 102 insertions(+), 77 deletions(-)
diff --git
a/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryBuilder.java
b/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryBuilder.java
index e18aa66..fd7f38a 100644
---
a/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryBuilder.java
+++
b/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryBuilder.java
@@ -29,7 +29,6 @@ import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
-import java.util.concurrent.atomic.AtomicBoolean;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
@@ -68,6 +67,7 @@ import org.apache.camel.Message;
import org.apache.camel.NoTypeConversionAvailableException;
import org.apache.camel.Predicate;
import org.apache.camel.Processor;
+import org.apache.camel.RuntimeCamelException;
import org.apache.camel.RuntimeExpressionException;
import org.apache.camel.spi.NamespaceAware;
import org.apache.camel.support.MessageHelper;
@@ -95,7 +95,6 @@ public abstract class XQueryBuilder implements Expression,
Predicate, NamespaceA
private ResultFormat resultsFormat = ResultFormat.DOM;
private Properties properties = new Properties();
private Class<?> resultType;
- private final AtomicBoolean initialized = new AtomicBoolean();
private boolean stripsAllWhiteSpace = true;
private ModuleURIResolver moduleURIResolver;
private boolean allowStAX;
@@ -117,6 +116,44 @@ public abstract class XQueryBuilder implements Expression,
Predicate, NamespaceA
@Override
public void init(CamelContext context) {
+ // must use synchronized for concurrency issues and only let it
initialize once
+ LOG.debug("Initializing XQueryBuilder {}", this);
+ if (configuration == null) {
+ configuration = new Configuration();
+
configuration.getParseOptions().setSpaceStrippingRule(isStripsAllWhiteSpace()
+ ? AllElementsSpaceStrippingRule.getInstance() :
IgnorableSpaceStrippingRule.getInstance());
+ LOG.debug("Created new Configuration {}", configuration);
+ } else {
+ LOG.debug("Using existing Configuration {}", configuration);
+ }
+
+ if (configurationProperties != null &&
!configurationProperties.isEmpty()) {
+ for (Map.Entry<String, Object> entry :
configurationProperties.entrySet()) {
+ configuration.setConfigurationProperty(entry.getKey(),
entry.getValue());
+ }
+ }
+ staticQueryContext = getConfiguration().newStaticQueryContext();
+ if (moduleURIResolver != null) {
+ staticQueryContext.setModuleURIResolver(moduleURIResolver);
+ }
+
+ Set<Map.Entry<String, String>> entries = namespacePrefixes.entrySet();
+ for (Map.Entry<String, String> entry : entries) {
+ String prefix = entry.getKey();
+ String uri = entry.getValue();
+ // skip invalid prefix or uri according to XQuery spec
+ boolean invalid = "xml".equals(prefix) || "xmlns".equals(prefix);
+ if (!invalid) {
+ LOG.debug("Declaring namespace [prefix: {}, uri: {}]", prefix,
uri);
+ staticQueryContext.declareNamespace(prefix, uri);
+ staticQueryContext.setInheritNamespaces(true);
+ }
+ }
+ try {
+ expression = createQueryExpression(staticQueryContext);
+ } catch (Exception e) {
+ throw RuntimeCamelException.wrapRuntimeException(e);
+ }
}
@Override
@@ -162,14 +199,12 @@ public abstract class XQueryBuilder implements
Expression, Predicate, NamespaceA
public List<?> evaluateAsList(Exchange exchange) throws Exception {
LOG.debug("evaluateAsList: {} for exchange: {}", expression, exchange);
- initialize(exchange);
return getExpression().evaluate(createDynamicContext(exchange));
}
public Object evaluateAsStringSource(Exchange exchange) throws Exception {
LOG.debug("evaluateAsString: {} for exchange: {}", expression,
exchange);
- initialize(exchange);
String text = evaluateAsString(exchange);
return new StringSource(text);
@@ -177,7 +212,6 @@ public abstract class XQueryBuilder implements Expression,
Predicate, NamespaceA
public Object evaluateAsBytesSource(Exchange exchange) throws Exception {
LOG.debug("evaluateAsBytesSource: {} for exchange: {}", expression,
exchange);
- initialize(exchange);
byte[] bytes = evaluateAsBytes(exchange);
return new BytesSource(bytes);
@@ -185,7 +219,6 @@ public abstract class XQueryBuilder implements Expression,
Predicate, NamespaceA
public Node evaluateAsDOM(Exchange exchange) throws Exception {
LOG.debug("evaluateAsDOM: {} for exchange: {}", expression, exchange);
- initialize(exchange);
DOMResult result = new DOMResult();
DynamicQueryContext context = createDynamicContext(exchange);
@@ -196,7 +229,6 @@ public abstract class XQueryBuilder implements Expression,
Predicate, NamespaceA
public byte[] evaluateAsBytes(Exchange exchange) throws Exception {
LOG.debug("evaluateAsBytes: {} for exchange: {}", expression,
exchange);
- initialize(exchange);
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
Result result = new StreamResult(buffer);
@@ -209,7 +241,6 @@ public abstract class XQueryBuilder implements Expression,
Predicate, NamespaceA
public String evaluateAsString(Exchange exchange) throws Exception {
LOG.debug("evaluateAsString: {} for exchange: {}", expression,
exchange);
- initialize(exchange);
StringWriter buffer = new StringWriter();
SequenceIterator iter =
getExpression().iterator(createDynamicContext(exchange));
@@ -250,6 +281,12 @@ public abstract class XQueryBuilder implements Expression,
Predicate, NamespaceA
// Static helper methods
//-------------------------------------------------------------------------
+
+ /**
+ * Creates a new {@link XQueryBuilder} to evaluate against the expression
from the string.
+ *
+ * Important: The builder must be initialized before use.
+ */
public static XQueryBuilder xquery(final String queryText) {
return new XQueryBuilder() {
protected XQueryExpression
createQueryExpression(StaticQueryContext staticQueryContext)
@@ -259,6 +296,11 @@ public abstract class XQueryBuilder implements Expression,
Predicate, NamespaceA
};
}
+ /**
+ * Creates a new {@link XQueryBuilder} to evaluate against the expression
loaded from the reader.
+ *
+ * Important: The builder must be initialized before use.
+ */
public static XQueryBuilder xquery(final Reader reader) {
return new XQueryBuilder() {
protected XQueryExpression
createQueryExpression(StaticQueryContext staticQueryContext)
@@ -272,6 +314,11 @@ public abstract class XQueryBuilder implements Expression,
Predicate, NamespaceA
};
}
+ /**
+ * Creates a new {@link XQueryBuilder} to evaluate against the expression
loaded from the input stream.
+ *
+ * Important: The builder must be initialized before use.
+ */
public static XQueryBuilder xquery(final InputStream in, final String
characterSet) {
return new XQueryBuilder() {
protected XQueryExpression
createQueryExpression(StaticQueryContext staticQueryContext)
@@ -285,6 +332,11 @@ public abstract class XQueryBuilder implements Expression,
Predicate, NamespaceA
};
}
+ /**
+ * Creates a new {@link XQueryBuilder} to evaluate against the expression
loaded from the input stream.
+ *
+ * Important: The builder must be initialized before use.
+ */
public static XQueryBuilder xquery(final InputStream in) {
return new XQueryBuilder() {
protected XQueryExpression
createQueryExpression(StaticQueryContext staticQueryContext)
@@ -307,8 +359,6 @@ public abstract class XQueryBuilder implements Expression,
Predicate, NamespaceA
public XQueryBuilder namespace(String prefix, String uri) {
namespacePrefixes.put(prefix, uri);
- // more namespace, we must re initialize
- initialized.set(false);
return this;
}
@@ -381,8 +431,6 @@ public abstract class XQueryBuilder implements Expression,
Predicate, NamespaceA
@Override
public void setNamespaces(Map<String, String> namespaces) {
namespacePrefixes.putAll(namespaces);
- // more namespace, we must re initialize
- initialized.set(false);
}
@Override
@@ -400,8 +448,6 @@ public abstract class XQueryBuilder implements Expression,
Predicate, NamespaceA
public void setConfiguration(Configuration configuration) {
this.configuration = configuration;
- // change configuration, we must re initialize
- initialized.set(false);
}
public Map<String, Object> getConfigurationProperties() {
@@ -410,8 +456,6 @@ public abstract class XQueryBuilder implements Expression,
Predicate, NamespaceA
public void setConfigurationProperties(Map<String, Object>
configurationProperties) {
this.configurationProperties = Collections.unmodifiableMap(new
HashMap<>(configurationProperties));
- // change configuration, we must re initialize
- initialized.set(false);
}
public StaticQueryContext getStaticQueryContext() {
@@ -420,8 +464,6 @@ public abstract class XQueryBuilder implements Expression,
Predicate, NamespaceA
public void setStaticQueryContext(StaticQueryContext staticQueryContext) {
this.staticQueryContext = staticQueryContext;
- // change context, we must re initialize
- initialized.set(false);
}
public Map<String, Object> getParameters() {
@@ -685,52 +727,4 @@ public abstract class XQueryBuilder implements Expression,
Predicate, NamespaceA
return ObjectHelper.matches(results);
}
- /**
- * Initializes this builder - <b>Must be invoked before evaluation</b>.
- */
- protected synchronized void initialize(Exchange exchange) throws
XPathException, IOException {
- // must use synchronized for concurrency issues and only let it
initialize once
- if (!initialized.get()) {
- LOG.debug("Initializing XQueryBuilder {}", this);
- if (configuration == null) {
- configuration = new Configuration();
-
configuration.getParseOptions().setSpaceStrippingRule(isStripsAllWhiteSpace()
- ? AllElementsSpaceStrippingRule.getInstance() :
IgnorableSpaceStrippingRule.getInstance());
- LOG.debug("Created new Configuration {}", configuration);
- } else {
- LOG.debug("Using existing Configuration {}", configuration);
- }
-
- if (configurationProperties != null &&
!configurationProperties.isEmpty()) {
- for (Map.Entry<String, Object> entry :
configurationProperties.entrySet()) {
- configuration.setConfigurationProperty(entry.getKey(),
entry.getValue());
- }
- }
- staticQueryContext = getConfiguration().newStaticQueryContext();
- if (moduleURIResolver != null) {
- staticQueryContext.setModuleURIResolver(moduleURIResolver);
- }
-
- Set<Map.Entry<String, String>> entries =
namespacePrefixes.entrySet();
- for (Map.Entry<String, String> entry : entries) {
- String prefix = entry.getKey();
- String uri = entry.getValue();
- // skip invalid prefix or uri according to XQuery spec
- boolean invalid = "xml".equals(prefix) ||
"xmlns".equals(prefix);
- if (!invalid) {
- LOG.debug("Declaring namespace [prefix: {}, uri: {}]",
prefix, uri);
- staticQueryContext.declareNamespace(prefix, uri);
- staticQueryContext.setInheritNamespaces(true);
- }
- }
- expression = createQueryExpression(staticQueryContext);
-
- initialized.set(true);
- }
-
- // let the configuration be accessible on the exchange as its shared
for this evaluation
- // and can be needed by 3rd party type converters or other situations
(camel-artixds)
- exchange.setProperty("CamelSaxonConfiguration", configuration);
- }
-
}
diff --git
a/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryEndpoint.java
b/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryEndpoint.java
index c7bfc49..dcc2a18 100644
---
a/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryEndpoint.java
+++
b/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryEndpoint.java
@@ -223,9 +223,23 @@ public class XQueryEndpoint extends ProcessorEndpoint {
}
@Override
+ protected void doInit() throws Exception {
+ super.doInit();
+ if (ResourceHelper.isClasspathUri(resourceUri)) {
+ doInitXQuery();
+ }
+ }
+
+ @Override
protected void doStart() throws Exception {
super.doStart();
+ if (!ResourceHelper.isClasspathUri(resourceUri)) {
+ doInitXQuery();
+ }
+ ServiceHelper.startService(xquery);
+ }
+ protected void doInitXQuery() throws Exception {
LOG.debug("{} using schema resource: {}", this, resourceUri);
InputStream is =
ResourceHelper.resolveMandatoryResourceAsInputStream(getCamelContext(),
resourceUri);
@@ -242,10 +256,9 @@ public class XQueryEndpoint extends ProcessorEndpoint {
this.xquery.setAllowStAX(isAllowStAX());
this.xquery.setHeaderName(getHeaderName());
this.xquery.setModuleURIResolver(getModuleURIResolver());
+ this.xquery.init(getCamelContext());
setProcessor(xquery);
-
- ServiceHelper.startService(xquery);
}
@Override
diff --git
a/components/camel-saxon/src/main/java/org/apache/camel/language/xquery/XQueryLanguage.java
b/components/camel-saxon/src/main/java/org/apache/camel/language/xquery/XQueryLanguage.java
index 30e6814..8b9b017 100644
---
a/components/camel-saxon/src/main/java/org/apache/camel/language/xquery/XQueryLanguage.java
+++
b/components/camel-saxon/src/main/java/org/apache/camel/language/xquery/XQueryLanguage.java
@@ -91,7 +91,6 @@ public class XQueryLanguage extends LanguageSupport {
if (headerName != null) {
builder.setHeaderName(headerName);
}
- builder.init(getCamelContext());
}
}
diff --git
a/components/camel-saxon/src/test/java/org/apache/camel/builder/saxon/ParameterDynamicTest.java
b/components/camel-saxon/src/test/java/org/apache/camel/builder/saxon/ParameterDynamicTest.java
index 9788114..7e6957c 100644
---
a/components/camel-saxon/src/test/java/org/apache/camel/builder/saxon/ParameterDynamicTest.java
+++
b/components/camel-saxon/src/test/java/org/apache/camel/builder/saxon/ParameterDynamicTest.java
@@ -23,7 +23,9 @@ import net.sf.saxon.query.DynamicQueryContext;
import net.sf.saxon.query.XQueryExpression;
import net.sf.saxon.value.BooleanValue;
import net.sf.saxon.value.ObjectValue;
+import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
+import org.apache.camel.component.xquery.XQueryBuilder;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.support.DefaultExchange;
import org.junit.jupiter.api.BeforeEach;
@@ -82,15 +84,23 @@ public class ParameterDynamicTest {
@Test
public void testXQueryBuilder() throws Exception {
- Exchange exchange = new DefaultExchange(new DefaultCamelContext());
+ CamelContext context = new DefaultCamelContext();
+ context.start();
+
+ Exchange exchange = new DefaultExchange(context);
exchange.getIn().setBody("<foo><bar>abc_def_ghi</bar></foo>");
exchange.setProperty("extParam", true);
- Object result = xquery(TEST_QUERY).asString().evaluate(exchange,
boolean.class);
+ XQueryBuilder xquery = xquery(TEST_QUERY);
+ xquery.init(context);
+
+ Object result = xquery.asString().evaluate(exchange, boolean.class);
assertEquals(true, result);
exchange.setProperty("extParam", false);
- result = xquery(TEST_QUERY).asString().evaluate(exchange,
boolean.class);
+ result = xquery.evaluate(exchange, boolean.class);
assertEquals(false, result);
+
+ context.stop();
}
}
diff --git
a/components/camel-saxon/src/test/java/org/apache/camel/builder/saxon/XQueryTest.java
b/components/camel-saxon/src/test/java/org/apache/camel/builder/saxon/XQueryTest.java
index bfdd778..7592d59 100644
---
a/components/camel-saxon/src/test/java/org/apache/camel/builder/saxon/XQueryTest.java
+++
b/components/camel-saxon/src/test/java/org/apache/camel/builder/saxon/XQueryTest.java
@@ -18,7 +18,9 @@ package org.apache.camel.builder.saxon;
import org.w3c.dom.Document;
+import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
+import org.apache.camel.component.xquery.XQueryBuilder;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.support.DefaultExchange;
import org.junit.jupiter.api.Test;
@@ -31,18 +33,22 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
public class XQueryTest {
@Test
public void testXQuery() throws Exception {
- Exchange exchange = new DefaultExchange(new DefaultCamelContext());
+ CamelContext context = new DefaultCamelContext();
+ context.start();
+
+ Exchange exchange = new DefaultExchange(context);
exchange.getIn().setBody(
"<products><product type='food'><pizza/></product><product
type='beer'><stella/></product></products>");
- Object result = xquery(".//product[@type =
'beer']/*").evaluate(exchange, Object.class);
+ XQueryBuilder xquery = xquery(".//product[@type = 'beer']/*");
+ xquery.init(context);
+ Object result = xquery.evaluate(exchange, Object.class);
assertTrue(result instanceof Document, "Should be a document but was:
" + className(result));
-
Document doc = (Document) result;
assertEquals("stella", doc.getDocumentElement().getLocalName(), "Root
document element name");
- result = xquery(".//product[@type = 'beer']/*").evaluate(exchange,
String.class);
+ result = xquery.evaluate(exchange, String.class);
assertEquals("<stella/>", result, "Get a wrong result");
}
}
diff --git
a/components/camel-saxon/src/test/java/org/apache/camel/component/xquery/XQueryStripWhitespaceTest.java
b/components/camel-saxon/src/test/java/org/apache/camel/component/xquery/XQueryStripWhitespaceTest.java
index 970559a..c9cd016 100644
---
a/components/camel-saxon/src/test/java/org/apache/camel/component/xquery/XQueryStripWhitespaceTest.java
+++
b/components/camel-saxon/src/test/java/org/apache/camel/component/xquery/XQueryStripWhitespaceTest.java
@@ -39,6 +39,8 @@ public class XQueryStripWhitespaceTest extends
CamelTestSupport {
exchange.getIn().setBody(new File("src/test/resources/payload.xml"));
XQueryBuilder xquery =
XQueryBuilder.xquery("//payload").asString().stripsAllWhiteSpace();
+ xquery.init(context);
+
Object result = xquery.evaluate(exchange);
assertNotNull(result);
assertEquals("012010-10-04JohnDoeThis is a test reportserver is
[email protected]", result);
@@ -50,6 +52,8 @@ public class XQueryStripWhitespaceTest extends
CamelTestSupport {
exchange.getIn().setBody(new File("src/test/resources/payload.xml"));
XQueryBuilder xquery =
XQueryBuilder.xquery("//payload").asString().stripsIgnorableWhiteSpace();
+ xquery.init(context);
+
String result = xquery.evaluate(exchange, String.class);
assertNotNull(result);
diff --git
a/components/camel-xpath/src/main/java/org/apache/camel/language/xpath/XPathLanguage.java
b/components/camel-xpath/src/main/java/org/apache/camel/language/xpath/XPathLanguage.java
index 3b9deb0..315a9bf 100644
---
a/components/camel-xpath/src/main/java/org/apache/camel/language/xpath/XPathLanguage.java
+++
b/components/camel-xpath/src/main/java/org/apache/camel/language/xpath/XPathLanguage.java
@@ -198,7 +198,6 @@ public class XPathLanguage extends LanguageSupport {
builder.setObjectModelUri(objectModelUri);
}
}
- builder.init(getCamelContext());
}
}