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/26 09:24:17 UTC
svn commit: r1189052 - in /camel/branches/camel-2.8.x: ./
components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryBuilder.java
components/camel-saxon/src/test/java/org/apache/camel/component/xquery/XQueryFromFileExceptionTest.java
Author: davsclaus
Date: Wed Oct 26 07:24:16 2011
New Revision: 1189052
URL: http://svn.apache.org/viewvc?rev=1189052&view=rev
Log:
CAMEL-4584: Added option allowStAX to xquery component. Fixed issue with not closing underlying input stream if used.
Added:
camel/branches/camel-2.8.x/components/camel-saxon/src/test/java/org/apache/camel/component/xquery/XQueryFromFileExceptionTest.java
- copied unchanged from r1188879, camel/trunk/components/camel-saxon/src/test/java/org/apache/camel/component/xquery/XQueryFromFileExceptionTest.java
Modified:
camel/branches/camel-2.8.x/ (props changed)
camel/branches/camel-2.8.x/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryBuilder.java
Propchange: camel/branches/camel-2.8.x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Oct 26 07:24:16 2011
@@ -1 +1 @@
-/camel/trunk:1186106,1186625,1186772,1187221,1187485,1187882,1187893,1188070-1188085,1188642,1188674
+/camel/trunk:1186106,1186625,1186772,1187221,1187485,1187882,1187893,1188070-1188085,1188642,1188674,1188879
Propchange: camel/branches/camel-2.8.x/
------------------------------------------------------------------------------
Binary property 'svnmerge-integrated' - no diff available.
Modified: camel/branches/camel-2.8.x/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryBuilder.java
URL: http://svn.apache.org/viewvc/camel/branches/camel-2.8.x/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryBuilder.java?rev=1189052&r1=1189051&r2=1189052&view=diff
==============================================================================
--- camel/branches/camel-2.8.x/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryBuilder.java (original)
+++ camel/branches/camel-2.8.x/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryBuilder.java Wed Oct 26 07:24:16 2011
@@ -34,8 +34,13 @@ import java.util.concurrent.atomic.Atomi
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+import org.w3c.dom.Document;
import org.w3c.dom.Node;
import net.sf.saxon.Configuration;
@@ -63,6 +68,7 @@ import org.apache.camel.converter.jaxp.B
import org.apache.camel.converter.jaxp.StringSource;
import org.apache.camel.converter.jaxp.XmlConverter;
import org.apache.camel.spi.NamespaceAware;
+import org.apache.camel.util.IOHelper;
import org.apache.camel.util.MessageHelper;
import org.apache.camel.util.ObjectHelper;
import org.slf4j.Logger;
@@ -89,6 +95,7 @@ public abstract class XQueryBuilder impl
private final AtomicBoolean initialized = new AtomicBoolean(false);
private boolean stripsAllWhiteSpace = true;
private ModuleURIResolver moduleURIResolver;
+ private boolean allowStAX;
@Override
public String toString() {
@@ -180,8 +187,10 @@ public abstract class XQueryBuilder impl
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
Result result = new StreamResult(buffer);
getExpression().pull(createDynamicContext(exchange), result, properties);
- byte[] bytes = buffer.toByteArray();
- return bytes;
+
+ byte[] answer = buffer.toByteArray();
+ buffer.close();
+ return answer;
}
public String evaluateAsString(Exchange exchange) throws Exception {
@@ -192,7 +201,10 @@ public abstract class XQueryBuilder impl
for (Item item = iter.next(); item != null; item = iter.next()) {
buffer.append(item.getStringValueCS());
}
- return buffer.toString();
+
+ String answer = buffer.toString();
+ buffer.close();
+ return answer;
}
public boolean matches(Exchange exchange) {
@@ -327,6 +339,16 @@ public abstract class XQueryBuilder impl
return this;
}
+ /**
+ * Enables to allow using StAX.
+ * <p/>
+ * When enabled StAX is preferred as the first choice as {@link Source}.
+ */
+ public XQueryBuilder allowStAX() {
+ setAllowStAX(true);
+ return this;
+ }
+
// Properties
// -------------------------------------------------------------------------
@@ -411,6 +433,14 @@ public abstract class XQueryBuilder impl
this.stripsAllWhiteSpace = stripsAllWhiteSpace;
}
+ public boolean isAllowStAX() {
+ return allowStAX;
+ }
+
+ public void setAllowStAX(boolean allowStAX) {
+ this.allowStAX = allowStAX;
+ }
+
// Implementation methods
// -------------------------------------------------------------------------
@@ -433,35 +463,32 @@ public abstract class XQueryBuilder impl
if (item != null) {
dynamicQueryContext.setContextItem(item);
} else {
- Source source = in.getBody(Source.class);
- if (source == null) {
- Object body = in.getBody();
-
- // lets try coerce some common types into something JAXP can deal with
- if (body instanceof GenericFile) {
- // special for files so we can work with them out of the box
- InputStream is = exchange.getContext().getTypeConverter().convertTo(InputStream.class, body);
- source = converter.toDOMSource(is);
- } else if (body instanceof BeanInvocation) {
- // if its a null bean invocation then handle that
- BeanInvocation bi = exchange.getContext().getTypeConverter().convertTo(BeanInvocation.class, body);
- if (bi.getArgs() != null && bi.getArgs().length == 1 && bi.getArgs()[0] == null) {
- // its a null argument from the bean invocation so use null as answer
- source = null;
- }
- } else if (body instanceof String) {
- source = converter.toDOMSource(body.toString());
+ Object body = in.getBody();
+
+ // the underlying input stream, which we need to close to avoid locking files or other resources
+ InputStream is = null;
+ try {
+ Source source;
+ // only convert to input stream if really needed
+ if (isInputStreamNeeded(exchange)) {
+ is = exchange.getIn().getBody(InputStream.class);
+ source = getSource(exchange, is);
} else {
- // try some of Camels type converters
- InputStream is = in.getBody(InputStream.class);
- if (is != null) {
+ source = getSource(exchange, body);
+ }
+
+ // there is a couple of special types we need to check
+ if (source == null) {
+ if (body instanceof GenericFile) {
+ // special for files so we can work with them out of the box
+ is = exchange.getContext().getTypeConverter().convertTo(InputStream.class, body);
source = converter.toDOMSource(is);
- }
- // fallback and use String
- if (source == null) {
- String s = in.getBody(String.class);
- if (s != null) {
- source = converter.toDOMSource(s);
+ } else if (body instanceof BeanInvocation) {
+ // if its a null bean invocation then handle that
+ BeanInvocation bi = exchange.getContext().getTypeConverter().convertTo(BeanInvocation.class, body);
+ if (bi.getArgs() != null && bi.getArgs().length == 1 && bi.getArgs()[0] == null) {
+ // its a null argument from the bean invocation so use null as answer
+ source = null;
}
}
}
@@ -470,9 +497,13 @@ public abstract class XQueryBuilder impl
// indicate it was not possible to convert to a Source type
throw new NoTypeConversionAvailableException(body, Source.class);
}
+
+ DocumentInfo doc = getStaticQueryContext().buildDocument(source);
+ dynamicQueryContext.setContextItem(doc);
+ } finally {
+ // can deal if is is null
+ IOHelper.close(is);
}
- DocumentInfo doc = getStaticQueryContext().buildDocument(source);
- dynamicQueryContext.setContextItem(doc);
}
configureQuery(dynamicQueryContext, exchange);
@@ -482,6 +513,69 @@ public abstract class XQueryBuilder impl
}
/**
+ * Checks whether we need an {@link InputStream} to access the message body.
+ * <p/>
+ * Depending on the content in the message body, we may not need to convert
+ * to {@link InputStream}.
+ *
+ * @param exchange the current exchange
+ * @return <tt>true</tt> to convert to {@link InputStream} beforehand converting to {@link Source} afterwards.
+ */
+ protected boolean isInputStreamNeeded(Exchange exchange) {
+ Object body = exchange.getIn().getBody();
+ if (body == null) {
+ return false;
+ }
+
+ if (body instanceof Source) {
+ return false;
+ } else if (body instanceof String) {
+ return false;
+ } else if (body instanceof Document) {
+ return false;
+ }
+
+ // yes an input stream is needed
+ return true;
+ }
+
+ /**
+ * Converts the inbound body to a {@link Source}, if the body is <b>not</b> already a {@link Source}.
+ * <p/>
+ * This implementation will prefer to source in the following order:
+ * <ul>
+ * <li>StAX - Is StAX is allowed</li>
+ * <li>SAX - SAX as 2nd choice</li>
+ * <li>Stream - Stream as 3rd choice</li>
+ * <li>DOM - DOM as 4th choice</li>
+ * </ul>
+ */
+ protected Source getSource(Exchange exchange, Object body) {
+ // body may already be a source
+ if (body instanceof Source) {
+ return (Source) body;
+ }
+
+ Source source = null;
+ if (isAllowStAX()) {
+ source = exchange.getContext().getTypeConverter().convertTo(StAXSource.class, exchange, body);
+ }
+ if (source == null) {
+ // then try SAX
+ source = exchange.getContext().getTypeConverter().convertTo(SAXSource.class, exchange, body);
+ }
+ if (source == null) {
+ // then try stream
+ source = exchange.getContext().getTypeConverter().convertTo(StreamSource.class, exchange, body);
+ }
+ if (source == null) {
+ // and fallback to DOM
+ source = exchange.getContext().getTypeConverter().convertTo(DOMSource.class, exchange, body);
+ }
+ return source;
+ }
+
+ /**
* Configures the dynamic context with exchange specific parameters
*/
protected void configureQuery(DynamicQueryContext dynamicQueryContext, Exchange exchange)