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/11/03 15:53:03 UTC
svn commit: r1197168 - in /camel/trunk:
camel-core/src/main/java/org/apache/camel/builder/
camel-core/src/main/java/org/apache/camel/language/tokenizer/
camel-core/src/main/java/org/apache/camel/model/language/
camel-core/src/main/java/org/apache/camel...
Author: davsclaus
Date: Thu Nov 3 14:53:02 2011
New Revision: 1197168
URL: http://svn.apache.org/viewvc?rev=1197168&view=rev
Log:
CAMEL-4610: Tokenizer XML mode which supports namespaces.
Added:
camel/trunk/camel-core/src/main/java/org/apache/camel/support/TokenXMLPairExpressionIterator.java
- copied, changed from r1197028, camel/trunk/camel-core/src/main/java/org/apache/camel/support/TokenPairExpressionIterator.java
camel/trunk/camel-core/src/test/java/org/apache/camel/language/TokenXMLPairNamespaceSplitTest.java
- copied, changed from r1197028, camel/trunk/camel-core/src/test/java/org/apache/camel/language/TokenPairPredicateTest.java
camel/trunk/components/camel-spring/src/test/java/org/apache/camel/language/SpringTokenXMLPairNamespaceSplitTest.java
camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/language/SpringTokenXMLPairNamespaceSplitTest.xml
- copied, changed from r1197028, camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/aopbefore.xml
Modified:
camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.java
camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionClause.java
camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionClauseSupport.java
camel/trunk/camel-core/src/main/java/org/apache/camel/language/tokenizer/TokenizeLanguage.java
camel/trunk/camel-core/src/main/java/org/apache/camel/model/language/TokenizerExpression.java
camel/trunk/camel-core/src/main/java/org/apache/camel/support/TokenPairExpressionIterator.java
camel/trunk/camel-core/src/test/java/org/apache/camel/language/TokenPairIteratorSplitChoicePerformanceTest.java
camel/trunk/camel-core/src/test/java/org/apache/camel/language/TokenizerTest.java
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.java?rev=1197168&r1=1197167&r2=1197168&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionBuilder.java Thu Nov 3 14:53:02 2011
@@ -42,6 +42,7 @@ import org.apache.camel.model.language.M
import org.apache.camel.spi.Language;
import org.apache.camel.support.ExpressionAdapter;
import org.apache.camel.support.TokenPairExpressionIterator;
+import org.apache.camel.support.TokenXMLPairExpressionIterator;
import org.apache.camel.util.ExchangeHelper;
import org.apache.camel.util.FileUtil;
import org.apache.camel.util.IOHelper;
@@ -1027,11 +1028,39 @@ public final class ExpressionBuilder {
/**
* Returns an {@link TokenPairExpressionIterator} expression
*/
- public static Expression tokenizePairExpression(final String startToken, final String endToken) {
+ public static Expression tokenizePairExpression(String startToken, String endToken) {
return new TokenPairExpressionIterator(startToken, endToken);
}
/**
+ * Returns an {@link TokenXMLPairExpressionIterator} expression
+ */
+ public static Expression tokenizeXMLExpression(String tagName, String inheritNamespaceTagName) {
+ ObjectHelper.notEmpty(tagName, "tagName");
+
+ // must be XML tokens
+ if (!tagName.startsWith("<")) {
+ tagName = "<" + tagName;
+ }
+ if (!tagName.endsWith(">")) {
+ tagName = tagName + ">";
+ }
+
+ String endToken = "</" + tagName.substring(1);
+
+ if (inheritNamespaceTagName != null) {
+ if (!inheritNamespaceTagName.startsWith("<")) {
+ inheritNamespaceTagName = "<" + inheritNamespaceTagName;
+ }
+ if (!inheritNamespaceTagName.endsWith(">")) {
+ inheritNamespaceTagName = inheritNamespaceTagName + ">";
+ }
+ }
+
+ return new TokenXMLPairExpressionIterator(tagName, endToken, inheritNamespaceTagName);
+ }
+
+ /**
* Returns a tokenize expression which will tokenize the string with the
* given regex
*/
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionClause.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionClause.java?rev=1197168&r1=1197167&r2=1197168&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionClause.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionClause.java Thu Nov 3 14:53:02 2011
@@ -435,6 +435,27 @@ public class ExpressionClause<T> extends
}
/**
+ * Evaluates a XML token expression on the message body with XML content
+ *
+ * @param tagName the the tag name of the child nodes to tokenize
+ * @return the builder to continue processing the DSL
+ */
+ public T tokenizeXML(String tagName) {
+ return tokenizeXML(tagName, null);
+ }
+
+ /**
+ * Evaluates a token pair expression on the message body with XML content
+ *
+ * @param tagName the the tag name of the child nodes to tokenize
+ * @param inheritNamespaceTagName parent or root tag name that contains namespace(s) to inherit
+ * @return the builder to continue processing the DSL
+ */
+ public T tokenizeXML(String tagName, String inheritNamespaceTagName) {
+ return delegate.tokenizeXMLPair(tagName, inheritNamespaceTagName);
+ }
+
+ /**
* Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
* expression</a>
*
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionClauseSupport.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionClauseSupport.java?rev=1197168&r1=1197167&r2=1197168&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionClauseSupport.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExpressionClauseSupport.java Thu Nov 3 14:53:02 2011
@@ -486,6 +486,22 @@ public class ExpressionClauseSupport<T>
}
/**
+ * Evaluates a token pair expression on the message body with XML content
+ *
+ * @param tagName the the tag name of the child nodes to tokenize
+ * @param inheritNamespaceTagName optional parent or root tag name that contains namespace(s) to inherit
+ * @return the builder to continue processing the DSL
+ */
+ public T tokenizeXMLPair(String tagName, String inheritNamespaceTagName) {
+ TokenizerExpression expression = new TokenizerExpression();
+ expression.setToken(tagName);
+ expression.setInheritNamespaceTagName(inheritNamespaceTagName);
+ expression.setXml(true);
+ setExpressionType(expression);
+ return result;
+ }
+
+ /**
* Evaluates an <a href="http://camel.apache.org/xpath.html">XPath
* expression</a>
*
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/language/tokenizer/TokenizeLanguage.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/language/tokenizer/TokenizeLanguage.java?rev=1197168&r1=1197167&r2=1197168&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/language/tokenizer/TokenizeLanguage.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/language/tokenizer/TokenizeLanguage.java Thu Nov 3 14:53:02 2011
@@ -27,20 +27,24 @@ import org.apache.camel.util.ObjectHelpe
/**
* A language for tokenizer expressions.
* <p/>
- * This tokenizer language can operator in two modes
+ * This tokenizer language can operator in the following modes:
* <ul>
* <li>default - using a single tokenizer</li>
* <li>pair - using both start and end tokens</li>
+ * <li>xml - using both start and end tokens in XML mode, support inheriting namespaces</li>
* </ul>
* The default mode supports the <tt>headerName</tt> and <tt>regex</tt> options.
* Where as the pair mode only supports <tt>token</tt> and <tt>endToken</tt>.
+ * And the <tt>xml</tt> mode supports the <tt>inheritNamespaceTagName</tt> option.
*/
public class TokenizeLanguage implements Language, IsSingleton {
private String token;
private String endToken;
+ private String inheritNamespaceTagName;
private String headerName;
private boolean regex;
+ private boolean xml;
public static Expression tokenize(String token) {
return tokenize(token, false);
@@ -72,6 +76,14 @@ public class TokenizeLanguage implements
return language.createExpression(null);
}
+ public static Expression tokenizeXML(String tagName, String inheritNamespaceTagName) {
+ TokenizeLanguage language = new TokenizeLanguage();
+ language.setToken(tagName);
+ language.setInheritNamespaceTagName(inheritNamespaceTagName);
+ language.setXml(true);
+ return language.createExpression(null);
+ }
+
public Predicate createPredicate(String expression) {
return ExpressionToPredicateAdapter.toPredicate(createExpression(expression));
}
@@ -82,8 +94,9 @@ public class TokenizeLanguage implements
public Expression createExpression() {
ObjectHelper.notNull(token, "token");
- // if end token is provided then use the tokenize pair expression
- if (endToken != null) {
+ if (isXml()) {
+ return ExpressionBuilder.tokenizeXMLExpression(token, inheritNamespaceTagName);
+ } else if (endToken != null) {
return ExpressionBuilder.tokenizePairExpression(token, endToken);
}
@@ -135,7 +148,23 @@ public class TokenizeLanguage implements
this.regex = regex;
}
+ public String getInheritNamespaceTagName() {
+ return inheritNamespaceTagName;
+ }
+
+ public void setInheritNamespaceTagName(String inheritNamespaceTagName) {
+ this.inheritNamespaceTagName = inheritNamespaceTagName;
+ }
+
+ public boolean isXml() {
+ return xml;
+ }
+
+ public void setXml(boolean xml) {
+ this.xml = xml;
+ }
+
public boolean isSingleton() {
return false;
}
-}
\ No newline at end of file
+}
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/model/language/TokenizerExpression.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/language/TokenizerExpression.java?rev=1197168&r1=1197167&r2=1197168&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/model/language/TokenizerExpression.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/model/language/TokenizerExpression.java Thu Nov 3 14:53:02 2011
@@ -40,9 +40,13 @@ public class TokenizerExpression extends
@XmlAttribute
private String endToken;
@XmlAttribute
+ private String inheritNamespaceTagName;
+ @XmlAttribute
private String headerName;
@XmlAttribute
private Boolean regex;
+ @XmlAttribute
+ private Boolean xml;
public TokenizerExpression() {
}
@@ -84,15 +88,35 @@ public class TokenizerExpression extends
return regex;
}
+ public String getInheritNamespaceTagName() {
+ return inheritNamespaceTagName;
+ }
+
+ public void setInheritNamespaceTagName(String inheritNamespaceTagName) {
+ this.inheritNamespaceTagName = inheritNamespaceTagName;
+ }
+
+ public Boolean getXml() {
+ return xml;
+ }
+
+ public void setXml(Boolean xml) {
+ this.xml = xml;
+ }
+
@Override
public Expression createExpression(CamelContext camelContext) {
TokenizeLanguage language = new TokenizeLanguage();
language.setToken(token);
language.setEndToken(endToken);
+ language.setInheritNamespaceTagName(inheritNamespaceTagName);
language.setHeaderName(headerName);
if (regex != null) {
language.setRegex(regex);
}
+ if (xml != null) {
+ language.setXml(xml);
+ }
return language.createExpression();
}
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/support/TokenPairExpressionIterator.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/support/TokenPairExpressionIterator.java?rev=1197168&r1=1197167&r2=1197168&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/support/TokenPairExpressionIterator.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/support/TokenPairExpressionIterator.java Thu Nov 3 14:53:02 2011
@@ -34,12 +34,12 @@ import org.apache.camel.util.ObjectHelpe
* The message body must be able to convert to {@link InputStream} type which is used as stream
* to access the message body.
* <p/>
- * Can be used to split big XML files
+ * For splitting XML files use {@link TokenXMLPairExpressionIterator} instead.
*/
public class TokenPairExpressionIterator extends ExpressionAdapter {
- private final String startToken;
- private final String endToken;
+ protected final String startToken;
+ protected final String endToken;
public TokenPairExpressionIterator(String startToken, String endToken) {
this.startToken = startToken;
@@ -54,13 +54,26 @@ public class TokenPairExpressionIterator
InputStream in = exchange.getIn().getMandatoryBody(InputStream.class);
// we may read from a file, and want to support custom charset defined on the exchange
String charset = IOHelper.getCharsetName(exchange);
- return new TokenPairIterator(startToken, endToken, in, charset);
+ return createIterator(in, charset);
} catch (InvalidPayloadException e) {
exchange.setException(e);
return null;
}
}
+ /**
+ * Strategy to create the iterator
+ *
+ * @param in input stream to iterate
+ * @param charset charset
+ * @return the iterator
+ */
+ protected Iterator createIterator(InputStream in, String charset) {
+ TokenPairIterator iterator = new TokenPairIterator(startToken, endToken, in, charset);
+ iterator.init();
+ return iterator;
+ }
+
@Override
public String toString() {
return "tokenize[body() using tokens: " + startToken + "..." + endToken + "]";
@@ -69,22 +82,29 @@ public class TokenPairExpressionIterator
/**
* Iterator to walk the input stream
*/
- private static final class TokenPairIterator implements Iterator, Closeable {
+ static class TokenPairIterator implements Iterator, Closeable {
- private final String startToken;
- private final String endToken;
- private final Scanner scanner;
- private Object image;
+ final String startToken;
+ final String endToken;
+ final InputStream in;
+ final String charset;
+ Scanner scanner;
+ Object image;
- private TokenPairIterator(String startToken, String endToken, InputStream in, String charset) {
+ TokenPairIterator(String startToken, String endToken, InputStream in, String charset) {
this.startToken = startToken;
this.endToken = endToken;
+ this.in = in;
+ this.charset = charset;
+ }
+
+ void init() {
// use end token as delimiter
this.scanner = new Scanner(in, charset).useDelimiter(endToken);
// this iterator will do look ahead as we may have data
// after the last end token, which the scanner would find
// so we need to be one step ahead of the scanner
- this.image = scanner.hasNext() ? next() : null;
+ this.image = scanner.hasNext() ? next(true) : null;
}
@Override
@@ -94,10 +114,14 @@ public class TokenPairExpressionIterator
@Override
public Object next() {
+ return next(false);
+ }
+
+ Object next(boolean first) {
Object answer = image;
// calculate next
if (scanner.hasNext()) {
- image = getNext();
+ image = getNext(first);
} else {
image = null;
}
@@ -109,7 +133,7 @@ public class TokenPairExpressionIterator
return answer;
}
- private Object getNext() {
+ Object getNext(boolean first) {
String next = scanner.next();
// only grab text after the start token
Copied: camel/trunk/camel-core/src/main/java/org/apache/camel/support/TokenXMLPairExpressionIterator.java (from r1197028, camel/trunk/camel-core/src/main/java/org/apache/camel/support/TokenPairExpressionIterator.java)
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/support/TokenXMLPairExpressionIterator.java?p2=camel/trunk/camel-core/src/main/java/org/apache/camel/support/TokenXMLPairExpressionIterator.java&p1=camel/trunk/camel-core/src/main/java/org/apache/camel/support/TokenPairExpressionIterator.java&r1=1197028&r2=1197168&rev=1197168&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/support/TokenPairExpressionIterator.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/support/TokenXMLPairExpressionIterator.java Thu Nov 3 14:53:02 2011
@@ -16,128 +16,177 @@
*/
package org.apache.camel.support;
-import java.io.Closeable;
-import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
import java.util.Scanner;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
-import org.apache.camel.Exchange;
-import org.apache.camel.InvalidPayloadException;
-import org.apache.camel.util.IOHelper;
import org.apache.camel.util.ObjectHelper;
/**
- * {@link org.apache.camel.Expression} to walk a {@link org.apache.camel.Message} body
- * using an {@link Iterator}, which grabs the content between a start and end token.
+ * {@link org.apache.camel.Expression} to walk a {@link org.apache.camel.Message} XML body
+ * using an {@link java.util.Iterator}, which grabs the content between a XML start and end token.
* <p/>
- * The message body must be able to convert to {@link InputStream} type which is used as stream
+ * The message body must be able to convert to {@link java.io.InputStream} type which is used as stream
* to access the message body.
* <p/>
- * Can be used to split big XML files
+ * Can be used to split big XML files.
+ * <p/>
+ * This implementation supports inheriting namespaces from a parent/root tag.
*/
-public class TokenPairExpressionIterator extends ExpressionAdapter {
-
- private final String startToken;
- private final String endToken;
+public class TokenXMLPairExpressionIterator extends TokenPairExpressionIterator {
- public TokenPairExpressionIterator(String startToken, String endToken) {
- this.startToken = startToken;
- this.endToken = endToken;
- ObjectHelper.notEmpty(startToken, "startToken");
- ObjectHelper.notEmpty(endToken, "endToken");
- }
-
- @Override
- public Object evaluate(Exchange exchange) {
- try {
- InputStream in = exchange.getIn().getMandatoryBody(InputStream.class);
- // we may read from a file, and want to support custom charset defined on the exchange
- String charset = IOHelper.getCharsetName(exchange);
- return new TokenPairIterator(startToken, endToken, in, charset);
- } catch (InvalidPayloadException e) {
- exchange.setException(e);
- return null;
+ private static final Pattern NAMESPACE_PATTERN = Pattern.compile("xmlns(:\\w+|)=\\\"(.*?)\\\"");
+ private static final String SCAN_TOKEN_REGEX = "(\\s+.*?|)>";
+ protected final String inheritNamespaceToken;
+
+ public TokenXMLPairExpressionIterator(String startToken, String endToken, String inheritNamespaceToken) {
+ super(startToken, endToken);
+ // namespace token is optional
+ this.inheritNamespaceToken = inheritNamespaceToken;
+
+ // must be XML tokens
+ if (!startToken.startsWith("<") || !startToken.endsWith(">")) {
+ throw new IllegalArgumentException("Start token must be a valid XML token, was: " + startToken);
+ }
+ if (!endToken.startsWith("<") || !endToken.endsWith(">")) {
+ throw new IllegalArgumentException("End token must be a valid XML token, was: " + endToken);
+ }
+ if (inheritNamespaceToken != null && (!inheritNamespaceToken.startsWith("<") || !inheritNamespaceToken.endsWith(">"))) {
+ throw new IllegalArgumentException("Namespace token must be a valid XML token, was: " + inheritNamespaceToken);
}
}
@Override
- public String toString() {
- return "tokenize[body() using tokens: " + startToken + "..." + endToken + "]";
+ protected Iterator createIterator(InputStream in, String charset) {
+ XMLTokenPairIterator iterator = new XMLTokenPairIterator(startToken, endToken, inheritNamespaceToken, in, charset);
+ iterator.init();
+ return iterator;
}
/**
* Iterator to walk the input stream
*/
- private static final class TokenPairIterator implements Iterator, Closeable {
+ static class XMLTokenPairIterator extends TokenPairIterator {
+
+ private final Pattern startTokenPattern;
+ private final String scanEndToken;
+ private final String inheritNamespaceToken;
+ private Pattern inheritNamespaceTokenPattern;
+ private String rootTokenNamespaces;
+
+ XMLTokenPairIterator(String startToken, String endToken, String inheritNamespaceToken, InputStream in, String charset) {
+ super(startToken, endToken, in, charset);
+
+ // remove any ending > as we need to support attributes on the tags, so we need to use a reg exp pattern
+ String token = startToken.substring(0, startToken.length() - 1) + SCAN_TOKEN_REGEX;
+ this.startTokenPattern = Pattern.compile(token);
+ this.scanEndToken = endToken.substring(0, endToken.length() - 1) + SCAN_TOKEN_REGEX;
+ this.inheritNamespaceToken = inheritNamespaceToken;
+ if (inheritNamespaceToken != null) {
+ token = inheritNamespaceToken.substring(0, inheritNamespaceToken.length() - 1) + SCAN_TOKEN_REGEX;
+ this.inheritNamespaceTokenPattern = Pattern.compile(token);
+ }
+ }
- private final String startToken;
- private final String endToken;
- private final Scanner scanner;
- private Object image;
-
- private TokenPairIterator(String startToken, String endToken, InputStream in, String charset) {
- this.startToken = startToken;
- this.endToken = endToken;
- // use end token as delimiter
- this.scanner = new Scanner(in, charset).useDelimiter(endToken);
+ @Override
+ void init() {
+ // use scan end token as delimiter which supports attributes/namespaces
+ this.scanner = new Scanner(in, charset).useDelimiter(scanEndToken);
// this iterator will do look ahead as we may have data
// after the last end token, which the scanner would find
// so we need to be one step ahead of the scanner
- this.image = scanner.hasNext() ? next() : null;
+ this.image = scanner.hasNext() ? (String) next(true) : null;
}
@Override
- public boolean hasNext() {
- return image != null;
- }
+ String getNext(boolean first) {
+ String next = scanner.next();
+ if (next == null) {
+ return null;
+ }
- @Override
- public Object next() {
- Object answer = image;
- // calculate next
- if (scanner.hasNext()) {
- image = getNext();
+ // initialize inherited namespaces on first
+ if (first && inheritNamespaceToken != null) {
+ rootTokenNamespaces = getNamespacesFromNamespaceToken(next);
+ }
+
+ // make sure next is positioned at start token as we can have leading data
+ // or we reached EOL and there is no more start tags
+ Matcher matcher = startTokenPattern.matcher(next);
+ if (!matcher.find()) {
+ return null;
} else {
- image = null;
+ int index = matcher.start();
+ next = next.substring(index);
}
- if (answer == null) {
- // first time the image may be null
- answer = image;
+ // build answer accordingly to whether namespaces should be inherited or not
+ StringBuilder sb = new StringBuilder();
+ if (inheritNamespaceToken != null && rootTokenNamespaces != null) {
+ // append root namespaces to local start token
+ String tag = ObjectHelper.before(next, ">");
+ // grab the text
+ String text = ObjectHelper.after(next, ">");
+ // build result with inherited namespaces
+ next = sb.append(tag).append(rootTokenNamespaces).append(">").append(text).append(endToken).toString();
+ } else {
+ next = sb.append(next).append(endToken).toString();
}
- return answer;
+
+ return next;
}
- private Object getNext() {
- String next = scanner.next();
+ private String getNamespacesFromNamespaceToken(String text) {
+ if (text == null) {
+ return null;
+ }
- // only grab text after the start token
- if (next != null && next.contains(startToken)) {
- next = ObjectHelper.after(next, startToken);
-
- // include tokens in answer
- if (next != null) {
- StringBuilder sb = new StringBuilder();
- next = sb.append(startToken).append(next).append(endToken).toString();
- }
+ // grab the namespace tag
+ Matcher mat = inheritNamespaceTokenPattern.matcher(text);
+ if (mat.find()) {
+ text = mat.group(0);
} else {
- // must have start token, otherwise we have reached beyond last tokens
- // and should not return more data
+ // cannot find namespace tag
return null;
}
- return next;
- }
+ // find namespaces (there can be attributes mixed, so we should only grab the namespaces)
+ Map<String, String> namespaces = new LinkedHashMap<String, String>();
+ Matcher matcher = NAMESPACE_PATTERN.matcher(text);
+ while (matcher.find()) {
+ String prefix = matcher.group(1);
+ String url = matcher.group(2);
+ if (ObjectHelper.isEmpty(prefix)) {
+ prefix = "_DEFAULT_";
+ } else {
+ // skip leading :
+ prefix = prefix.substring(1);
+ }
+ namespaces.put(prefix, url);
+ }
- @Override
- public void remove() {
- // noop
- }
+ // did we find any namespaces
+ if (namespaces.isEmpty()) {
+ return null;
+ }
- @Override
- public void close() throws IOException {
- scanner.close();
+ // build namespace String
+ StringBuilder sb = new StringBuilder();
+ for (Map.Entry<String, String> entry : namespaces.entrySet()) {
+ String key = entry.getKey();
+ String value = entry.getValue();
+ if ("_DEFAULT_".equals(key)) {
+ sb.append(" xmlns=\"").append(value).append("\"");
+ } else {
+ sb.append(" xmlns:").append(key).append("=\"").append(value).append("\"");
+ }
+ }
+
+ return sb.toString();
}
}
Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/language/TokenPairIteratorSplitChoicePerformanceTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/language/TokenPairIteratorSplitChoicePerformanceTest.java?rev=1197168&r1=1197167&r2=1197168&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/language/TokenPairIteratorSplitChoicePerformanceTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/language/TokenPairIteratorSplitChoicePerformanceTest.java Thu Nov 3 14:53:02 2011
@@ -83,7 +83,7 @@ public class TokenPairIteratorSplitChoic
watch.restart();
}
})
- .split().tokenizePair("<order>", "</order>").streaming()
+ .split().tokenizeXML("<order>", "</order>").streaming()
.choice()
.when().xpath("/order/amount < 10")
.process(new Processor() {
Copied: camel/trunk/camel-core/src/test/java/org/apache/camel/language/TokenXMLPairNamespaceSplitTest.java (from r1197028, camel/trunk/camel-core/src/test/java/org/apache/camel/language/TokenPairPredicateTest.java)
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/language/TokenXMLPairNamespaceSplitTest.java?p2=camel/trunk/camel-core/src/test/java/org/apache/camel/language/TokenXMLPairNamespaceSplitTest.java&p1=camel/trunk/camel-core/src/test/java/org/apache/camel/language/TokenPairPredicateTest.java&r1=1197028&r2=1197168&rev=1197168&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/language/TokenPairPredicateTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/language/TokenXMLPairNamespaceSplitTest.java Thu Nov 3 14:53:02 2011
@@ -16,16 +16,15 @@
*/
package org.apache.camel.language;
-import java.io.File;
-
import org.apache.camel.ContextTestSupport;
import org.apache.camel.Exchange;
import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
/**
*
*/
-public class TokenPairPredicateTest extends ContextTestSupport {
+public class TokenXMLPairNamespaceSplitTest extends ContextTestSupport {
@Override
protected void setUp() throws Exception {
@@ -33,20 +32,27 @@ public class TokenPairPredicateTest exte
super.setUp();
}
- public void testTokenPairPredicate() throws Exception {
- getMockEndpoint("mock:result").expectedMessageCount(1);
+ public void testTokenXMLPair() throws Exception {
+ MockEndpoint mock = getMockEndpoint("mock:split");
+ mock.expectedMessageCount(3);
+ mock.message(0).body().isEqualTo("<order id=\"1\" xmlns=\"http:acme.com\">Camel in Action</order>");
+ mock.message(1).body().isEqualTo("<order id=\"2\" xmlns=\"http:acme.com\">ActiveMQ in Action</order>");
+ mock.message(2).body().isEqualTo("<order id=\"3\" xmlns=\"http:acme.com\">DSL in Action</order>");
- template.sendBodyAndHeader("file:target/pair", "<hello>world!</hello>", Exchange.FILE_NAME, "hello.xml");
+ String body = createBody();
+ template.sendBodyAndHeader("file:target/pair", body, Exchange.FILE_NAME, "orders.xml");
assertMockEndpointsSatisfied();
+ }
- oneExchangeDone.matchesMockWaitTime();
-
- File file = new File("target/pair/hello.xml");
- assertFalse("File should not exists " + file, file.exists());
-
- file = new File("target/pair/ok/hello.xml");
- assertTrue("File should exists " + file, file.exists());
+ private String createBody() {
+ StringBuilder sb = new StringBuilder("<?xml version=\"1.0\"?>\n");
+ sb.append("<orders xmlns=\"http:acme.com\">\n");
+ sb.append(" <order id=\"1\">Camel in Action</order>\n");
+ sb.append(" <order id=\"2\">ActiveMQ in Action</order>\n");
+ sb.append(" <order id=\"3\">DSL in Action</order>\n");
+ sb.append("</orders>");
+ return sb.toString();
}
@Override
@@ -54,12 +60,12 @@ public class TokenPairPredicateTest exte
return new RouteBuilder() {
@Override
public void configure() throws Exception {
- from("file:target/pair?move=ok")
- .choice()
- // does not make so much sense to use a tokenPair in a predicate
- // but you can do it nevertheless
- .when().tokenizePair("<hello>", "</hello>").to("mock:result")
- .end();
+ // START SNIPPET: e1
+ from("file:target/pair")
+ // split the order child tags, and inherit namespaces from the orders root tag
+ .split().tokenizeXML("order", "orders")
+ .to("mock:split");
+ // END SNIPPET: e1
}
};
}
Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/language/TokenizerTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/language/TokenizerTest.java?rev=1197168&r1=1197167&r2=1197168&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/language/TokenizerTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/language/TokenizerTest.java Thu Nov 3 14:53:02 2011
@@ -99,8 +99,8 @@ public class TokenizerTest extends Excha
assertEquals(false, lan.isSingleton());
}
- public void testTokenizePair() throws Exception {
- Expression exp = TokenizeLanguage.tokenizePair("<person>", "</person>");
+ public void testTokenizeXMLPair() throws Exception {
+ Expression exp = TokenizeLanguage.tokenizeXML("<person>", null);
exchange.getIn().setBody("<persons><person>James</person><person>Claus</person><person>Jonathan</person><person>Hadrian</person></persons>");
@@ -113,8 +113,22 @@ public class TokenizerTest extends Excha
assertEquals("<person>Hadrian</person>", names.get(3));
}
- public void testTokenizePairWithNoise() throws Exception {
- Expression exp = TokenizeLanguage.tokenizePair("<person>", "</person>");
+ public void testTokenizeXMLPairNoXMLTag() throws Exception {
+ Expression exp = TokenizeLanguage.tokenizeXML("person", null);
+
+ exchange.getIn().setBody("<persons><person>James</person><person>Claus</person><person>Jonathan</person><person>Hadrian</person></persons>");
+
+ List names = exp.evaluate(exchange, List.class);
+ assertEquals(4, names.size());
+
+ assertEquals("<person>James</person>", names.get(0));
+ assertEquals("<person>Claus</person>", names.get(1));
+ assertEquals("<person>Jonathan</person>", names.get(2));
+ assertEquals("<person>Hadrian</person>", names.get(3));
+ }
+
+ public void testTokenizeXMLPairWithNoise() throws Exception {
+ Expression exp = TokenizeLanguage.tokenizeXML("<person>", null);
exchange.getIn().setBody("<?xml version=\"1.0\"?><!-- bla bla --><persons>\n<person>James</person>\n<person>Claus</person>\n"
+ "<!-- more bla bla --><person>Jonathan</person>\n<person>Hadrian</person>\n</persons> ");
@@ -128,8 +142,8 @@ public class TokenizerTest extends Excha
assertEquals("<person>Hadrian</person>", names.get(3));
}
- public void testTokenizePairEmpty() throws Exception {
- Expression exp = TokenizeLanguage.tokenizePair("<person>", "</person>");
+ public void testTokenizeXMLPairEmpty() throws Exception {
+ Expression exp = TokenizeLanguage.tokenizeXML("<person>", null);
exchange.getIn().setBody("<?xml version=\"1.0\"?><!-- bla bla --><persons></persons> ");
@@ -137,8 +151,8 @@ public class TokenizerTest extends Excha
assertEquals(0, names.size());
}
- public void testTokenizePairNoData() throws Exception {
- Expression exp = TokenizeLanguage.tokenizePair("<person>", "</person>");
+ public void testTokenizeXMLPairNoData() throws Exception {
+ Expression exp = TokenizeLanguage.tokenizeXML("<person>", null);
exchange.getIn().setBody("");
@@ -146,8 +160,8 @@ public class TokenizerTest extends Excha
assertEquals(0, names.size());
}
- public void testTokenizePairNullData() throws Exception {
- Expression exp = TokenizeLanguage.tokenizePair("<person>", "</person>");
+ public void testTokenizeXMLPairNullData() throws Exception {
+ Expression exp = TokenizeLanguage.tokenizeXML("<person>", null);
exchange.getIn().setBody(null);
@@ -155,4 +169,139 @@ public class TokenizerTest extends Excha
assertNull(names);
}
+ public void testTokenizeXMLPairWithDefaultNamespace() throws Exception {
+ Expression exp = TokenizeLanguage.tokenizeXML("<person>", "<persons>");
+
+ exchange.getIn().setBody("<?xml version=\"1.0\"?><persons xmlns=\"http:acme.com/persons\">\n<person>James</person>\n<person>Claus</person>\n"
+ + "<person>Jonathan</person>\n<person>Hadrian</person>\n</persons>\n");
+
+ List names = exp.evaluate(exchange, List.class);
+ assertEquals(4, names.size());
+
+ assertEquals("<person xmlns=\"http:acme.com/persons\">James</person>", names.get(0));
+ assertEquals("<person xmlns=\"http:acme.com/persons\">Claus</person>", names.get(1));
+ assertEquals("<person xmlns=\"http:acme.com/persons\">Jonathan</person>", names.get(2));
+ assertEquals("<person xmlns=\"http:acme.com/persons\">Hadrian</person>", names.get(3));
+ }
+
+ public void testTokenizeXMLPairWithDefaultNamespaceNotInherit() throws Exception {
+ Expression exp = TokenizeLanguage.tokenizeXML("<person>", null);
+
+ exchange.getIn().setBody("<?xml version=\"1.0\"?><persons xmlns=\"http:acme.com/persons\">\n<person>James</person>\n<person>Claus</person>\n"
+ + "<person>Jonathan</person>\n<person>Hadrian</person>\n</persons>\n");
+
+ List names = exp.evaluate(exchange, List.class);
+ assertEquals(4, names.size());
+
+ assertEquals("<person>James</person>", names.get(0));
+ assertEquals("<person>Claus</person>", names.get(1));
+ assertEquals("<person>Jonathan</person>", names.get(2));
+ assertEquals("<person>Hadrian</person>", names.get(3));
+ }
+
+ public void testTokenizeXMLPairWithDefaultAndFooNamespace() throws Exception {
+ Expression exp = TokenizeLanguage.tokenizeXML("<person>", "<persons>");
+
+ exchange.getIn().setBody("<?xml version=\"1.0\"?><persons xmlns=\"http:acme.com/persons\" xmlns:foo=\"http:foo.com\">\n<person>James</person>\n<person>Claus</person>\n"
+ + "<person>Jonathan</person>\n<person>Hadrian</person>\n</persons>\n");
+
+ List names = exp.evaluate(exchange, List.class);
+ assertEquals(4, names.size());
+
+ assertEquals("<person xmlns=\"http:acme.com/persons\" xmlns:foo=\"http:foo.com\">James</person>", names.get(0));
+ assertEquals("<person xmlns=\"http:acme.com/persons\" xmlns:foo=\"http:foo.com\">Claus</person>", names.get(1));
+ assertEquals("<person xmlns=\"http:acme.com/persons\" xmlns:foo=\"http:foo.com\">Jonathan</person>", names.get(2));
+ assertEquals("<person xmlns=\"http:acme.com/persons\" xmlns:foo=\"http:foo.com\">Hadrian</person>", names.get(3));
+ }
+
+ public void testTokenizeXMLPairWithLocalNamespace() throws Exception {
+ Expression exp = TokenizeLanguage.tokenizeXML("<person>", null);
+
+ exchange.getIn().setBody("<?xml version=\"1.0\"?><persons>\n<person xmlns=\"http:acme.com/persons\">James</person>\n<person xmlns=\"http:acme.com/persons\">Claus</person>\n"
+ + "<person xmlns=\"http:acme.com/persons\">Jonathan</person>\n<person xmlns=\"http:acme.com/persons\">Hadrian</person>\n</persons>\n");
+
+ List names = exp.evaluate(exchange, List.class);
+ assertEquals(4, names.size());
+
+ assertEquals("<person xmlns=\"http:acme.com/persons\">James</person>", names.get(0));
+ assertEquals("<person xmlns=\"http:acme.com/persons\">Claus</person>", names.get(1));
+ assertEquals("<person xmlns=\"http:acme.com/persons\">Jonathan</person>", names.get(2));
+ assertEquals("<person xmlns=\"http:acme.com/persons\">Hadrian</person>", names.get(3));
+ }
+
+ public void testTokenizeXMLPairWithLocalAndInheritedNamespace() throws Exception {
+ Expression exp = TokenizeLanguage.tokenizeXML("<person>", "<persons>");
+
+ exchange.getIn().setBody("<?xml version=\"1.0\"?><persons xmlns=\"http:acme.com/persons\">\n<person xmlns:foo=\"http:foo.com\">James</person>\n<person>Claus</person>\n"
+ + "<person>Jonathan</person>\n<person xmlns:bar=\"http:bar.com\">Hadrian</person>\n</persons>\n");
+
+ List names = exp.evaluate(exchange, List.class);
+ assertEquals(4, names.size());
+
+ assertEquals("<person xmlns:foo=\"http:foo.com\" xmlns=\"http:acme.com/persons\">James</person>", names.get(0));
+ assertEquals("<person xmlns=\"http:acme.com/persons\">Claus</person>", names.get(1));
+ assertEquals("<person xmlns=\"http:acme.com/persons\">Jonathan</person>", names.get(2));
+ assertEquals("<person xmlns:bar=\"http:bar.com\" xmlns=\"http:acme.com/persons\">Hadrian</person>", names.get(3));
+ }
+
+ public void testTokenizeXMLPairWithLocalAndNotInheritedNamespace() throws Exception {
+ Expression exp = TokenizeLanguage.tokenizeXML("<person>", null);
+
+ exchange.getIn().setBody("<?xml version=\"1.0\"?><persons xmlns=\"http:acme.com/persons\">\n<person xmlns:foo=\"http:foo.com\">James</person>\n"
+ + "<person>Claus</person>\n<person>Jonathan</person>\n<person xmlns:bar=\"http:bar.com\">Hadrian</person>\n</persons>\n");
+
+ List names = exp.evaluate(exchange, List.class);
+ assertEquals(4, names.size());
+
+ assertEquals("<person xmlns:foo=\"http:foo.com\">James</person>", names.get(0));
+ assertEquals("<person>Claus</person>", names.get(1));
+ assertEquals("<person>Jonathan</person>", names.get(2));
+ assertEquals("<person xmlns:bar=\"http:bar.com\">Hadrian</person>", names.get(3));
+ }
+
+ public void testTokenizeXMLPairWithAttributes() throws Exception {
+ Expression exp = TokenizeLanguage.tokenizeXML("<person>", null);
+
+ exchange.getIn().setBody("<persons><person id=\"1\">James</person><person id=\"2\">Claus</person><person id=\"3\">Jonathan</person>"
+ + "<person id=\"4\">Hadrian</person></persons>");
+
+ List names = exp.evaluate(exchange, List.class);
+ assertEquals(4, names.size());
+
+ assertEquals("<person id=\"1\">James</person>", names.get(0));
+ assertEquals("<person id=\"2\">Claus</person>", names.get(1));
+ assertEquals("<person id=\"3\">Jonathan</person>", names.get(2));
+ assertEquals("<person id=\"4\">Hadrian</person>", names.get(3));
+ }
+
+ public void testTokenizeXMLPairWithAttributesInheritNamespace() throws Exception {
+ Expression exp = TokenizeLanguage.tokenizeXML("<person>", "<persons>");
+
+ exchange.getIn().setBody("<persons xmlns=\"http:acme.com/persons\"><person id=\"1\">James</person><person id=\"2\">Claus</person>"
+ + "<person id=\"3\">Jonathan</person><person id=\"4\">Hadrian</person></persons>");
+
+ List names = exp.evaluate(exchange, List.class);
+ assertEquals(4, names.size());
+
+ assertEquals("<person id=\"1\" xmlns=\"http:acme.com/persons\">James</person>", names.get(0));
+ assertEquals("<person id=\"2\" xmlns=\"http:acme.com/persons\">Claus</person>", names.get(1));
+ assertEquals("<person id=\"3\" xmlns=\"http:acme.com/persons\">Jonathan</person>", names.get(2));
+ assertEquals("<person id=\"4\" xmlns=\"http:acme.com/persons\">Hadrian</person>", names.get(3));
+ }
+
+ public void testTokenizeXMLPairWithAttributes2InheritNamespace() throws Exception {
+ Expression exp = TokenizeLanguage.tokenizeXML("<person>", "<persons>");
+
+ exchange.getIn().setBody("<persons riders=\"true\" xmlns=\"http:acme.com/persons\"><person id=\"1\">James</person><person id=\"2\">Claus</person>"
+ + "<person id=\"3\">Jonathan</person><person id=\"4\">Hadrian</person></persons>");
+
+ List names = exp.evaluate(exchange, List.class);
+ assertEquals(4, names.size());
+
+ assertEquals("<person id=\"1\" xmlns=\"http:acme.com/persons\">James</person>", names.get(0));
+ assertEquals("<person id=\"2\" xmlns=\"http:acme.com/persons\">Claus</person>", names.get(1));
+ assertEquals("<person id=\"3\" xmlns=\"http:acme.com/persons\">Jonathan</person>", names.get(2));
+ assertEquals("<person id=\"4\" xmlns=\"http:acme.com/persons\">Hadrian</person>", names.get(3));
+ }
+
}
\ No newline at end of file
Added: camel/trunk/components/camel-spring/src/test/java/org/apache/camel/language/SpringTokenXMLPairNamespaceSplitTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/language/SpringTokenXMLPairNamespaceSplitTest.java?rev=1197168&view=auto
==============================================================================
--- camel/trunk/components/camel-spring/src/test/java/org/apache/camel/language/SpringTokenXMLPairNamespaceSplitTest.java (added)
+++ camel/trunk/components/camel-spring/src/test/java/org/apache/camel/language/SpringTokenXMLPairNamespaceSplitTest.java Thu Nov 3 14:53:02 2011
@@ -0,0 +1,32 @@
+/**
+ * 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.CamelContext;
+
+import static org.apache.camel.spring.processor.SpringTestHelper.createSpringCamelContext;
+
+/**
+ *
+ */
+public class SpringTokenXMLPairNamespaceSplitTest extends TokenXMLPairNamespaceSplitTest {
+
+ protected CamelContext createCamelContext() throws Exception {
+ return createSpringCamelContext(this, "org/apache/camel/language/SpringTokenXMLPairNamespaceSplitTest.xml");
+ }
+
+}
Copied: camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/language/SpringTokenXMLPairNamespaceSplitTest.xml (from r1197028, camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/aopbefore.xml)
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/language/SpringTokenXMLPairNamespaceSplitTest.xml?p2=camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/language/SpringTokenXMLPairNamespaceSplitTest.xml&p1=camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/aopbefore.xml&r1=1197028&r2=1197168&rev=1197168&view=diff
==============================================================================
--- camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/aopbefore.xml (original)
+++ camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/language/SpringTokenXMLPairNamespaceSplitTest.xml Thu Nov 3 14:53:02 2011
@@ -22,16 +22,19 @@
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
">
- <!-- START SNIPPET: e1 -->
- <camelContext xmlns="http://camel.apache.org/schema/spring">
- <route>
- <from uri="direct:start"/>
- <aop beforeUri="mock:before">
- <transform><constant>Bye World</constant></transform>
- <to uri="mock:result"/>
- </aop>
- </route>
- </camelContext>
- <!-- END SNIPPET: e1 -->
+ <!-- START SNIPPET: e1 -->
+ <camelContext xmlns="http://camel.apache.org/schema/spring">
+ <route>
+ <from uri="file:target/pair"/>
+ <split>
+ <!-- split the file using XML tokenizer, where we grab the order tag,
+ and inherit the namespaces from the parent/root orders tag
+ the xml attribute must be set to true, to enable XML mode -->
+ <tokenize token="order" inheritNamespaceTagName="orders" xml="true"/>
+ <to uri="mock:split"/>
+ </split>
+ </route>
+ </camelContext>
+ <!-- END SNIPPET: e1 -->
</beans>