You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ay...@apache.org on 2014/06/02 10:36:13 UTC
[2/2] git commit: add wildcard handling and fix the default nsdecl
handling for the injected mode for CAMEL-7468
add wildcard handling and fix the default nsdecl handling for the injected mode for CAMEL-7468
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/22721385
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/22721385
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/22721385
Branch: refs/heads/master
Commit: 22721385334aace46c3b9943a1d715024c17ff73
Parents: f17f778
Author: Akitoshi Yoshida <ay...@apache.org>
Authored: Fri May 30 18:32:34 2014 +0200
Committer: Akitoshi Yoshida <ay...@apache.org>
Committed: Mon Jun 2 10:19:31 2014 +0200
----------------------------------------------------------------------
.../support/TokenXMLExpressionIterator.java | 3 -
.../support/XMLTokenExpressionIterator.java | 68 ++++++++++++++++----
.../support/XMLTokenExpressionIteratorTest.java | 63 +++++++++++++++++-
3 files changed, 116 insertions(+), 18 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/22721385/camel-core/src/main/java/org/apache/camel/support/TokenXMLExpressionIterator.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/support/TokenXMLExpressionIterator.java b/camel-core/src/main/java/org/apache/camel/support/TokenXMLExpressionIterator.java
index 4192acf..497e63f 100644
--- a/camel-core/src/main/java/org/apache/camel/support/TokenXMLExpressionIterator.java
+++ b/camel-core/src/main/java/org/apache/camel/support/TokenXMLExpressionIterator.java
@@ -16,12 +16,9 @@
*/
package org.apache.camel.support;
-import java.io.ByteArrayOutputStream;
import java.io.Closeable;
-import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Iterator;
http://git-wip-us.apache.org/repos/asf/camel/blob/22721385/camel-core/src/main/java/org/apache/camel/support/XMLTokenExpressionIterator.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/support/XMLTokenExpressionIterator.java b/camel-core/src/main/java/org/apache/camel/support/XMLTokenExpressionIterator.java
index 111bdaa..a8b8aa8 100644
--- a/camel-core/src/main/java/org/apache/camel/support/XMLTokenExpressionIterator.java
+++ b/camel-core/src/main/java/org/apache/camel/support/XMLTokenExpressionIterator.java
@@ -119,7 +119,7 @@ public class XMLTokenExpressionIterator extends ExpressionAdapter implements Nam
private static final Logger LOG = LoggerFactory.getLogger(XMLTokenIterator.class);
private static final Pattern NAMESPACE_PATTERN = Pattern.compile("xmlns(:\\w+|)\\s*=\\s*('[^']+'|\"[^\"]+\")");
- private QName[] splitpath;
+ private AttributedQName[] splitpath;
private int index;
private boolean wrap;
private RecordableInputStream in;
@@ -138,13 +138,15 @@ public class XMLTokenExpressionIterator extends ExpressionAdapter implements Nam
public XMLTokenIterator(String path, Map<String, String> nsmap, boolean wrap, InputStream in, Exchange exchange) throws XMLStreamException {
final String[] sl = path.substring(1).split("/");
- this.splitpath = new QName[sl.length];
+ this.splitpath = new AttributedQName[sl.length];
for (int i = 0; i < sl.length; i++) {
String s = sl[i];
if (s.length() > 0) {
int d = s.indexOf(':');
String pfx = d > 0 ? s.substring(0, d) : "";
- this.splitpath[i] = new QName(nsmap.get(pfx), d > 0 ? s.substring(d + 1) : s, pfx);
+ this.splitpath[i] =
+ new AttributedQName(
+ "*".equals(pfx) ? "*" : nsmap.get(pfx), d > 0 ? s.substring(d + 1) : s, pfx);
}
}
@@ -154,7 +156,8 @@ public class XMLTokenExpressionIterator extends ExpressionAdapter implements Nam
this.reader = new StaxConverter().createXMLStreamReader(this.in, exchange);
LOG.trace("reader.class: {}", reader.getClass());
- if (reader.getLocation().getCharacterOffset() < 0) {
+ int coff = reader.getLocation().getCharacterOffset();
+ if (coff != 0) {
LOG.error("XMLStreamReader {} not supporting Location");
throw new XMLStreamException("reader not supporting Location");
}
@@ -177,11 +180,11 @@ public class XMLTokenExpressionIterator extends ExpressionAdapter implements Nam
return splitpath[index] == null;
}
- private QName current() {
+ private AttributedQName current() {
return splitpath[index + (isDoS() ? 1 : 0)];
}
- private QName ancestor() {
+ private AttributedQName ancestor() {
return index == 0 ? null : splitpath[index - 1];
}
@@ -335,7 +338,8 @@ public class XMLTokenExpressionIterator extends ExpressionAdapter implements Nam
sb.append(token.substring(0, stag.length() - (empty ? 2 : 1)));
for (Entry<String, String> e : getCurrentNamespaceBindings().entrySet()) {
if (!skip.contains(e.getKey())) {
- sb.append(" xmlns:").append(e.getKey()).append("=").append(quote).append(e.getValue()).append(quote);
+ sb.append(e.getKey().length() == 0 ? " xmlns" : " xmlns:")
+ .append(e.getKey()).append("=").append(quote).append(e.getValue()).append(quote);
}
}
sb.append(token.substring(stag.length() - (empty ? 2 : 1)));
@@ -367,7 +371,7 @@ public class XMLTokenExpressionIterator extends ExpressionAdapter implements Nam
pushNamespaces(reader);
}
backtrack = false;
- if (matches(name, current())) {
+ if (current().matches(name)) {
// mark the position of the match in the segments list
if (isBottom()) {
// final match
@@ -417,7 +421,7 @@ public class XMLTokenExpressionIterator extends ExpressionAdapter implements Nam
}
if ((ancestor() == null && !isTop())
- || (ancestor() != null && matches(endname, ancestor()))) {
+ || (ancestor() != null && ancestor().matches(endname))) {
up();
}
}
@@ -437,10 +441,6 @@ public class XMLTokenExpressionIterator extends ExpressionAdapter implements Nam
return pfx.length() == 0 ? qname.getLocalPart() : qname.getPrefix() + ":" + qname.getLocalPart();
}
- private static boolean matches(QName a, QName b) {
- return a.getNamespaceURI().equals(b.getNamespaceURI()) && a.getLocalPart().equals(b.getLocalPart());
- }
-
@Override
public boolean hasNext() {
return nextToken != null;
@@ -472,4 +472,46 @@ public class XMLTokenExpressionIterator extends ExpressionAdapter implements Nam
}
}
+ static class AttributedQName extends QName {
+ private static final long serialVersionUID = 9878370226894144L;
+ private Pattern lcpattern;
+ private boolean nsany;
+
+ public AttributedQName(String localPart) {
+ super(localPart);
+ checkWildcard("", localPart);
+ }
+
+ public AttributedQName(String namespaceURI, String localPart, String prefix) {
+ super(namespaceURI, localPart, prefix);
+ checkWildcard(namespaceURI, localPart);
+ }
+
+ public AttributedQName(String namespaceURI, String localPart) {
+ super(namespaceURI, localPart);
+ checkWildcard(namespaceURI, localPart);
+ }
+
+ public boolean matches(QName qname) {
+ return (nsany || getNamespaceURI().equals(qname.getNamespaceURI()))
+ && (lcpattern != null
+ ? lcpattern.matcher(qname.getLocalPart()).matches()
+ : getLocalPart().equals(qname.getLocalPart()));
+ }
+
+ private void checkWildcard(String nsa, String lcp) {
+ nsany = "*".equals(nsa);
+ boolean wc = false;
+ for (int i = 0; i < lcp.length(); i++) {
+ char c = lcp.charAt(i);
+ if (c == '?' || c == '*') {
+ wc = true;
+ break;
+ }
+ }
+ if (wc) {
+ lcpattern = Pattern.compile(lcp.replace(".", "\\.").replace("*", ".*").replace("?", "."));
+ }
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/camel/blob/22721385/camel-core/src/test/java/org/apache/camel/support/XMLTokenExpressionIteratorTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/support/XMLTokenExpressionIteratorTest.java b/camel-core/src/test/java/org/apache/camel/support/XMLTokenExpressionIteratorTest.java
index 67bb159..fe0c8bf 100644
--- a/camel-core/src/test/java/org/apache/camel/support/XMLTokenExpressionIteratorTest.java
+++ b/camel-core/src/test/java/org/apache/camel/support/XMLTokenExpressionIteratorTest.java
@@ -55,7 +55,21 @@ public class XMLTokenExpressionIteratorTest extends TestCase {
+ "</c:parent>"
+ "</grandparent>"
+ "</g:greatgrandparent>").getBytes();
-
+
+ private static final byte[] TEST_BODY_NS_MIXED =
+ ("<?xml version='1.0' encoding='UTF-8'?>"
+ + "<g:greatgrandparent xmlns:g='urn:g'><grandparent>"
+ + "<parent some_attr='1' xmlns:c='urn:c' xmlns=\"urn:c\">"
+ + "<child some_attr='a' anotherAttr='a'></child>"
+ + "<x:child xmlns:x='urn:c' some_attr='b' anotherAttr='b'/>"
+ + "</parent>"
+ + "<c:parent some_attr='2' xmlns:c='urn:c'>"
+ + "<child some_attr='c' anotherAttr='c' xmlns='urn:c'></child>"
+ + "<c:child some_attr='d' anotherAttr='d'/>"
+ + "</c:parent>"
+ + "</grandparent>"
+ + "</g:greatgrandparent>").getBytes();
+
private static final String[] RESULTS_CHILD_WRAPPED = {
"<?xml version='1.0' encoding='UTF-8'?>"
+ "<g:greatgrandparent xmlns:g='urn:g'><grandparent><uncle/><aunt>emma</aunt>"
@@ -89,6 +103,28 @@ public class XMLTokenExpressionIteratorTest extends TestCase {
+ "</c:parent></grandparent></g:greatgrandparent>"
};
+ private static final String[] RESULTS_CHILD_MIXED = {
+ "<child some_attr='a' anotherAttr='a' xmlns=\"urn:c\" xmlns:g=\"urn:g\" xmlns:c=\"urn:c\"></child>",
+ "<x:child xmlns:x='urn:c' some_attr='b' anotherAttr='b' xmlns='urn:c' xmlns:g='urn:g' xmlns:c='urn:c'/>",
+ "<child some_attr='c' anotherAttr='c' xmlns='urn:c' xmlns:g='urn:g' xmlns:c='urn:c'></child>",
+ "<c:child some_attr='d' anotherAttr='d' xmlns:g=\"urn:g\" xmlns:c=\"urn:c\"/>"
+ };
+
+ private static final String[] RESULTS_CHILD_MIXED_WRAPPED = {
+ "<?xml version='1.0' encoding='UTF-8'?><g:greatgrandparent xmlns:g='urn:g'><grandparent>"
+ + "<parent some_attr='1' xmlns:c='urn:c' xmlns=\"urn:c\">"
+ + "<child some_attr='a' anotherAttr='a'></child></parent></grandparent></g:greatgrandparent>",
+ "<?xml version='1.0' encoding='UTF-8'?><g:greatgrandparent xmlns:g='urn:g'><grandparent>"
+ + "<parent some_attr='1' xmlns:c='urn:c' xmlns=\"urn:c\">"
+ + "<x:child xmlns:x='urn:c' some_attr='b' anotherAttr='b'/></parent></grandparent></g:greatgrandparent>",
+ "<?xml version='1.0' encoding='UTF-8'?><g:greatgrandparent xmlns:g='urn:g'><grandparent>"
+ + "<c:parent some_attr='2' xmlns:c='urn:c'>"
+ + "<child some_attr='c' anotherAttr='c' xmlns='urn:c'></child></c:parent></grandparent></g:greatgrandparent>",
+ "<?xml version='1.0' encoding='UTF-8'?><g:greatgrandparent xmlns:g='urn:g'><grandparent>"
+ + "<c:parent some_attr='2' xmlns:c='urn:c'>"
+ + "<c:child some_attr='d' anotherAttr='d'/></c:parent></grandparent></g:greatgrandparent>"
+ };
+
private static final String[] RESULTS_CHILD = {
"<c:child some_attr='a' anotherAttr='a' xmlns:g=\"urn:g\" xmlns:d=\"urn:d\" xmlns:c=\"urn:c\"></c:child>",
"<c:child some_attr='b' anotherAttr='b' xmlns:g=\"urn:g\" xmlns:d=\"urn:d\" xmlns:c=\"urn:c\"/>",
@@ -147,7 +183,10 @@ public class XMLTokenExpressionIteratorTest extends TestCase {
"<aunt xmlns:g=\"urn:g\">emma</aunt>",
"<aunt xmlns:g=\"urn:g\"/>"
};
-
+
+ private static final String[] RESULTS_NULL = {
+ };
+
private Map<String, String> nsmap;
private Exchange exchange;
@@ -170,6 +209,26 @@ public class XMLTokenExpressionIteratorTest extends TestCase {
invokeAndVerify("//C:child", false, new ByteArrayInputStream(TEST_BODY), RESULTS_CHILD);
}
+ public void testExtractChildNSMixed() throws Exception {
+ invokeAndVerify("//*:child", true, new ByteArrayInputStream(TEST_BODY_NS_MIXED), RESULTS_CHILD_MIXED_WRAPPED);
+ }
+
+ public void testExtractChildNSMixedInjected() throws Exception {
+ invokeAndVerify("//*:child", false, new ByteArrayInputStream(TEST_BODY_NS_MIXED), RESULTS_CHILD_MIXED);
+ }
+
+ public void testExtractAnyChild() throws Exception {
+ invokeAndVerify("//*:child", true, new ByteArrayInputStream(TEST_BODY), RESULTS_CHILD_WRAPPED);
+ }
+
+ public void testExtractCxxxd() throws Exception {
+ invokeAndVerify("//C:c*d", false, new ByteArrayInputStream(TEST_BODY), RESULTS_CHILD);
+ }
+
+ public void testExtractUnqualifiedChild() throws Exception {
+ invokeAndVerify("//child", true, new ByteArrayInputStream(TEST_BODY), RESULTS_NULL);
+ }
+
public void testExtractChildWithAncestorGGPdGP() throws Exception {
invokeAndVerify("/G:greatgrandparent/grandparent//C:child",
true, new ByteArrayInputStream(TEST_BODY), RESULTS_CHILD_WRAPPED);