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 2015/01/17 12:05:41 UTC
camel git commit: CAMEL-8250: camel-saxon add type converter for
Saxon types. Thanks to Stephan Siano for the patch.
Repository: camel
Updated Branches:
refs/heads/master 059aaf024 -> 94d527783
CAMEL-8250: camel-saxon add type converter for Saxon types. Thanks to Stephan Siano for the patch.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/94d52778
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/94d52778
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/94d52778
Branch: refs/heads/master
Commit: 94d527783719f495c05df4caea7dcece2113d065
Parents: 059aaf0
Author: Claus Ibsen <da...@apache.org>
Authored: Sat Jan 17 11:50:03 2015 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Sat Jan 17 11:50:03 2015 +0100
----------------------------------------------------------------------
components/camel-saxon/pom.xml | 3 +-
.../camel/converter/saxon/SaxonConverter.java | 132 +++++++++++++++++
.../services/org/apache/camel/TypeConverter | 18 +++
.../converter/saxon/SaxonConverterTest.java | 143 +++++++++++++++++++
4 files changed, 295 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/94d52778/components/camel-saxon/pom.xml
----------------------------------------------------------------------
diff --git a/components/camel-saxon/pom.xml b/components/camel-saxon/pom.xml
index d2da420..bc0cc9f 100644
--- a/components/camel-saxon/pom.xml
+++ b/components/camel-saxon/pom.xml
@@ -32,7 +32,8 @@
<properties>
<camel.osgi.export.pkg>
org.apache.camel.component.xquery.*,
- org.apache.camel.language.xquery.*
+ org.apache.camel.language.xquery.*,
+ org.apache.camel.converter.saxon.*
</camel.osgi.export.pkg>
<camel.osgi.export.service>
org.apache.camel.spi.ComponentResolver;component=xquery,
http://git-wip-us.apache.org/repos/asf/camel/blob/94d52778/components/camel-saxon/src/main/java/org/apache/camel/converter/saxon/SaxonConverter.java
----------------------------------------------------------------------
diff --git a/components/camel-saxon/src/main/java/org/apache/camel/converter/saxon/SaxonConverter.java b/components/camel-saxon/src/main/java/org/apache/camel/converter/saxon/SaxonConverter.java
new file mode 100644
index 0000000..5e18e64
--- /dev/null
+++ b/components/camel-saxon/src/main/java/org/apache/camel/converter/saxon/SaxonConverter.java
@@ -0,0 +1,132 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.converter.saxon;
+
+import java.util.LinkedList;
+import java.util.List;
+import javax.xml.transform.dom.DOMSource;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import net.sf.saxon.Configuration;
+import net.sf.saxon.dom.DOMNodeList;
+import net.sf.saxon.dom.NodeOverNodeInfo;
+import net.sf.saxon.om.DocumentInfo;
+import net.sf.saxon.om.NodeInfo;
+import net.sf.saxon.trans.XPathException;
+import net.sf.saxon.type.Type;
+
+import org.apache.camel.Converter;
+import org.apache.camel.Exchange;
+import org.apache.camel.FallbackConverter;
+import org.apache.camel.TypeConverter;
+import org.apache.camel.spi.TypeConverterRegistry;
+
+@Converter
+public final class SaxonConverter {
+
+ private SaxonConverter() {
+ }
+
+ @Converter
+ public static Document toDOMDocument(NodeInfo node) throws XPathException {
+ switch (node.getNodeKind()) {
+ case Type.DOCUMENT:
+ // DOCUMENT type nodes can be wrapped directly
+ return (Document) NodeOverNodeInfo.wrap(node);
+ case Type.ELEMENT:
+ // ELEMENT nodes need to build a new DocumentInfo before wrapping
+ Configuration config = node.getConfiguration();
+ DocumentInfo documentInfo = config.buildDocument(node);
+ return (Document) NodeOverNodeInfo.wrap(documentInfo);
+ default:
+ return null;
+ }
+ }
+
+ @Converter
+ public static Node toDOMNode(NodeInfo node) {
+ return NodeOverNodeInfo.wrap(node);
+ }
+
+ @Converter
+ public static DOMSource toDOMSourceFromNodeInfo(NodeInfo nodeInfo) {
+ return new DOMSource(toDOMNode(nodeInfo));
+ }
+
+ @Converter
+ public static NodeList toDOMNodeList(List<? extends NodeInfo> nodeList) {
+ List<Node> domNodeList = new LinkedList<Node>();
+ if (nodeList != null) {
+ for (NodeInfo ni : nodeList) {
+ domNodeList.add(NodeOverNodeInfo.wrap(ni));
+ }
+ }
+ return new DOMNodeList(domNodeList);
+ }
+
+ @FallbackConverter
+ public static <T> T convertTo(Class<T> type, Exchange exchange, Object value, TypeConverterRegistry registry) {
+ if (NodeInfo.class.isAssignableFrom(value.getClass())) {
+ // use a fallback type converter so we can convert the embedded body if the value is NodeInfo
+ NodeInfo ni = (NodeInfo) value;
+ // first try to find a Converter for Node
+ TypeConverter tc = registry.lookup(type, Node.class);
+ if (tc != null) {
+ Node node = NodeOverNodeInfo.wrap(ni);
+ return tc.convertTo(type, exchange, node);
+ }
+ // if this does not exist we can also try NodeList (there are some type converters for that) as
+ // the default Xerces Node implementation also implements NodeList.
+ tc = registry.lookup(type, NodeList.class);
+ if (tc != null) {
+ List<NodeInfo> nil = new LinkedList<NodeInfo>();
+ nil.add((NodeInfo) value);
+ return tc.convertTo(type, exchange, toDOMNodeList(nil));
+ }
+ } else if (List.class.isAssignableFrom(value.getClass())) {
+ TypeConverter tc = registry.lookup(type, NodeList.class);
+ if (tc != null) {
+ List<NodeInfo> lion = new LinkedList<NodeInfo>();
+ for (Object o : (List<?>) value) {
+ if (o instanceof NodeInfo) {
+ lion.add((NodeInfo) o);
+ }
+ }
+ if (lion.size() > 0) {
+ NodeList nl = toDOMNodeList(lion);
+ return tc.convertTo(type, exchange, nl);
+ }
+ }
+ } else if (NodeOverNodeInfo.class.isAssignableFrom(value.getClass())) {
+ // NodeOverNode info is a read-only Node implementation from Saxon. In contrast to the JDK
+ // com.sun.org.apache.xerces.internal.dom.NodeImpl class it does not implement NodeList, but
+ // many Camel type converters are based on that interface. Therefore we convert to NodeList and
+ // try type conversion in the fallback type converter.
+ TypeConverter tc = registry.lookup(type, NodeList.class);
+ if (tc != null) {
+ List<Node> domNodeList = new LinkedList<Node>();
+ domNodeList.add((NodeOverNodeInfo) value);
+ return tc.convertTo(type, exchange, new DOMNodeList(domNodeList));
+ }
+ }
+
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/94d52778/components/camel-saxon/src/main/resources/META-INF/services/org/apache/camel/TypeConverter
----------------------------------------------------------------------
diff --git a/components/camel-saxon/src/main/resources/META-INF/services/org/apache/camel/TypeConverter b/components/camel-saxon/src/main/resources/META-INF/services/org/apache/camel/TypeConverter
new file mode 100644
index 0000000..b666928
--- /dev/null
+++ b/components/camel-saxon/src/main/resources/META-INF/services/org/apache/camel/TypeConverter
@@ -0,0 +1,18 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+org.apache.camel.converter.saxon.SaxonConverter
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/94d52778/components/camel-saxon/src/test/java/org/apache/camel/converter/saxon/SaxonConverterTest.java
----------------------------------------------------------------------
diff --git a/components/camel-saxon/src/test/java/org/apache/camel/converter/saxon/SaxonConverterTest.java b/components/camel-saxon/src/test/java/org/apache/camel/converter/saxon/SaxonConverterTest.java
new file mode 100644
index 0000000..5509dc3
--- /dev/null
+++ b/components/camel-saxon/src/test/java/org/apache/camel/converter/saxon/SaxonConverterTest.java
@@ -0,0 +1,143 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.converter.saxon;
+
+import java.io.InputStream;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import net.sf.saxon.om.NodeInfo;
+import net.sf.saxon.trans.XPathException;
+import net.sf.saxon.xpath.XPathEvaluator;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.StringSource;
+import org.apache.camel.builder.xml.DefaultNamespaceContext;
+import org.apache.camel.impl.DefaultExchange;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SaxonConverterTest extends CamelTestSupport {
+ private static final String CONTENT = "<a xmlns=\"http://www.apache.org/test\"><b foo=\"bar\">test</b><c><d>foobar</d></c></a>";
+ private static final String CONTENT_B = "<b xmlns=\"http://www.apache.org/test\" foo=\"bar\">test</b>";
+ private static final NamespaceContext NS_CONTEXT = (new DefaultNamespaceContext()).add("ns1", "http://www.apache.org/test");
+
+ private Exchange exchange;
+ private XPathEvaluator evaluator;
+ private NodeInfo doc;
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ exchange = new DefaultExchange(context);
+ evaluator = new XPathEvaluator();
+ doc = evaluator.setSource(new StringSource(CONTENT));
+ }
+
+ @Test
+ public void convertToDOMSource() throws XPathException {
+ DOMSource source = context.getTypeConverter().convertTo(DOMSource.class, exchange, doc);
+ assertNotNull(source);
+ String string = context.getTypeConverter().convertTo(String.class, exchange, source);
+ assertEquals(CONTENT, string);
+ }
+
+ @Test
+ public void convertToDocument() throws XPathException {
+ Document document = context.getTypeConverter().convertTo(Document.class, exchange, doc);
+ assertNotNull(document);
+ String string = context.getTypeConverter().convertTo(String.class, exchange, document);
+ assertEquals(CONTENT, string);
+ }
+
+ @Test
+ public void convertSubNodeToDocument() throws XPathException, XPathExpressionException {
+ evaluator.setNamespaceContext(NS_CONTEXT);
+ Object nodeObj = evaluator.evaluate("/ns1:a/ns1:b", doc, XPathConstants.NODE);
+ assertNotNull(nodeObj);
+ Document document = context.getTypeConverter().convertTo(Document.class, exchange, nodeObj);
+ assertNotNull(document);
+ String string = context.getTypeConverter().convertTo(String.class, exchange, document);
+ assertEquals(CONTENT_B, string);
+ }
+
+ @Test
+ public void convertSubNodeSetToDocument() throws XPathException, XPathExpressionException {
+ evaluator.setNamespaceContext(NS_CONTEXT);
+ Object nodeObj = evaluator.evaluate("/ns1:a/ns1:b", doc, XPathConstants.NODESET);
+ assertNotNull(nodeObj);
+ Document document = context.getTypeConverter().convertTo(Document.class, exchange, nodeObj);
+ assertNotNull(document);
+ String string = context.getTypeConverter().convertTo(String.class, exchange, document);
+ assertEquals(CONTENT_B, string);
+ }
+
+ @Test
+ public void convertToNode() throws XPathException {
+ Node node = context.getTypeConverter().convertTo(Node.class, exchange, doc);
+ assertNotNull(node);
+ String string = context.getTypeConverter().convertTo(String.class, exchange, node);
+ assertEquals(CONTENT, string);
+ }
+
+ @Test
+ public void convertToNodeList() throws XPathException {
+ List<NodeInfo> nil = new LinkedList<NodeInfo>();
+ nil.add(doc);
+ NodeList nodeList = context.getTypeConverter().convertTo(NodeList.class, exchange, nil);
+ assertNotNull(nodeList);
+ assertEquals(1, nodeList.getLength());
+ String string = context.getTypeConverter().convertTo(String.class, exchange, nodeList);
+ assertEquals(CONTENT, string);
+ }
+
+ @Test
+ public void convertToInputStream() throws XPathException {
+ InputStream is = context.getTypeConverter().convertTo(InputStream.class, exchange, doc);
+ assertNotNull(is);
+ String string = context.getTypeConverter().convertTo(String.class, exchange, is);
+ assertEquals(CONTENT, string);
+ }
+
+ @Test
+ public void convertToByteArray() throws XPathException {
+ byte[] ba = context.getTypeConverter().convertTo(byte[].class, exchange, doc);
+ assertNotNull(ba);
+ String string = context.getTypeConverter().convertTo(String.class, exchange, ba);
+ assertEquals(CONTENT, string);
+ }
+
+ @Test
+ public void convertToNodeAndByteArray() throws XPathException {
+ Node node = context.getTypeConverter().convertTo(Node.class, exchange, doc);
+ assertNotNull(node);
+ byte[] ba = context.getTypeConverter().convertTo(byte[].class, exchange, node);
+ assertNotNull(ba);
+ String string = context.getTypeConverter().convertTo(String.class, exchange, ba);
+ assertEquals(CONTENT, string);
+ }
+}