You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ni...@apache.org on 2014/01/24 07:35:52 UTC

[3/6] git commit: CAMEL-7130 fixed the issue of using stax with Xalan 2.7.1

CAMEL-7130 fixed the issue of using stax with Xalan 2.7.1


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

Branch: refs/heads/camel-2.11.x
Commit: 40b1576475ac09213cb7dd5bea46851e33b6d3ad
Parents: 363c89e
Author: Willem Jiang <wi...@gmail.com>
Authored: Fri Jan 24 10:27:54 2014 +0800
Committer: Willem Jiang <wi...@gmail.com>
Committed: Fri Jan 24 14:06:24 2014 +0800

----------------------------------------------------------------------
 .../apache/camel/builder/xml/XsltBuilder.java   |  25 +-
 .../apache/camel/converter/jaxp/StaxSource.java | 279 +++++++++++++++++++
 2 files changed, 301 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/40b15764/camel-core/src/main/java/org/apache/camel/builder/xml/XsltBuilder.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/builder/xml/XsltBuilder.java b/camel-core/src/main/java/org/apache/camel/builder/xml/XsltBuilder.java
index d4291b2..8406794 100644
--- a/camel-core/src/main/java/org/apache/camel/builder/xml/XsltBuilder.java
+++ b/camel-core/src/main/java/org/apache/camel/builder/xml/XsltBuilder.java
@@ -27,6 +27,8 @@ import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.BlockingQueue;
 
 import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLStreamReader;
 import javax.xml.transform.ErrorListener;
 import javax.xml.transform.Result;
 import javax.xml.transform.Source;
@@ -48,6 +50,7 @@ import org.apache.camel.Message;
 import org.apache.camel.Processor;
 import org.apache.camel.RuntimeTransformException;
 import org.apache.camel.TypeConverter;
+import org.apache.camel.converter.jaxp.StaxSource;
 import org.apache.camel.converter.jaxp.XmlConverter;
 import org.apache.camel.converter.jaxp.XmlErrorListener;
 import org.apache.camel.support.SynchronizationAdapter;
@@ -107,7 +110,7 @@ public class XsltBuilder implements Processor {
         transformer.setErrorListener(new DefaultTransformErrorHandler());
         ResultHandler resultHandler = resultHandlerFactory.createResult(exchange);
         Result result = resultHandler.getResult();
-
+        exchange.setProperty("isXalanTransformer", isXalanTransformer(transformer));
         // let's copy the headers before we invoke the transform in case they modify them
         Message out = exchange.getOut();
         out.copyFrom(exchange.getIn());
@@ -129,11 +132,17 @@ public class XsltBuilder implements Processor {
             LOG.trace("Transform complete with result {}", result);
             resultHandler.setBody(out);
         } finally {
+            // clean up the setting on the exchange
+            
             releaseTransformer(transformer);
             // IOHelper can handle if is is null
             IOHelper.close(is);
         }
     }
+    
+    private boolean isXalanTransformer(Transformer transformer) {
+        return transformer.getClass().getName().startsWith("org.apache.xalan.transformer");
+    }
 
     // Builder methods
     // -------------------------------------------------------------------------
@@ -447,14 +456,23 @@ public class XsltBuilder implements Processor {
      * </ul>
      */
     protected Source getSource(Exchange exchange, Object body) {
+        Boolean isXalanTransformer = exchange.getProperty("isXalanTransformer", Boolean.class);
         // body may already be a source
         if (body instanceof Source) {
             return (Source) body;
         }
         Source source = null;
         if (body != null) {
-            if (isAllowStAX()) {
-                source = exchange.getContext().getTypeConverter().tryConvertTo(StAXSource.class, exchange, body);
+            if (isXalanTransformer) {
+                XMLStreamReader reader = exchange.getContext().getTypeConverter().tryConvertTo(XMLStreamReader.class, exchange, body);
+                if (reader != null) {
+                    // create a new SAXSource with stax parser API
+                    source = new StaxSource(reader);
+                }
+            } else {
+                if (isAllowStAX()) {
+                    source = exchange.getContext().getTypeConverter().tryConvertTo(StAXSource.class, exchange, body);
+                }
             }
             if (source == null) {
                 // then try SAX
@@ -490,6 +508,7 @@ public class XsltBuilder implements Processor {
         }
         return source;
     }
+   
 
     /**
      * Configures the transformer with exchange specific parameters

http://git-wip-us.apache.org/repos/asf/camel/blob/40b15764/camel-core/src/main/java/org/apache/camel/converter/jaxp/StaxSource.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/converter/jaxp/StaxSource.java b/camel-core/src/main/java/org/apache/camel/converter/jaxp/StaxSource.java
new file mode 100644
index 0000000..0fb6a6d
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/converter/jaxp/StaxSource.java
@@ -0,0 +1,279 @@
+/**
+ * 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.converter.jaxp;
+
+import javax.xml.XMLConstants;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.transform.sax.SAXSource;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.ext.LexicalHandler;
+import org.xml.sax.helpers.AttributesImpl;
+
+public class StaxSource extends SAXSource implements XMLReader {
+
+    private XMLStreamReader streamReader;
+
+    private ContentHandler contentHandler;
+    
+    private LexicalHandler lexicalHandler;
+
+    public StaxSource(XMLStreamReader streamReader) {
+        this.streamReader = streamReader;
+        setInputSource(new InputSource());
+    }
+
+    public XMLReader getXMLReader() {
+        return this;
+    }
+
+    public XMLStreamReader getXMLStreamReader() {
+        return streamReader;
+    }
+
+    protected void parse() throws SAXException {
+        try {
+            while (true) {
+                switch (streamReader.getEventType()) {
+                // Attributes are handled in START_ELEMENT
+                case XMLStreamConstants.ATTRIBUTE:
+                    break;
+                case XMLStreamConstants.CDATA:
+                {
+                    if (lexicalHandler != null) {
+                        lexicalHandler.startCDATA();
+                    }
+                    int length = streamReader.getTextLength();
+                    int start = streamReader.getTextStart();
+                    char[] chars = streamReader.getTextCharacters();
+                    contentHandler.characters(chars, start, length);
+                    if (lexicalHandler != null) {
+                        lexicalHandler.endCDATA();
+                    }
+                    break;
+                }
+                case XMLStreamConstants.CHARACTERS:
+                {
+                    int length = streamReader.getTextLength();
+                    int start = streamReader.getTextStart();
+                    char[] chars = streamReader.getTextCharacters();
+                    contentHandler.characters(chars, start, length);
+                    break;
+                }
+                case XMLStreamConstants.SPACE:
+                {
+                    int length = streamReader.getTextLength();
+                    int start = streamReader.getTextStart();
+                    char[] chars = streamReader.getTextCharacters();
+                    contentHandler.ignorableWhitespace(chars, start, length);
+                    break;
+                }
+                case XMLStreamConstants.COMMENT:
+                    if (lexicalHandler != null) {
+                        int length = streamReader.getTextLength();
+                        int start = streamReader.getTextStart();
+                        char[] chars = streamReader.getTextCharacters();
+                        lexicalHandler.comment(chars, start, length);
+                    } 
+                    break;
+                case XMLStreamConstants.DTD:
+                    break;
+                case XMLStreamConstants.END_DOCUMENT:
+                    contentHandler.endDocument();
+                    return;
+                case XMLStreamConstants.END_ELEMENT: {
+                    String uri = streamReader.getNamespaceURI();
+                    String localName = streamReader.getLocalName();
+                    String prefix = streamReader.getPrefix();
+                    String qname = prefix != null && prefix.length() > 0 
+                        ? prefix + ":" + localName : localName;
+                    contentHandler.endElement(uri, localName, qname);
+                    break;
+                }
+                case XMLStreamConstants.ENTITY_DECLARATION:
+                case XMLStreamConstants.ENTITY_REFERENCE:
+                case XMLStreamConstants.NAMESPACE:
+                case XMLStreamConstants.NOTATION_DECLARATION:
+                    break;
+                case XMLStreamConstants.PROCESSING_INSTRUCTION:
+                    break;
+                case XMLStreamConstants.START_DOCUMENT:
+                    contentHandler.startDocument();
+                    break;
+                case XMLStreamConstants.START_ELEMENT: {
+                    String uri = streamReader.getNamespaceURI();
+                    String localName = streamReader.getLocalName();
+                    String prefix = streamReader.getPrefix();
+                    String qname = prefix != null && prefix.length() > 0 
+                        ? prefix + ":" + localName : localName;
+                    contentHandler.startElement(uri == null ? "" : uri, localName, qname, getAttributes());
+                    break;
+                }
+                default:
+                    break;
+                }
+                if (!streamReader.hasNext()) {
+                    return;
+                }
+                streamReader.next();
+            }
+        } catch (XMLStreamException e) {
+            SAXParseException spe;
+            if (e.getLocation() != null) {
+                spe = new SAXParseException(e.getMessage(), null, null,
+                                            e.getLocation().getLineNumber(),
+                                            e.getLocation().getColumnNumber(), e);
+            } else {
+                spe = new SAXParseException(e.getMessage(), null, null, -1, -1, e);
+            }
+            spe.initCause(e);
+            throw spe;
+        }
+    }
+
+    protected String getQualifiedName() {
+        String prefix = streamReader.getPrefix();
+        if (prefix != null && prefix.length() > 0) {
+            return prefix + ":" + streamReader.getLocalName();
+        } else {
+            return streamReader.getLocalName();
+        }
+    }
+
+    protected Attributes getAttributes() {
+        AttributesImpl attrs = new AttributesImpl();
+        // Adding namespace declaration as attributes is necessary because
+        // the xalan implementation that ships with SUN JDK 1.4 is bugged
+        // and does not handle the startPrefixMapping method
+        for (int i = 0; i < streamReader.getNamespaceCount(); i++) {
+            String prefix = streamReader.getNamespacePrefix(i);
+            String uri = streamReader.getNamespaceURI(i);
+            if (uri == null) {
+                uri = "";
+            }
+            // Default namespace
+            if (prefix == null || prefix.length() == 0) {
+                attrs.addAttribute("", 
+                                   "", 
+                                   XMLConstants.XMLNS_ATTRIBUTE, 
+                                   "CDATA", 
+                                   uri);
+            } else {
+                attrs.addAttribute(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, 
+                                   prefix, 
+                                   XMLConstants.XMLNS_ATTRIBUTE + ":" + prefix, 
+                                   "CDATA", 
+                                   uri);
+            }
+        }
+        for (int i = 0; i < streamReader.getAttributeCount(); i++) {
+            String uri = streamReader.getAttributeNamespace(i);
+            String localName = streamReader.getAttributeLocalName(i);
+            String prefix = streamReader.getAttributePrefix(i);
+            String qName;
+            if (prefix != null && prefix.length() > 0) {
+                qName = prefix + ':' + localName;
+            } else {
+                qName = localName;
+            }
+            String type = streamReader.getAttributeType(i);
+            String value = streamReader.getAttributeValue(i);
+            if (value == null) {
+                value = "";
+            }
+
+            attrs.addAttribute(uri == null ? "" : uri, localName, qName, type, value);
+        }
+        return attrs;
+    }
+
+    public boolean getFeature(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
+        return false;
+    }
+
+    public void setFeature(String name, boolean value) 
+        throws SAXNotRecognizedException, SAXNotSupportedException {
+    }
+
+    public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
+        return null;
+    }
+
+    public void setProperty(String name, Object value) 
+        throws SAXNotRecognizedException, SAXNotSupportedException {
+        if ("http://xml.org/sax/properties/lexical-handler".equals(name)) {
+            lexicalHandler = (LexicalHandler) value;
+        } else {
+            throw new SAXNotRecognizedException(name);
+        }
+    }
+
+    public void setEntityResolver(EntityResolver resolver) {
+    }
+
+    public EntityResolver getEntityResolver() {
+        return null;
+    }
+
+    public void setDTDHandler(DTDHandler handler) {
+    }
+
+    public DTDHandler getDTDHandler() {
+        return null;
+    }
+
+    public void setContentHandler(ContentHandler handler) {
+        this.contentHandler = handler;
+        if (handler instanceof LexicalHandler
+            && lexicalHandler == null) {
+            lexicalHandler = (LexicalHandler)handler;
+        }
+    }
+
+    public ContentHandler getContentHandler() {
+        return this.contentHandler;
+    }
+
+    public void setErrorHandler(ErrorHandler handler) {
+    }
+
+    public ErrorHandler getErrorHandler() {
+        return null;
+    }
+
+    public void parse(InputSource input) throws SAXException {
+        StaxSource.this.parse();
+    }
+
+    public void parse(String systemId) throws SAXException {
+        StaxSource.this.parse();
+    }
+
+}