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 2016/11/29 19:45:50 UTC
[4/4] camel git commit: CAMEL-10509: Handle namespaces on XML dump
and load operations
CAMEL-10509: Handle namespaces on XML dump and load operations
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/20a1b012
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/20a1b012
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/20a1b012
Branch: refs/heads/camel-2.18.x
Commit: 20a1b012bd03c58b702af615dde0b0198284fb52
Parents: 9b43224
Author: James Netherton <ja...@gmail.com>
Authored: Fri Nov 25 15:25:22 2016 +0000
Committer: Claus Ibsen <da...@apache.org>
Committed: Tue Nov 29 20:45:15 2016 +0100
----------------------------------------------------------------------
.../camel/converter/jaxp/XmlConverter.java | 18 ++
.../apache/camel/impl/DefaultCamelContext.java | 28 +--
.../org/apache/camel/model/ModelHelper.java | 209 ++++++++++++++-----
.../org/apache/camel/util/ExchangeHelper.java | 2 +-
.../properties/PropertiesRouteFromTest.java | 2 +-
.../camel/converter/jaxp/XmlConverterTest.java | 30 ++-
.../management/ManagedFromRestGetTest.java | 8 +-
.../ManagedFromRestPlaceholderTest.java | 8 +-
.../LoadRouteFromXmlWithNamespaceTest.java | 44 ++++
.../camel/util/CreateModelFromXmlTest.java | 123 +++++++++++
.../util/DumpModelAsXmlAggregateRouteTest.java | 2 +-
.../camel/util/DumpModelAsXmlNamespaceTest.java | 26 ++-
.../util/DumpModelAsXmlPlaceholdersTest.java | 7 +-
.../apache/camel/model/routeWithNamespace.xml | 32 +++
.../org/apache/camel/util/simpleRoute.xml | 30 +++
.../camel/util/simpleRouteWithNamespaces.xml | 30 +++
.../spring/DumpModelAsXmlPlaceholdersTest.java | 4 +-
17 files changed, 501 insertions(+), 102 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/20a1b012/camel-core/src/main/java/org/apache/camel/converter/jaxp/XmlConverter.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/converter/jaxp/XmlConverter.java b/camel-core/src/main/java/org/apache/camel/converter/jaxp/XmlConverter.java
index 70f4f87..539eee6 100644
--- a/camel-core/src/main/java/org/apache/camel/converter/jaxp/XmlConverter.java
+++ b/camel-core/src/main/java/org/apache/camel/converter/jaxp/XmlConverter.java
@@ -283,6 +283,24 @@ public class XmlConverter {
}
/**
+ * Converts the given Document to into text
+ * @param document The document to convert
+ * @param outputOptions The {@link OutputKeys} properties to control various aspects of the XML output
+ * @return The string representation of the document
+ * @throws TransformerException
+ */
+ public String toStringFromDocument(Document document, Properties outputOptions) throws TransformerException {
+ if (document == null) {
+ return null;
+ }
+
+ DOMSource source = new DOMSource(document);
+ StringWriter buffer = new StringWriter();
+ toResult(source, new StreamResult(buffer), outputOptions);
+ return buffer.toString();
+ }
+
+ /**
* Converts the source instance to a {@link DOMSource} or returns null if the conversion is not
* supported (making it easy to derive from this class to add new kinds of conversion).
* @deprecated will be removed in Camel 3.0. Use the method which has 2 parameters.
http://git-wip-us.apache.org/repos/asf/camel/blob/20a1b012/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java b/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
index 8cf7a78..8948e6c 100644
--- a/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
+++ b/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
@@ -97,6 +97,7 @@ import org.apache.camel.management.ManagementStrategyFactory;
import org.apache.camel.model.DataFormatDefinition;
import org.apache.camel.model.FromDefinition;
import org.apache.camel.model.ModelCamelContext;
+import org.apache.camel.model.ModelHelper;
import org.apache.camel.model.ProcessorDefinition;
import org.apache.camel.model.ProcessorDefinitionHelper;
import org.apache.camel.model.RouteDefinition;
@@ -873,32 +874,7 @@ public class DefaultCamelContext extends ServiceSupport implements ModelCamelCon
}
public synchronized RoutesDefinition loadRoutesDefinition(InputStream is) throws Exception {
- // load routes using JAXB
- if (jaxbContext == null) {
- // must use classloader from CamelContext to have JAXB working
- jaxbContext = getModelJAXBContextFactory().newJAXBContext();
- }
-
- Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
- Object result = unmarshaller.unmarshal(is);
-
- if (result == null) {
- throw new IOException("Cannot unmarshal to routes using JAXB from input stream: " + is);
- }
-
- // can either be routes or a single route
- RoutesDefinition answer;
- if (result instanceof RouteDefinition) {
- RouteDefinition route = (RouteDefinition) result;
- answer = new RoutesDefinition();
- answer.getRoutes().add(route);
- } else if (result instanceof RoutesDefinition) {
- answer = (RoutesDefinition) result;
- } else {
- throw new IllegalArgumentException("Unmarshalled object is an unsupported type: " + ObjectHelper.className(result) + " -> " + result);
- }
-
- return answer;
+ return ModelHelper.loadRoutesDefinition(this, is);
}
public synchronized RestsDefinition loadRestsDefinition(InputStream is) throws Exception {
http://git-wip-us.apache.org/repos/asf/camel/blob/20a1b012/camel-core/src/main/java/org/apache/camel/model/ModelHelper.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/ModelHelper.java b/camel-core/src/main/java/org/apache/camel/model/ModelHelper.java
index 3a1aa68..a1d30fd 100644
--- a/camel-core/src/main/java/org/apache/camel/model/ModelHelper.java
+++ b/camel-core/src/main/java/org/apache/camel/model/ModelHelper.java
@@ -17,23 +17,32 @@
package org.apache.camel.model;
import java.io.InputStream;
-import java.io.StringReader;
import java.io.StringWriter;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Properties;
+import javax.xml.bind.Binder;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
-import javax.xml.bind.Unmarshaller;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.TransformerException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
import org.apache.camel.CamelContext;
import org.apache.camel.Expression;
import org.apache.camel.NamedNode;
+import org.apache.camel.converter.jaxp.XmlConverter;
import org.apache.camel.model.language.ExpressionDefinition;
import org.apache.camel.spi.NamespaceAware;
-import org.apache.camel.util.IOHelper;
+import org.apache.camel.spi.TypeConverterRegistry;
+import org.apache.camel.util.ObjectHelper;
import static org.apache.camel.model.ProcessorDefinitionHelper.filterTypeInOutputs;
@@ -55,13 +64,7 @@ public final class ModelHelper {
* @throws JAXBException is throw if error marshalling to XML
*/
public static String dumpModelAsXml(CamelContext context, NamedNode definition) throws JAXBException {
- JAXBContext jaxbContext;
- if (context == null) {
- jaxbContext = createJAXBContext();
- } else {
- jaxbContext = context.getModelJAXBContextFactory().newJAXBContext();
- }
-
+ JAXBContext jaxbContext = getJAXBContext(context);
final Map<String, String> namespaces = new LinkedHashMap<>();
// gather all namespaces from the routes or route which is stored on the expression nodes
@@ -75,14 +78,32 @@ public final class ModelHelper {
extractNamespaces(route, namespaces);
}
- // TODO: add all namespaces to the root node so the xml output includes those
-
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
StringWriter buffer = new StringWriter();
marshaller.marshal(definition, buffer);
- return buffer.toString();
+ Document dom = context.getTypeConverter().convertTo(Document.class, buffer.toString());
+
+ // Add additional namespaces to the document root element
+ Element documentElement = dom.getDocumentElement();
+ for (String nsPrefix : namespaces.keySet()) {
+ documentElement.setAttribute("xmlns:" + nsPrefix, namespaces.get(nsPrefix));
+ }
+
+ // We invoke the type converter directly because we need to pass some custom XML output options
+ TypeConverterRegistry registry = context.getTypeConverterRegistry();
+ XmlConverter xmlConverter = registry.getInjector().newInstance(XmlConverter.class);
+
+ Properties outputProperties = new Properties();
+ outputProperties.put(OutputKeys.INDENT, "yes");
+ outputProperties.put(OutputKeys.STANDALONE, "yes");
+ try {
+ return xmlConverter.toStringFromDocument(dom, outputProperties);
+ } catch (TransformerException e) {
+ throw new IllegalStateException("Failed converting document object to string", e);
+ }
+
}
/**
@@ -95,28 +116,7 @@ public final class ModelHelper {
* @throws javax.xml.bind.JAXBException is thrown if error unmarshalling from xml to model
*/
public static <T extends NamedNode> T createModelFromXml(CamelContext context, String xml, Class<T> type) throws JAXBException {
- // TODO: support injecting namespaces into each namespace aware node
-
- JAXBContext jaxbContext;
- if (context == null) {
- jaxbContext = createJAXBContext();
- } else {
- jaxbContext = context.getModelJAXBContextFactory().newJAXBContext();
- }
-
- StringReader reader = new StringReader(xml);
- Object result;
- try {
- Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
- result = unmarshaller.unmarshal(reader);
- } finally {
- IOHelper.close(reader);
- }
-
- if (result == null) {
- throw new JAXBException("Cannot unmarshal to " + type + " using JAXB from XML: " + xml);
- }
- return type.cast(result);
+ return modelToXml(context, xml, type);
}
/**
@@ -129,18 +129,109 @@ public final class ModelHelper {
* @throws javax.xml.bind.JAXBException is thrown if error unmarshalling from xml to model
*/
public static <T extends NamedNode> T createModelFromXml(CamelContext context, InputStream stream, Class<T> type) throws JAXBException {
- // TODO: support injecting namespaces into each namespace aware node
+ return modelToXml(context, stream, type);
+ }
+
+ /**
+ * Marshal the xml to the model definition
+ *
+ * @param context the CamelContext, if <tt>null</tt> then {@link org.apache.camel.spi.ModelJAXBContextFactory} is not in use
+ * @param inputStream the xml stream
+ * @throws Exception is thrown if an error is encountered unmarshalling from xml to model
+ */
+ public static RoutesDefinition loadRoutesDefinition(CamelContext context, InputStream inputStream) throws Exception {
+ JAXBContext jaxbContext = getJAXBContext(context);
+
+ Map<String, String> namespaces = new LinkedHashMap<>();
+ Document dom = context.getTypeConverter().mandatoryConvertTo(Document.class, inputStream);
+ extractNamespaces(dom, namespaces);
+
+ Binder<Node> binder = jaxbContext.createBinder();
+ Object result = binder.unmarshal(dom);
+
+ if (result == null) {
+ throw new JAXBException("Cannot unmarshal to RoutesDefinition using JAXB");
+ }
+
+ // can either be routes or a single route
+ RoutesDefinition answer;
+ if (result instanceof RouteDefinition) {
+ RouteDefinition route = (RouteDefinition) result;
+ answer = new RoutesDefinition();
+ applyNamespaces(route, namespaces);
+ answer.getRoutes().add(route);
+ } else if (result instanceof RoutesDefinition) {
+ answer = (RoutesDefinition) result;
+ for (RouteDefinition route : answer.getRoutes()) {
+ applyNamespaces(route, namespaces);
+ }
+ } else {
+ throw new IllegalArgumentException("Unmarshalled object is an unsupported type: " + ObjectHelper.className(result) + " -> " + result);
+ }
+ return answer;
+ }
+
+ private static <T extends NamedNode> T modelToXml(CamelContext context, Object object, Class<T> type) throws JAXBException {
+ JAXBContext jaxbContext = getJAXBContext(context);
+
+ Map<String, String> namespaces = new LinkedHashMap<>();
+ Document dom = context.getTypeConverter().convertTo(Document.class, object);
+ extractNamespaces(dom, namespaces);
+
+ Binder<Node> binder = jaxbContext.createBinder();
+ Object result = binder.unmarshal(dom);
+
+ if (result == null) {
+ throw new JAXBException("Cannot unmarshal to " + type + " using JAXB");
+ }
+
+ // Restore namespaces to anything that's NamespaceAware
+ if (result instanceof RoutesDefinition) {
+ List<RouteDefinition> routes = ((RoutesDefinition) result).getRoutes();
+ for (RouteDefinition route : routes) {
+ applyNamespaces(route, namespaces);
+ }
+ } else if (result instanceof RouteDefinition) {
+ RouteDefinition route = (RouteDefinition) result;
+ applyNamespaces(route, namespaces);
+ }
+
+ return type.cast(result);
+ }
+
+ private static JAXBContext getJAXBContext(CamelContext context) throws JAXBException {
JAXBContext jaxbContext;
if (context == null) {
jaxbContext = createJAXBContext();
} else {
jaxbContext = context.getModelJAXBContextFactory().newJAXBContext();
}
+ return jaxbContext;
+ }
- Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
- Object result = unmarshaller.unmarshal(stream);
- return type.cast(result);
+ private static void applyNamespaces(RouteDefinition route, Map<String, String> namespaces) {
+ Iterator<ExpressionNode> it = filterTypeInOutputs(route.getOutputs(), ExpressionNode.class);
+ while (it.hasNext()) {
+ NamespaceAware na = getNamespaceAwareFromExpression(it.next());
+ if (na != null) {
+ na.setNamespaces(namespaces);
+ }
+ }
+ }
+
+ private static NamespaceAware getNamespaceAwareFromExpression(ExpressionNode expressionNode) {
+ ExpressionDefinition ed = expressionNode.getExpression();
+
+ NamespaceAware na = null;
+ Expression exp = ed.getExpressionValue();
+ if (exp instanceof NamespaceAware) {
+ na = (NamespaceAware) exp;
+ } else if (ed instanceof NamespaceAware) {
+ na = (NamespaceAware) ed;
+ }
+
+ return na;
}
private static JAXBContext createJAXBContext() throws JAXBException {
@@ -152,22 +243,12 @@ public final class ModelHelper {
* Extract all XML namespaces from the expressions in the route
*
* @param route the route
- * @param namespaces the map of namespace to add new found XML namespaces
+ * @param namespaces the map of namespaces to add discovered XML namespaces into
*/
private static void extractNamespaces(RouteDefinition route, Map<String, String> namespaces) {
Iterator<ExpressionNode> it = filterTypeInOutputs(route.getOutputs(), ExpressionNode.class);
while (it.hasNext()) {
- ExpressionNode en = it.next();
- ExpressionDefinition ed = en.getExpression();
-
- // java-dsl sets directly expression so try this first
- NamespaceAware na = null;
- Expression exp = ed.getExpressionValue();
- if (exp != null && exp instanceof NamespaceAware) {
- na = (NamespaceAware) exp;
- } else if (ed instanceof NamespaceAware) {
- na = (NamespaceAware) ed;
- }
+ NamespaceAware na = getNamespaceAwareFromExpression(it.next());
if (na != null) {
Map<String, String> map = na.getNamespaces();
@@ -177,4 +258,30 @@ public final class ModelHelper {
}
}
}
+
+ /**
+ * Extract all XML namespaces from the root element in a DOM Document
+ *
+ * @param document the DOM document
+ * @param namespaces the map of namespaces to add new found XML namespaces
+ */
+ private static void extractNamespaces(Document document, Map<String, String> namespaces) throws JAXBException {
+ NamedNodeMap attributes = document.getDocumentElement().getAttributes();
+ for (int i = 0; i < attributes.getLength(); i++) {
+ Node item = attributes.item(i);
+ String nsPrefix = item.getNodeName();
+ if (nsPrefix != null && nsPrefix.startsWith("xmlns")) {
+ String nsValue = item.getNodeValue();
+ String[] nsParts = nsPrefix.split(":");
+ if (nsParts.length == 1) {
+ namespaces.put(nsParts[0], nsValue);
+ } else if (nsParts.length == 2) {
+ namespaces.put(nsParts[1], nsValue);
+ } else {
+ // Fallback on adding the namespace prefix as we find it
+ namespaces.put(nsPrefix, nsValue);
+ }
+ }
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/camel/blob/20a1b012/camel-core/src/main/java/org/apache/camel/util/ExchangeHelper.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/util/ExchangeHelper.java b/camel-core/src/main/java/org/apache/camel/util/ExchangeHelper.java
index eca7f0f..ce3fdca 100644
--- a/camel-core/src/main/java/org/apache/camel/util/ExchangeHelper.java
+++ b/camel-core/src/main/java/org/apache/camel/util/ExchangeHelper.java
@@ -51,7 +51,7 @@ import org.apache.camel.spi.UnitOfWork;
/**
* Some helper methods for working with {@link Exchange} objects
*
- * @version
+ * @version
*/
public final class ExchangeHelper {
http://git-wip-us.apache.org/repos/asf/camel/blob/20a1b012/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesRouteFromTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesRouteFromTest.java b/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesRouteFromTest.java
index 10eff3b..fb6296d 100644
--- a/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesRouteFromTest.java
+++ b/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesRouteFromTest.java
@@ -38,7 +38,7 @@ public class PropertiesRouteFromTest extends ContextTestSupport {
// use a routes definition to dump the routes
String xml = ModelHelper.dumpModelAsXml(context, context.getRouteDefinition("foo"));
assertTrue(xml.contains("<from uri=\"{{cool.start}}\"/>"));
- assertTrue(xml.contains("<to uri=\"{{cool.end}}\""));
+ assertTrue(xml.contains("<to id=\"to1\" uri=\"{{cool.end}}\"/>"));
}
@Override
http://git-wip-us.apache.org/repos/asf/camel/blob/20a1b012/camel-core/src/test/java/org/apache/camel/converter/jaxp/XmlConverterTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/converter/jaxp/XmlConverterTest.java b/camel-core/src/test/java/org/apache/camel/converter/jaxp/XmlConverterTest.java
index e35a3db..4618131 100644
--- a/camel-core/src/test/java/org/apache/camel/converter/jaxp/XmlConverterTest.java
+++ b/camel-core/src/test/java/org/apache/camel/converter/jaxp/XmlConverterTest.java
@@ -20,6 +20,7 @@ import java.io.File;
import java.io.InputStream;
import java.io.Reader;
import java.nio.ByteBuffer;
+import java.util.Properties;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
@@ -79,6 +80,33 @@ public class XmlConverterTest extends ContextTestSupport {
assertEquals("<foo>bar</foo>", out);
}
+ public void testToStringWithDocument() throws Exception {
+ XmlConverter conv = new XmlConverter();
+
+ Document document = conv.createDocument();
+ Element foo = document.createElement("foo");
+ foo.setTextContent("bar");
+ document.appendChild(foo);
+
+ String out = conv.toStringFromDocument(document, null);
+ assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><foo>bar</foo>", out);
+ }
+
+ public void testToStringWithDocumentSourceOutputProperties() throws Exception {
+ XmlConverter conv = new XmlConverter();
+
+ Document document = conv.createDocument();
+ Element foo = document.createElement("foo");
+ foo.setTextContent("bar");
+ document.appendChild(foo);
+
+ Properties properties = new Properties();
+ properties.put(OutputKeys.ENCODING, "ISO-8859-1");
+
+ String out = conv.toStringFromDocument(document, properties);
+ assertEquals("<?xml version=\"1.0\" encoding=\"ISO-8859-1\" standalone=\"no\"?><foo>bar</foo>", out);
+ }
+
public void testToSource() throws Exception {
XmlConverter conv = new XmlConverter();
@@ -497,7 +525,7 @@ public class XmlConverterTest extends ContextTestSupport {
XmlConverter conv = new XmlConverter();
SAXSource source = conv.toSAXSource("<foo>bar</foo>", exchange);
- DOMSource out = conv.toDOMSource(source);
+ DOMSource out = conv.toDOMSource(source, exchange);
assertNotSame(source, out);
assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><foo>bar</foo>", conv.toString(out, exchange));
http://git-wip-us.apache.org/repos/asf/camel/blob/20a1b012/camel-core/src/test/java/org/apache/camel/management/ManagedFromRestGetTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/management/ManagedFromRestGetTest.java b/camel-core/src/test/java/org/apache/camel/management/ManagedFromRestGetTest.java
index 5aa9ec7..2b69d03 100644
--- a/camel-core/src/test/java/org/apache/camel/management/ManagedFromRestGetTest.java
+++ b/camel-core/src/test/java/org/apache/camel/management/ManagedFromRestGetTest.java
@@ -62,10 +62,10 @@ public class ManagedFromRestGetTest extends ManagementTestSupport {
assertTrue(xml.contains("application/json"));
assertTrue(xml.contains("</rests>"));
- assertTrue(xml.contains("<param name=\"header_letter\" type=\"query\" description=\"header param description2\""
- + " defaultValue=\"b\" required=\"false\" collectionFormat=\"multi\" dataType=\"string\">"));
- assertTrue(xml.contains("<param name=\"header_count\" type=\"header\" description=\"header param description1\" "
- + "defaultValue=\"1\" required=\"true\" dataType=\"integer\""));
+ assertTrue(xml.contains("<param collectionFormat=\"multi\" dataType=\"string\" defaultValue=\"b\" "
+ + "description=\"header param description2\" name=\"header_letter\" required=\"false\" type=\"query\">"));
+ assertTrue(xml.contains("<param dataType=\"integer\" defaultValue=\"1\" "
+ + "description=\"header param description1\" name=\"header_count\" required=\"true\" type=\"header\">"));
assertTrue(xml.contains("<value>1</value>"));
assertTrue(xml.contains("<value>a</value>"));
http://git-wip-us.apache.org/repos/asf/camel/blob/20a1b012/camel-core/src/test/java/org/apache/camel/management/ManagedFromRestPlaceholderTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/management/ManagedFromRestPlaceholderTest.java b/camel-core/src/test/java/org/apache/camel/management/ManagedFromRestPlaceholderTest.java
index 6eec89b..559943a 100644
--- a/camel-core/src/test/java/org/apache/camel/management/ManagedFromRestPlaceholderTest.java
+++ b/camel-core/src/test/java/org/apache/camel/management/ManagedFromRestPlaceholderTest.java
@@ -69,10 +69,10 @@ public class ManagedFromRestPlaceholderTest extends ManagementTestSupport {
assertTrue(xml.contains("application/json"));
assertTrue(xml.contains("</rests>"));
- assertTrue(xml.contains("<param name=\"header_letter\" type=\"query\" description=\"header param description2\""
- + " defaultValue=\"b\" required=\"false\" collectionFormat=\"multi\" dataType=\"string\">"));
- assertTrue(xml.contains("<param name=\"header_count\" type=\"header\" description=\"header param description1\" "
- + "defaultValue=\"1\" required=\"true\" dataType=\"integer\">"));
+ assertTrue(xml.contains("<param collectionFormat=\"multi\" dataType=\"string\" defaultValue=\"b\" description=\"header param description2\" "
+ + "name=\"header_letter\" required=\"false\" type=\"query\">"));
+ assertTrue(xml.contains("<param dataType=\"integer\" defaultValue=\"1\" description=\"header param description1\" "
+ + "name=\"header_count\" required=\"true\" type=\"header\">"));
assertTrue(xml.contains("<value>1</value>"));
assertTrue(xml.contains("<value>a</value>"));
http://git-wip-us.apache.org/repos/asf/camel/blob/20a1b012/camel-core/src/test/java/org/apache/camel/model/LoadRouteFromXmlWithNamespaceTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/model/LoadRouteFromXmlWithNamespaceTest.java b/camel-core/src/test/java/org/apache/camel/model/LoadRouteFromXmlWithNamespaceTest.java
new file mode 100644
index 0000000..aae0265
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/model/LoadRouteFromXmlWithNamespaceTest.java
@@ -0,0 +1,44 @@
+/**
+ * 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.model;
+
+import java.io.InputStream;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Route;
+import org.apache.camel.component.mock.MockEndpoint;
+
+public class LoadRouteFromXmlWithNamespaceTest extends ContextTestSupport {
+
+ public void testLoadRouteWithNamespaceFromXml() throws Exception {
+ InputStream inputStream = getClass().getResourceAsStream("routeWithNamespace.xml");
+ RoutesDefinition routes = context.loadRoutesDefinition(inputStream);
+ context.addRouteDefinitions(routes.getRoutes());
+ context.start();
+
+ Route routeWithNamespace = context.getRoute("routeWithNamespace");
+ assertNotNull("Expected to find route with id: routeWithNamespace", routeWithNamespace);
+
+ MockEndpoint bar = context.getEndpoint("mock:bar", MockEndpoint.class);
+ bar.expectedBodiesReceived("Hello from foo");
+
+ // Make sure loaded route can process a XML payload with namespaces attached
+ context.createProducerTemplate().sendBody("direct:foo", "<?xml version='1.0'?><foo xmlns='http://foo'><bar>cheese</bar></foo>");
+
+ bar.assertIsSatisfied();
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/20a1b012/camel-core/src/test/java/org/apache/camel/util/CreateModelFromXmlTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/util/CreateModelFromXmlTest.java b/camel-core/src/test/java/org/apache/camel/util/CreateModelFromXmlTest.java
new file mode 100644
index 0000000..29bcf9b
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/util/CreateModelFromXmlTest.java
@@ -0,0 +1,123 @@
+/**
+ * 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.util;
+
+import java.io.InputStream;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Expression;
+import org.apache.camel.model.ExpressionNode;
+import org.apache.camel.model.ModelHelper;
+import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.model.RoutesDefinition;
+import org.apache.camel.model.language.ExpressionDefinition;
+import org.apache.camel.spi.NamespaceAware;
+import org.junit.Test;
+
+import static org.apache.camel.model.ProcessorDefinitionHelper.filterTypeInOutputs;
+
+public class CreateModelFromXmlTest extends ContextTestSupport {
+
+ public static final String NS_CAMEL = "http://camel.apache.org/schema/spring";
+ public static final String NS_FOO = "http://foo";
+ public static final String NS_BAR = "http://bar";
+
+ @Test
+ public void testCreateModelFromXmlForInputStreamWithDefaultNamespace() throws Exception {
+ RoutesDefinition routesDefinition = createModelFromXml("simpleRoute.xml", false);
+ assertNotNull(routesDefinition);
+
+ Map<String, String> expectedNamespaces = new LinkedHashMap<>();
+ expectedNamespaces.put("xmlns", NS_CAMEL);
+
+ assertNamespacesPresent(routesDefinition, expectedNamespaces);
+ }
+
+ @Test
+ public void testCreateModelFromXmlForInputStreamWithAdditionalNamespaces() throws Exception {
+ RoutesDefinition routesDefinition = createModelFromXml("simpleRouteWithNamespaces.xml", false);
+ assertNotNull(routesDefinition);
+
+ Map<String, String> expectedNamespaces = new LinkedHashMap<>();
+ expectedNamespaces.put("xmlns", NS_CAMEL);
+ expectedNamespaces.put("foo", NS_FOO);
+ expectedNamespaces.put("bar", NS_BAR);
+
+ assertNamespacesPresent(routesDefinition, expectedNamespaces);
+ }
+
+ @Test
+ public void testCreateModelFromXmlForStringWithDefaultNamespace() throws Exception {
+ RoutesDefinition routesDefinition = createModelFromXml("simpleRoute.xml", true);
+ assertNotNull(routesDefinition);
+
+ Map<String, String> expectedNamespaces = new LinkedHashMap<>();
+ expectedNamespaces.put("xmlns", NS_CAMEL);
+
+ assertNamespacesPresent(routesDefinition, expectedNamespaces);
+ }
+
+ @Test
+ public void testCreateModelFromXmlForStringWithAdditionalNamespaces() throws Exception {
+ RoutesDefinition routesDefinition = createModelFromXml("simpleRouteWithNamespaces.xml", true);
+ assertNotNull(routesDefinition);
+
+ Map<String, String> expectedNamespaces = new LinkedHashMap<>();
+ expectedNamespaces.put("xmlns", NS_CAMEL);
+ expectedNamespaces.put("foo", NS_FOO);
+ expectedNamespaces.put("bar", NS_BAR);
+
+ assertNamespacesPresent(routesDefinition, expectedNamespaces);
+ }
+
+ private RoutesDefinition createModelFromXml(String camelContextResource, boolean fromString) throws Exception {
+ InputStream inputStream = getClass().getResourceAsStream(camelContextResource);
+
+ if (fromString) {
+ String xml = context.getTypeConverter().convertTo(String.class, inputStream);
+ return ModelHelper.createModelFromXml(context, xml, RoutesDefinition.class);
+ }
+
+ return ModelHelper.createModelFromXml(context, inputStream, RoutesDefinition.class);
+ }
+
+ private void assertNamespacesPresent(RoutesDefinition routesDefinition, Map<String, String> expectedNamespaces) {
+ for (RouteDefinition route : routesDefinition.getRoutes()) {
+ Iterator<ExpressionNode> it = filterTypeInOutputs(route.getOutputs(), ExpressionNode.class);
+ if (it.hasNext()) {
+ ExpressionNode en = it.next();
+ ExpressionDefinition ed = en.getExpression();
+
+ NamespaceAware na = null;
+ Expression exp = ed.getExpressionValue();
+ if (exp != null && exp instanceof NamespaceAware) {
+ na = (NamespaceAware) exp;
+ } else if (ed instanceof NamespaceAware) {
+ na = (NamespaceAware) ed;
+ }
+
+ assertNotNull(na);
+ assertEquals(expectedNamespaces, na.getNamespaces());
+ } else {
+ fail("Expected to find at least one ExpressionNode in route");
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/20a1b012/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlAggregateRouteTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlAggregateRouteTest.java b/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlAggregateRouteTest.java
index 3369443..f172942 100644
--- a/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlAggregateRouteTest.java
+++ b/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlAggregateRouteTest.java
@@ -44,7 +44,7 @@ public class DumpModelAsXmlAggregateRouteTest extends ContextTestSupport {
from("direct:start").routeId("myRoute")
.to("log:input")
.aggregate(header("userId"), new GroupedExchangeAggregationStrategy()).completionSize(3)
- .to("mock:aggregate")
+ .to("mock:aggregate")
.end()
.to("mock:result");
}
http://git-wip-us.apache.org/repos/asf/camel/blob/20a1b012/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlNamespaceTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlNamespaceTest.java b/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlNamespaceTest.java
index 3216da37..2170609 100644
--- a/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlNamespaceTest.java
+++ b/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlNamespaceTest.java
@@ -16,19 +16,33 @@
*/
package org.apache.camel.util;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
import org.apache.camel.ContextTestSupport;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.model.ModelHelper;
-/**
- *
- */
public class DumpModelAsXmlNamespaceTest extends ContextTestSupport {
+ private static final String URL_FOO = "http://foo.com";
+ private static final String URL_BAR = "http://bar.com";
+
public void testDumpModelAsXml() throws Exception {
String xml = ModelHelper.dumpModelAsXml(context, context.getRouteDefinition("myRoute"));
assertNotNull(xml);
- log.info(xml);
+
+ Document dom = context.getTypeConverter().convertTo(Document.class, xml);
+ Element rootNode = dom.getDocumentElement();
+ assertNotNull(rootNode);
+
+ String attributeFoo = rootNode.getAttribute("xmlns:foo");
+ assertNotNull(attributeFoo);
+ assertEquals(URL_FOO, attributeFoo);
+
+ String attributeBar = rootNode.getAttribute("xmlns:bar");
+ assertNotNull(attributeBar);
+ assertEquals(URL_BAR, attributeBar);
}
@Override
@@ -38,8 +52,8 @@ public class DumpModelAsXmlNamespaceTest extends ContextTestSupport {
public void configure() throws Exception {
from("direct:start").routeId("myRoute")
.choice()
- .when(xpath("/foo:customer").namespace("foo", "http://foo.com")).to("mock:foo")
- .when(xpath("/bar:customer").namespace("bar", "http://bar.com")).to("mock:bar");
+ .when(xpath("/foo:customer").namespace("foo", URL_FOO)).to("mock:foo")
+ .when(xpath("/bar:customer").namespace("bar", URL_BAR)).to("mock:bar");
}
};
}
http://git-wip-us.apache.org/repos/asf/camel/blob/20a1b012/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlPlaceholdersTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlPlaceholdersTest.java b/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlPlaceholdersTest.java
index c0c25d7..91fb906 100644
--- a/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlPlaceholdersTest.java
+++ b/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlPlaceholdersTest.java
@@ -22,9 +22,6 @@ import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.properties.PropertiesComponent;
import org.apache.camel.model.ModelHelper;
-/**
- *
- */
public class DumpModelAsXmlPlaceholdersTest extends ContextTestSupport {
public void testDumpModelAsXml() throws Exception {
@@ -32,9 +29,9 @@ public class DumpModelAsXmlPlaceholdersTest extends ContextTestSupport {
String xml = ModelHelper.dumpModelAsXml(context, context.getRouteDefinition("Gouda"));
assertNotNull(xml);
log.info(xml);
- assertTrue(xml.contains("<route customId=\"true\" id=\"Gouda\" xmlns=\"http://camel.apache.org/schema/spring\">"));
+ assertTrue(xml.contains("<route xmlns=\"http://camel.apache.org/schema/spring\" customId=\"true\" id=\"Gouda\">"));
assertTrue(xml.contains("<from uri=\"direct:start-{{cheese.type}}\"/>"));
- assertTrue(xml.contains("<to uri=\"direct:end-{{cheese.type}}\" customId=\"true\" id=\"log\"/>"));
+ assertTrue(xml.contains("<to customId=\"true\" id=\"log\" uri=\"direct:end-{{cheese.type}}\"/>"));
}
@Override
http://git-wip-us.apache.org/repos/asf/camel/blob/20a1b012/camel-core/src/test/resources/org/apache/camel/model/routeWithNamespace.xml
----------------------------------------------------------------------
diff --git a/camel-core/src/test/resources/org/apache/camel/model/routeWithNamespace.xml b/camel-core/src/test/resources/org/apache/camel/model/routeWithNamespace.xml
new file mode 100644
index 0000000..a58b66d
--- /dev/null
+++ b/camel-core/src/test/resources/org/apache/camel/model/routeWithNamespace.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<routes xmlns="http://camel.apache.org/schema/spring" xmlns:foo="http://foo">
+ <route id="routeWithNamespace">
+ <from uri="direct:foo" />
+ <choice>
+ <when>
+ <xpath>/foo:foo/foo:bar = 'cheese'</xpath>
+ <setBody>
+ <constant>Hello from foo</constant>
+ </setBody>
+ <to uri="mock:bar"/>
+ </when>
+ </choice>
+ <to uri="log:end"/>
+ </route>
+</routes>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/20a1b012/camel-core/src/test/resources/org/apache/camel/util/simpleRoute.xml
----------------------------------------------------------------------
diff --git a/camel-core/src/test/resources/org/apache/camel/util/simpleRoute.xml b/camel-core/src/test/resources/org/apache/camel/util/simpleRoute.xml
new file mode 100644
index 0000000..49f5077
--- /dev/null
+++ b/camel-core/src/test/resources/org/apache/camel/util/simpleRoute.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<!-- START SNIPPET: e1 -->
+<routes xmlns="http://camel.apache.org/schema/spring">
+ <route id="foo">
+ <from uri="direct:start"/>
+ <choice>
+ <when>
+ <xpath>/a/foo = 'bar'</xpath>
+ <to uri="mock:bar"/>
+ </when>
+ </choice>
+ </route>
+</routes>
+<!-- END SNIPPET: e1 -->
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/20a1b012/camel-core/src/test/resources/org/apache/camel/util/simpleRouteWithNamespaces.xml
----------------------------------------------------------------------
diff --git a/camel-core/src/test/resources/org/apache/camel/util/simpleRouteWithNamespaces.xml b/camel-core/src/test/resources/org/apache/camel/util/simpleRouteWithNamespaces.xml
new file mode 100644
index 0000000..9a29480
--- /dev/null
+++ b/camel-core/src/test/resources/org/apache/camel/util/simpleRouteWithNamespaces.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<!-- START SNIPPET: e1 -->
+<routes xmlns="http://camel.apache.org/schema/spring" xmlns:foo="http://foo" xmlns:bar="http://bar">
+ <route id="foo">
+ <from uri="direct:start"/>
+ <choice>
+ <when>
+ <xpath>/a/foo = 'bar'</xpath>
+ <to uri="mock:bar"/>
+ </when>
+ </choice>
+ </route>
+</routes>
+<!-- END SNIPPET: e1 -->
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/20a1b012/components/camel-spring/src/test/java/org/apache/camel/spring/DumpModelAsXmlPlaceholdersTest.java
----------------------------------------------------------------------
diff --git a/components/camel-spring/src/test/java/org/apache/camel/spring/DumpModelAsXmlPlaceholdersTest.java b/components/camel-spring/src/test/java/org/apache/camel/spring/DumpModelAsXmlPlaceholdersTest.java
index 4f533c1..5bf0585 100644
--- a/components/camel-spring/src/test/java/org/apache/camel/spring/DumpModelAsXmlPlaceholdersTest.java
+++ b/components/camel-spring/src/test/java/org/apache/camel/spring/DumpModelAsXmlPlaceholdersTest.java
@@ -36,9 +36,9 @@ public class DumpModelAsXmlPlaceholdersTest extends SpringTestSupport {
assertNotNull(xml);
log.info(xml);
- assertTrue(xml.contains("<route customId=\"true\" id=\"Gouda\" xmlns=\"http://camel.apache.org/schema/spring\">"));
+ assertTrue(xml.contains("<route xmlns=\"http://camel.apache.org/schema/spring\" customId=\"true\" id=\"Gouda\">"));
assertTrue(xml.contains("<from uri=\"direct:start-{{cheese.type}}\"/>"));
- assertTrue(xml.contains("<to uri=\"direct:end-{{cheese.type}}\" customId=\"true\" id=\"log\"/>"));
+ assertTrue(xml.contains("<to customId=\"true\" id=\"log\" uri=\"direct:end-{{cheese.type}}\"/>"));
}
}