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/02/24 10:06:57 UTC

camel git commit: CAMEL-6934: Xtokenize with streaming() does not close stream.

Repository: camel
Updated Branches:
  refs/heads/camel-2.16.x b77804759 -> ecc996602


CAMEL-6934: Xtokenize with streaming() does not close stream.


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/ecc99660
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/ecc99660
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/ecc99660

Branch: refs/heads/camel-2.16.x
Commit: ecc9966026c0752b5d78081c822bd58c34bc5abf
Parents: b778047
Author: Claus Ibsen <da...@apache.org>
Authored: Wed Feb 24 10:05:36 2016 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Wed Feb 24 10:06:26 2016 +0100

----------------------------------------------------------------------
 .../support/XMLTokenExpressionIterator.java     | 34 +++++------
 .../XMLTokenizeLanguageStreamingFileTest.java   | 64 ++++++++++++++++++++
 .../XMLTokenizeLanguageStreamingTest.java       | 37 +++++++++++
 3 files changed, 118 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/ecc99660/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 a9f605e..fdb5088 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
@@ -48,7 +48,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- *
+ * An {@link org.apache.camel.language.tokenizer.XMLTokenizeLanguage} based iterator.
  */
 public class XMLTokenExpressionIterator extends ExpressionAdapter implements NamespaceAware {
     protected final String path;
@@ -89,19 +89,11 @@ public class XMLTokenExpressionIterator extends ExpressionAdapter implements Nam
     }
 
     protected Iterator<?> createIterator(InputStream in, String charset) throws XMLStreamException, UnsupportedEncodingException {
-        Reader reader;
-        if (charset == null) {
-            reader = new InputStreamReader(in);
-        } else {
-            reader = new InputStreamReader(in, charset);
-        }
-        XMLTokenIterator iterator = new XMLTokenIterator(path, nsmap, mode, group, reader);
-        return iterator;
+        return new XMLTokenIterator(path, nsmap, mode, group, in, charset);
     }
 
     protected Iterator<?> createIterator(Reader in) throws XMLStreamException {
-        XMLTokenIterator iterator = new XMLTokenIterator(path, nsmap, mode, group, in);
-        return iterator;
+        return new XMLTokenIterator(path, nsmap, mode, group, in);
     }
 
     @Override
@@ -158,6 +150,8 @@ 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 transient InputStream originalInputStream;
+
         private AttributedQName[] splitpath;
         private int index;
         private char mode;
@@ -182,12 +176,14 @@ public class XMLTokenExpressionIterator extends ExpressionAdapter implements Nam
             throws XMLStreamException, UnsupportedEncodingException {
             // woodstox's getLocation().etCharOffset() does not return the offset correctly for InputStream, so use Reader instead.
             this(path, nsmap, mode, 1, new InputStreamReader(in, charset));
+            this.originalInputStream = in;
         }
 
         public XMLTokenIterator(String path, Map<String, String> nsmap, char mode, int group, InputStream in, String charset) 
             throws XMLStreamException, UnsupportedEncodingException {
             // woodstox's getLocation().etCharOffset() does not return the offset correctly for InputStream, so use Reader instead.
-            this(path, nsmap, mode, new InputStreamReader(in, charset));
+            this(path, nsmap, mode, group, new InputStreamReader(in, charset));
+            this.originalInputStream = in;
         }
 
         public XMLTokenIterator(String path, Map<String, String> nsmap, char mode, Reader in) throws XMLStreamException {
@@ -278,7 +274,7 @@ public class XMLTokenExpressionIterator extends ExpressionAdapter implements Nam
             return c;
         }
         
-        private String getCurrenText() {
+        private String getCurrentText() {
             int pos = reader.getLocation().getCharacterOffset();
             String txt = in.getText(pos - consumed);
             consumed = pos;
@@ -357,7 +353,7 @@ public class XMLTokenExpressionIterator extends ExpressionAdapter implements Nam
             readCurrent(true);
             popName();
             
-            String token = createContextualToken(getCurrenText());
+            String token = createContextualToken(getCurrentText());
             if (mode == 'i') {
                 popNamespaces();
             }
@@ -466,7 +462,7 @@ public class XMLTokenExpressionIterator extends ExpressionAdapter implements Nam
                         LOG.trace("se={}; depth={}; trackdepth={}", new Object[]{name, depth, trackdepth});
                     }
                     
-                    String token = getCurrenText();
+                    String token = getCurrentText();
                     // perform the second compliance test
                     if (!compliant) {
                         if (token != null && token.startsWith("<") && !token.startsWith("<?")) {
@@ -600,8 +596,12 @@ public class XMLTokenExpressionIterator extends ExpressionAdapter implements Nam
         public void close() throws IOException {
             try {
                 reader.close();
-            } catch (XMLStreamException e) {
-                throw new IOException(e);
+            } catch (Exception e) {
+                // ignore
+            }
+            // need to close the original input stream as well as the reader do not delegate close it
+            if (originalInputStream != null) {
+                IOHelper.close(originalInputStream);
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/ecc99660/camel-core/src/test/java/org/apache/camel/language/tokenizer/XMLTokenizeLanguageStreamingFileTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/language/tokenizer/XMLTokenizeLanguageStreamingFileTest.java b/camel-core/src/test/java/org/apache/camel/language/tokenizer/XMLTokenizeLanguageStreamingFileTest.java
new file mode 100644
index 0000000..4b84300
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/language/tokenizer/XMLTokenizeLanguageStreamingFileTest.java
@@ -0,0 +1,64 @@
+/**
+ * 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.tokenizer;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.builder.xml.Namespaces;
+
+public class XMLTokenizeLanguageStreamingFileTest extends ContextTestSupport {
+
+    @Override
+    protected void setUp() throws Exception {
+        deleteDirectory("target/xmltokenize");
+        super.setUp();
+    }
+
+    public void testFromFile() throws Exception {
+        getMockEndpoint("mock:result").expectedBodiesReceived("<c:child some_attr='a' anotherAttr='a' xmlns:c=\"urn:c\"></c:child>",
+                "<c:child some_attr='b' anotherAttr='b' xmlns:c=\"urn:c\"></c:child>",
+                "<c:child some_attr='c' anotherAttr='c' xmlns:c=\"urn:c\"></c:child>",
+                "<c:child some_attr='d' anotherAttr='d' xmlns:c=\"urn:c\"></c:child>");
+
+        String body = "<?xml version='1.0' encoding='UTF-8'?>"
+                + "<c:parent xmlns:c='urn:c'>"
+                +   "<c:child some_attr='a' anotherAttr='a'></c:child>"
+                +   "<c:child some_attr='b' anotherAttr='b'></c:child>"
+                +   "<c:child some_attr='c' anotherAttr='c'></c:child>"
+                +   "<c:child some_attr='d' anotherAttr='d'></c:child>"
+                + "</c:parent>";
+
+        deleteDirectory("target/xmltokenize");
+        template.sendBodyAndHeader("file:target/xmltokenize", body, Exchange.FILE_NAME, "myxml.xml");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            Namespaces ns = new Namespaces("C", "urn:c");
+            public void configure() {
+                from("file:target/xmltokenize")
+                    .split().xtokenize("//C:child", ns).streaming()
+                        .to("mock:result")
+                    .end();
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/ecc99660/camel-core/src/test/java/org/apache/camel/language/tokenizer/XMLTokenizeLanguageStreamingTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/language/tokenizer/XMLTokenizeLanguageStreamingTest.java b/camel-core/src/test/java/org/apache/camel/language/tokenizer/XMLTokenizeLanguageStreamingTest.java
new file mode 100644
index 0000000..9f14c47
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/language/tokenizer/XMLTokenizeLanguageStreamingTest.java
@@ -0,0 +1,37 @@
+/**
+ * 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.tokenizer;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.builder.xml.Namespaces;
+
+public class XMLTokenizeLanguageStreamingTest extends XMLTokenizeLanguageTest {
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            Namespaces ns = new Namespaces("C", "urn:c");
+            public void configure() {
+                from("direct:start")
+                    .split().xtokenize("//C:child", ns).streaming()
+                        .to("mock:result")
+                    .end();
+            }
+        };
+    }
+}