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 713f219 CAMEL-13795: Fixing the issue of already declared namespaces
within the child (#3071)
713f219 is described below
commit 713f2194654b50b532750d9704b3d38be17f298b
Author: Christian Pieczewski <[email protected]>
AuthorDate: Wed Jul 31 14:28:17 2019 +0200
CAMEL-13795: Fixing the issue of already declared namespaces within the
child (#3071)
* CAMEL-13795:
Fixing the issue of already declared namespaces within the child
I have also align the tests classes
* CAMEL-13795: code cleanup
---
...kenXMLPairNamespaceSplitChildNamespaceTest.java | 100 +++++++++++++++++++++
.../builder/TokenXMLExpressionIterator.java | 46 ++++++++--
2 files changed, 140 insertions(+), 6 deletions(-)
diff --git
a/core/camel-core/src/test/java/org/apache/camel/language/TokenXMLPairNamespaceSplitChildNamespaceTest.java
b/core/camel-core/src/test/java/org/apache/camel/language/TokenXMLPairNamespaceSplitChildNamespaceTest.java
new file mode 100644
index 0000000..3308ce1
--- /dev/null
+++
b/core/camel-core/src/test/java/org/apache/camel/language/TokenXMLPairNamespaceSplitChildNamespaceTest.java
@@ -0,0 +1,100 @@
+/*
+ * 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.language;
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ *
+ */
+public class TokenXMLPairNamespaceSplitChildNamespaceTest extends
ContextTestSupport {
+
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ deleteDirectory("target/data/pair");
+ deleteDirectory("target/data/pair2");
+ super.setUp();
+ }
+
+ @Test
+ public void testTokenXMLPair() throws Exception {
+ MockEndpoint mock = getMockEndpoint("mock:split");
+ mock.expectedMessageCount(4);
+ mock.message(0).body().isEqualTo("<order id=\"1\"
xmlns=\"http:acme.com\" xmlns:foo=\"http:foo.com\">Camel in Action</order>");
+ mock.message(1).body().isEqualTo("<order id=\"2\"
xmlns=\"http:acme.com\" xmlns:foo=\"http:foo.com\">ActiveMQ in Action</order>");
+ mock.message(2).body().isEqualTo("<order id=\"3\"
xmlns=\"http:acme.com\" xmlns:foo=\"http:foo.com\">DSL in Action</order>");
+ mock.message(3).body().isEqualTo("<order id=\"4\"
xmlns:foo=\"http:foo.com\" xmlns=\"http:acme.com\">DSL in Action</order>");
+
+ String body = createBody();
+ template.sendBodyAndHeader("file:target/data/pair", body,
Exchange.FILE_NAME, "orders.xml");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ @Test
+ public void testTokenXMLPair2() throws Exception {
+ MockEndpoint mock = getMockEndpoint("mock:split");
+ mock.expectedMessageCount(3);
+ mock.message(0).body().isEqualTo("<order id=\"1\"
xmlns=\"http:acme.com\" xmlns:foo=\"http:foo.com\">Camel in Action</order>");
+ mock.message(1).body().isEqualTo("<order id=\"2\"
xmlns=\"http:acme.com\" xmlns:foo=\"http:foo.com\">ActiveMQ in Action</order>");
+ mock.message(2).body().isEqualTo("<order id=\"3\"
xmlns=\"http:acme.com\" xmlns:foo=\"http:foo.com\">DSL in Action</order>");
+ mock.message(3).body().isEqualTo("<order id=\"4\"
xmlns:foo=\"http:foo.com\" xmlns=\"http:acme.com\">DSL in Action</order>");
+
+ String body = createBody();
+ template.sendBodyAndHeader("file:target/data/pair2", body,
Exchange.FILE_NAME, "orders.xml");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ protected String createBody() {
+ StringBuilder sb = new StringBuilder("<?xml version=\"1.0\"?>\n");
+ sb.append("<orders xmlns=\"http:acme.com\"\n");
+ sb.append(" xmlns:foo=\"http:foo.com\">\n");
+ sb.append(" <order id=\"1\" xmlns=\"http:acme.com\">Camel in
Action</order>\n");
+ sb.append(" <order id=\"2\"");
+ sb.append(" xmlns=\"http:acme.com\">ActiveMQ in Action</order>\n");
+ sb.append(" <order id=\"3\">DSL in Action</order>\n");
+ sb.append(" <order id=\"4\" xmlns:foo=\"http:foo.com\">DSL in
Action</order>\n");
+ sb.append("</orders>");
+ return sb.toString();
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ // START SNIPPET: e1
+ from("file:target/data/pair?initialDelay=0&delay=10")
+ // split the order child tags, and inherit namespaces from
the orders root tag
+ .split().tokenizeXML("order", "orders")
+ .to("mock:split");
+ // END SNIPPET: e1
+
+ from("file:target/data/pair2?initialDelay=0&delay=10")
+ // split the order child tags, and inherit namespaces from
the orders root tag
+ .split(body().tokenizeXML("order", "orders"))
+ .to("mock:split");
+ }
+ };
+ }
+}
\ No newline at end of file
diff --git
a/core/camel-support/src/main/java/org/apache/camel/support/builder/TokenXMLExpressionIterator.java
b/core/camel-support/src/main/java/org/apache/camel/support/builder/TokenXMLExpressionIterator.java
index ff0dd5b..a6aa884 100644
---
a/core/camel-support/src/main/java/org/apache/camel/support/builder/TokenXMLExpressionIterator.java
+++
b/core/camel-support/src/main/java/org/apache/camel/support/builder/TokenXMLExpressionIterator.java
@@ -35,6 +35,7 @@ import org.apache.camel.InvalidPayloadException;
import org.apache.camel.support.ExchangeHelper;
import org.apache.camel.support.ExpressionAdapter;
import org.apache.camel.support.LanguageSupport;
+import org.apache.camel.util.CollectionStringBuffer;
import org.apache.camel.util.IOHelper;
import org.apache.camel.util.ObjectHelper;
import org.apache.camel.util.StringHelper;
@@ -57,6 +58,7 @@ public class TokenXMLExpressionIterator extends
ExpressionAdapter {
private static final String SCAN_BLOCK_TOKEN_REGEX_TEMPLATE =
"<{0}(\\s+[^>]*)?/>|<{0}(\\s+[^>]*)?>(?:(?!(</{0}\\s*>)).)*</{0}\\s*>";
private static final String SCAN_PARENT_TOKEN_REGEX_TEMPLATE =
"<{0}(\\s+[^>]*\\s*)?>";
private static final String OPTION_WRAP_TOKEN = "<*>";
+ private static final String NAMESPACE_SEPERATOR = " ";
protected final String tagToken;
protected final String inheritNamespaceToken;
@@ -162,7 +164,7 @@ public class TokenXMLExpressionIterator extends
ExpressionAdapter {
private final String inheritNamespaceToken;
private final boolean wrapToken;
private Pattern inheritNamespaceTokenPattern;
- private String rootTokenNamespaces;
+ private String[] rootTokenNamespaces;
private String wrapHead;
private String wrapTail;
@@ -203,7 +205,7 @@ public class TokenXMLExpressionIterator extends
ExpressionAdapter {
String getNext(boolean first) {
// initialize inherited namespaces on first
if (first && inheritNamespaceToken != null && !wrapToken) {
- rootTokenNamespaces =
getNamespacesFromNamespaceToken(scanner.findWithinHorizon(inheritNamespaceTokenPattern,
0));
+ rootTokenNamespaces =
getNamespacesFromNamespaceTokenSplitter(scanner.findWithinHorizon(inheritNamespaceTokenPattern,
0));
}
String next = scanner.findWithinHorizon(tagTokenPattern, 0);
@@ -218,7 +220,6 @@ public class TokenXMLExpressionIterator extends
ExpressionAdapter {
// build answer accordingly to whether namespaces should be
inherited or not
if (inheritNamespaceToken != null && rootTokenNamespaces != null) {
- // REVISIT should skip the prefixes that are declared within
the child itself.
String head = StringHelper.before(next, ">");
boolean empty = false;
if (head.endsWith("/")) {
@@ -229,8 +230,8 @@ public class TokenXMLExpressionIterator extends
ExpressionAdapter {
// append root namespaces to local start token
// grab the text
String tail = StringHelper.after(next, ">");
- // build result with inherited namespaces
- next =
sb.append(head).append(rootTokenNamespaces).append(empty ? "/>" :
">").append(tail).toString();
+ // build result with inherited namespaces and skip the
prefixes that are declared within the child itself.
+ next =
sb.append(head).append(getMissingInherritNamespaces(head)).append(empty ? "/>"
: ">").append(tail).toString();
} else if (wrapToken) {
// wrap the token
StringBuilder sb = new StringBuilder();
@@ -239,7 +240,40 @@ public class TokenXMLExpressionIterator extends
ExpressionAdapter {
return next;
}
-
+
+ private String getMissingInherritNamespaces(final String text) {
+ final StringBuilder sb = new StringBuilder();
+ if (text != null) {
+ boolean first = true;
+ final String[] containedNamespaces =
getNamespacesFromNamespaceTokenSplitter(text);
+ for (final String rn : rootTokenNamespaces) {
+ boolean nsExists = false;
+ for (final String cn : containedNamespaces) {
+ if (rn.equals(cn)) {
+ nsExists = true;
+ // already existing namespace in child were found
we need a separator, so we set first = false
+ if (first) {
+ first = false;
+ }
+ break;
+ }
+ }
+ if (!nsExists) {
+ sb.append(first ? rn : NAMESPACE_SEPERATOR + rn);
+ if (first) {
+ first = false;
+ }
+ }
+ }
+ }
+ return sb.toString();
+ }
+
+ private String[] getNamespacesFromNamespaceTokenSplitter(final String
text) {
+ final String namespaces = getNamespacesFromNamespaceToken(text);
+ return namespaces == null ? new String[0] :
namespaces.split(NAMESPACE_SEPERATOR);
+ }
+
private String getNamespacesFromNamespaceToken(String text) {
if (text == null) {
return null;