Coverage Report - org.apache.camel.converter.jaxp.XmlConverter
 
Classes in this File Line Coverage Branch Coverage Complexity
XmlConverter
29% 
25% 
0
 
 1  
 /**
 2  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  
  * contributor license agreements.  See the NOTICE file distributed with
 4  
  * this work for additional information regarding copyright ownership.
 5  
  * The ASF licenses this file to You under the Apache License, Version 2.0
 6  
  * (the "License"); you may not use this file except in compliance with
 7  
  * the License.  You may obtain a copy of the License at
 8  
  *
 9  
  *      http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 package org.apache.camel.converter.jaxp;
 18  
 
 19  
 import org.apache.camel.Converter;
 20  
 import org.apache.camel.converter.IOConverter;
 21  
 import org.apache.camel.converter.NIOConverter;
 22  
 import org.apache.camel.util.ObjectHelper;
 23  
 import org.w3c.dom.Document;
 24  
 import org.w3c.dom.Element;
 25  
 import org.w3c.dom.Node;
 26  
 import org.xml.sax.InputSource;
 27  
 import org.xml.sax.SAXException;
 28  
 import org.xml.sax.XMLReader;
 29  
 
 30  
 import javax.xml.parsers.DocumentBuilder;
 31  
 import javax.xml.parsers.DocumentBuilderFactory;
 32  
 import javax.xml.parsers.ParserConfigurationException;
 33  
 import javax.xml.transform.OutputKeys;
 34  
 import javax.xml.transform.Result;
 35  
 import javax.xml.transform.Source;
 36  
 import javax.xml.transform.Transformer;
 37  
 import javax.xml.transform.TransformerConfigurationException;
 38  
 import javax.xml.transform.TransformerException;
 39  
 import javax.xml.transform.TransformerFactory;
 40  
 import javax.xml.transform.dom.DOMResult;
 41  
 import javax.xml.transform.dom.DOMSource;
 42  
 import javax.xml.transform.sax.SAXSource;
 43  
 import javax.xml.transform.stream.StreamResult;
 44  
 import javax.xml.transform.stream.StreamSource;
 45  
 import java.io.ByteArrayInputStream;
 46  
 import java.io.File;
 47  
 import java.io.IOException;
 48  
 import java.io.InputStream;
 49  
 import java.io.InputStreamReader;
 50  
 import java.io.Reader;
 51  
 import java.io.StringReader;
 52  
 import java.io.StringWriter;
 53  
 import java.lang.reflect.Constructor;
 54  
 import java.nio.ByteBuffer;
 55  
 
 56  
 /**
 57  
  * A helper class to transform to and from various JAXB types such as {@link Source} and {@link Document}
 58  
  *
 59  
  * @version $Revision: 563665 $
 60  
  */
 61  
 @Converter
 62  
 public class XmlConverter {
 63  
     public static final String DEFAULT_CHARSET_PROPERTY = "org.apache.camel.default.charset";
 64  
 
 65  3
     public static String defaultCharset = ObjectHelper.getSystemProperty(DEFAULT_CHARSET_PROPERTY, "UTF-8");
 66  
 
 67  
     private DocumentBuilderFactory documentBuilderFactory;
 68  
     private TransformerFactory transformerFactory;
 69  
 
 70  
     /*
 71  
      * When converting a DOM tree to a SAXSource,
 72  
      * we try to use Xalan internal DOM parser if
 73  
      * available.  Else, transform the DOM tree
 74  
      * to a String and build a SAXSource on top of
 75  
      * it.
 76  
      */
 77  
     private static final Class dom2SaxClass;
 78  
 
 79  
     static {
 80  3
         Class cl = null;
 81  
         try {
 82  3
             cl = Class.forName("org.apache.xalan.xsltc.trax.DOM2SAX");
 83  0
         } catch (Throwable t) {}
 84  3
         dom2SaxClass = cl;
 85  3
     }
 86  
 
 87  
 
 88  69
     public XmlConverter() {
 89  69
     }
 90  
 
 91  0
     public XmlConverter(DocumentBuilderFactory documentBuilderFactory) {
 92  0
         this.documentBuilderFactory = documentBuilderFactory;
 93  0
     }
 94  
 
 95  
 
 96  
     /**
 97  
      * Converts the given input Source into the required result
 98  
      */
 99  
     public void toResult(Source source, Result result) throws TransformerException {
 100  3
         if (source == null) {
 101  0
             return;
 102  
         }
 103  3
         Transformer transformer = createTransfomer();
 104  3
         if (transformer == null) {
 105  0
             throw new TransformerException("Could not create a transformer - JAXP is misconfigured!");
 106  
         }
 107  3
         transformer.setOutputProperty(OutputKeys.ENCODING, defaultCharset);
 108  3
         transformer.transform(source, result);
 109  3
     }
 110  
 
 111  
     /**
 112  
      * Converts the given byte[] to a Source
 113  
      */
 114  
     @Converter
 115  
     public BytesSource toSource(byte[] data) {
 116  0
         return new BytesSource(data);
 117  
     }
 118  
 
 119  
 
 120  
     /**
 121  
      * Converts the given String to a Source
 122  
      */
 123  
     @Converter
 124  
     public StringSource toSource(String data) {
 125  6
         return new StringSource(data);
 126  
     }
 127  
 
 128  
     /**
 129  
      * Converts the given Document to a Source
 130  
      */
 131  
     @Converter
 132  
     public DOMSource toSource(Document document) {
 133  0
         return new DOMSource(document);
 134  
     }
 135  
 
 136  
     /**
 137  
      * Converts the given input Source into text
 138  
      */
 139  
     @Converter
 140  
     public String toString(Source source) throws TransformerException {
 141  3
         if (source == null) {
 142  0
             return null;
 143  3
         } else if (source instanceof StringSource) {
 144  0
             return ((StringSource) source).getText();
 145  3
         } else if (source instanceof BytesSource) {
 146  0
             return new String(((BytesSource) source).getData());
 147  
         } else {
 148  3
             StringWriter buffer = new StringWriter();
 149  3
             toResult(source, new StreamResult(buffer));
 150  3
             return buffer.toString();
 151  
         }
 152  
     }
 153  
 
 154  
     /**
 155  
      * Converts the given input Node into text
 156  
      */
 157  
     @Converter
 158  
     public String toString(Node node) throws TransformerException {
 159  3
         return toString(new DOMSource(node));
 160  
     }
 161  
 
 162  
     /**
 163  
      * Converts the source instance to a {@link DOMSource} or returns null if the conversion is not
 164  
      * supported (making it easy to derive from this class to add new kinds of conversion).
 165  
      */
 166  
     @Converter
 167  
     public DOMSource toDOMSource(Source source) throws ParserConfigurationException, IOException, SAXException, TransformerException {
 168  0
         if (source instanceof DOMSource) {
 169  0
             return (DOMSource) source;
 170  
         }
 171  0
         else if (source instanceof SAXSource) {
 172  0
             return toDOMSourceFromSAX((SAXSource) source);
 173  
         }
 174  0
         else if (source instanceof StreamSource) {
 175  0
             return toDOMSourceFromStream((StreamSource) source);
 176  
         }
 177  
         else {
 178  0
             return null;
 179  
         }
 180  
     }
 181  
 
 182  
     /**
 183  
      * Converts the source instance to a {@link DOMSource} or returns null if the conversion is not
 184  
      * supported (making it easy to derive from this class to add new kinds of conversion).
 185  
      */
 186  
     @Converter
 187  
     public DOMSource toDOMSource(String text) throws ParserConfigurationException, IOException, SAXException, TransformerException {
 188  6
         Source source = toSource(text);
 189  6
         if (source != null) {
 190  6
             return toDOMSourceFromStream((StreamSource) source);
 191  
         }
 192  
         else {
 193  0
             return null;
 194  
         }
 195  
     }
 196  
 
 197  
     /**
 198  
      * Converts the source instance to a {@link SAXSource} or returns null if the conversion is not
 199  
      * supported (making it easy to derive from this class to add new kinds of conversion).
 200  
      */
 201  
     @Converter
 202  
     public SAXSource toSAXSource(String source) throws IOException, SAXException, TransformerException {
 203  0
         return toSAXSource(toSource(source));
 204  
     }
 205  
 
 206  
     /**
 207  
      * Converts the source instance to a {@link SAXSource} or returns null if the conversion is not
 208  
      * supported (making it easy to derive from this class to add new kinds of conversion).
 209  
      */
 210  
     @Converter
 211  
     public SAXSource toSAXSource(InputStream source) throws IOException, SAXException, TransformerException {
 212  0
         return toSAXSource(toStreamSource(source));
 213  
     }
 214  
 
 215  
     /**
 216  
      * Converts the source instance to a {@link SAXSource} or returns null if the conversion is not
 217  
      * supported (making it easy to derive from this class to add new kinds of conversion).
 218  
      */
 219  
     @Converter
 220  
     public SAXSource toSAXSource(Source source) throws IOException, SAXException, TransformerException {
 221  0
         if (source instanceof SAXSource) {
 222  0
             return (SAXSource) source;
 223  
         }
 224  0
         else if (source instanceof DOMSource) {
 225  0
             return toSAXSourceFromDOM((DOMSource) source);
 226  
         }
 227  0
         else if (source instanceof StreamSource) {
 228  0
             return toSAXSourceFromStream((StreamSource) source);
 229  
         }
 230  
         else {
 231  0
             return null;
 232  
         }
 233  
     }
 234  
 
 235  
     @Converter
 236  
     public StreamSource toStreamSource(Source source) throws TransformerException {
 237  0
         if (source instanceof StreamSource) {
 238  0
             return (StreamSource) source;
 239  0
         } else if (source instanceof DOMSource) {
 240  0
             return toStreamSourceFromDOM((DOMSource) source);
 241  0
         } else if (source instanceof SAXSource) {
 242  0
             return toStreamSourceFromSAX((SAXSource) source);
 243  
         } else {
 244  0
             return null;
 245  
         }
 246  
     }
 247  
 
 248  
     @Converter
 249  
     public StreamSource toStreamSource(InputStream in) throws TransformerException {
 250  0
         if (in != null) {
 251  0
             return new StreamSource(in);
 252  
         }
 253  0
         return null;
 254  
     }
 255  
 
 256  
     @Converter
 257  
     public StreamSource toStreamSource(Reader in) throws TransformerException {
 258  0
         if (in != null) {
 259  0
             return new StreamSource(in);
 260  
         }
 261  0
         return null;
 262  
     }
 263  
 
 264  
     @Converter
 265  
     public StreamSource toStreamSource(File in) throws TransformerException {
 266  0
         if (in != null) {
 267  0
             return new StreamSource(in);
 268  
         }
 269  0
         return null;
 270  
     }
 271  
 
 272  
     @Converter
 273  
     public StreamSource toStreamSource(byte[] in) throws TransformerException {
 274  0
         if (in != null) {
 275  0
             return new StreamSource(IOConverter.toInputStream(in));
 276  
         }
 277  0
         return null;
 278  
     }
 279  
 
 280  
     @Converter
 281  
     public StreamSource toStreamSource(ByteBuffer in) throws TransformerException {
 282  0
         if (in != null) {
 283  0
             return new StreamSource(NIOConverter.toInputStream(in));
 284  
         }
 285  0
         return null;
 286  
     }
 287  
 
 288  
     @Converter
 289  
     public StreamSource toStreamSourceFromSAX(SAXSource source) throws TransformerException {
 290  0
         InputSource inputSource = source.getInputSource();
 291  0
         if (inputSource != null) {
 292  0
             if (inputSource.getCharacterStream() != null) {
 293  0
                 return new StreamSource(inputSource.getCharacterStream());
 294  
             }
 295  0
             if (inputSource.getByteStream() != null) {
 296  0
                 return new StreamSource(inputSource.getByteStream());
 297  
             }
 298  
         }
 299  0
         String result = toString(source);
 300  0
         return new StringSource(result);
 301  
     }
 302  
 
 303  
     @Converter
 304  
     public StreamSource toStreamSourceFromDOM(DOMSource source) throws TransformerException {
 305  0
         String result = toString(source);
 306  0
         return new StringSource(result);
 307  
     }
 308  
 
 309  
     @Converter
 310  
     public SAXSource toSAXSourceFromStream(StreamSource source) {
 311  
         InputSource inputSource;
 312  0
         if (source.getReader() != null) {
 313  0
             inputSource = new InputSource(source.getReader());
 314  0
         } else {
 315  0
             inputSource = new InputSource(source.getInputStream());
 316  
         }
 317  0
         inputSource.setSystemId(source.getSystemId());
 318  0
         inputSource.setPublicId(source.getPublicId());
 319  0
         return new SAXSource(inputSource);
 320  
     }
 321  
 
 322  
     @Converter
 323  
     public Reader toReaderFromSource(Source src) throws TransformerException {
 324  0
         StreamSource stSrc = toStreamSource(src);
 325  0
         Reader r = stSrc.getReader();
 326  0
         if (r == null) {
 327  0
             r = new InputStreamReader(stSrc.getInputStream());
 328  
         }
 329  0
         return r;
 330  
     }
 331  
 
 332  
     @Converter
 333  
     public DOMSource toDOMSourceFromStream(StreamSource source) throws ParserConfigurationException, IOException, SAXException {
 334  6
         DocumentBuilder builder = createDocumentBuilder();
 335  6
         String systemId = source.getSystemId();
 336  6
         Document document = null;
 337  6
         Reader reader = source.getReader();
 338  6
         if (reader != null) {
 339  6
             document = builder.parse(new InputSource(reader));
 340  6
         } else {
 341  0
             InputStream inputStream = source.getInputStream();
 342  0
             if (inputStream != null) {
 343  0
                 InputSource inputsource = new InputSource(inputStream);
 344  0
                 inputsource.setSystemId(systemId);
 345  0
                 document = builder.parse(inputsource);
 346  0
             }
 347  
             else {
 348  0
                 throw new IOException("No input stream or reader available");
 349  
             }
 350  
         }
 351  6
         return new DOMSource(document, systemId);
 352  
     }
 353  
 
 354  
     @Converter
 355  
     public SAXSource toSAXSourceFromDOM(DOMSource source) throws TransformerException {
 356  0
         if (dom2SaxClass != null) {
 357  
             try {
 358  0
                 Constructor cns = dom2SaxClass.getConstructor(new Class[] { Node.class });
 359  0
                 XMLReader converter = (XMLReader) cns.newInstance(new Object[] { source.getNode() });
 360  0
                 return new SAXSource(converter, new InputSource());
 361  0
             } catch (Exception e) {
 362  0
                 throw new TransformerException(e);
 363  
             }
 364  
         } else {
 365  0
             String str = toString(source);
 366  0
             StringReader reader = new StringReader(str);
 367  0
             return new SAXSource(new InputSource(reader));
 368  
         }
 369  
     }
 370  
 
 371  
     @Converter
 372  
     public DOMSource toDOMSourceFromSAX(SAXSource source) throws IOException, SAXException, ParserConfigurationException, TransformerException {
 373  0
         return new DOMSource(toDOMNodeFromSAX(source));
 374  
     }
 375  
 
 376  
     @Converter
 377  
     public Node toDOMNodeFromSAX(SAXSource source) throws ParserConfigurationException, IOException, SAXException, TransformerException {
 378  0
         DOMResult result = new DOMResult();
 379  0
         toResult(source, result);
 380  0
         return result.getNode();
 381  
     }
 382  
 
 383  
     /**
 384  
      * Converts the given TRaX Source into a W3C DOM node
 385  
      * @throws SAXException
 386  
      * @throws IOException
 387  
      * @throws ParserConfigurationException
 388  
      */
 389  
     @Converter
 390  
     public Node toDOMNode(Source source) throws TransformerException, ParserConfigurationException, IOException, SAXException {
 391  0
         DOMSource domSrc = toDOMSource(source);
 392  0
         return domSrc != null ? domSrc.getNode() :  null;
 393  
     }
 394  
 
 395  
     /**
 396  
      * Create a DOM element from the given source.
 397  
      *
 398  
      * @param source
 399  
      * @return
 400  
      * @throws TransformerException
 401  
      * @throws ParserConfigurationException
 402  
      * @throws IOException
 403  
      * @throws SAXException
 404  
      */
 405  
     @Converter
 406  
     public Element toDOMElement(Source source) throws TransformerException, ParserConfigurationException, IOException, SAXException {
 407  0
         Node node = toDOMNode(source);
 408  0
         return toDOMElement(node);
 409  
     }
 410  
 
 411  
     /**
 412  
      * Create a DOM element from the DOM node.
 413  
      * Simply cast if the node is an Element, or
 414  
      * return the root element if it is a Document.
 415  
      *
 416  
      * @param node
 417  
      * @return
 418  
      * @throws TransformerException
 419  
      */
 420  
     @Converter
 421  
     public Element toDOMElement(Node node) throws TransformerException {
 422  
         // If the node is an document, return the root element
 423  0
         if (node instanceof Document) {
 424  0
             return ((Document) node).getDocumentElement();
 425  
         // If the node is an element, just cast it
 426  0
         } else if (node instanceof Element) {
 427  0
             return (Element) node;
 428  
         // Other node types are not handled
 429  
         } else {
 430  0
             throw new TransformerException("Unable to convert DOM node to an Element");
 431  
         }
 432  
     }
 433  
 
 434  
     /**
 435  
      * Converts the given data to a DOM document
 436  
      *
 437  
      * @param data is the data to be parsed
 438  
      * @return the parsed document
 439  
      */
 440  
     @Converter
 441  
     public Document toDOMDocument(byte[] data) throws IOException, SAXException, ParserConfigurationException {
 442  96
         DocumentBuilder documentBuilder = getDocumentBuilderFactory().newDocumentBuilder();
 443  96
         return documentBuilder.parse(new ByteArrayInputStream(data));
 444  
     }
 445  
 
 446  
     /**
 447  
      * Converts the given {@link InputStream} to a DOM document
 448  
      *
 449  
      * @param in is the data to be parsed
 450  
      * @return the parsed document
 451  
      */
 452  
     @Converter
 453  
     public Document toDOMDocument(InputStream in) throws IOException, SAXException, ParserConfigurationException {
 454  0
         DocumentBuilder documentBuilder = getDocumentBuilderFactory().newDocumentBuilder();
 455  0
         return documentBuilder.parse(in);
 456  
     }
 457  
 
 458  
     /**
 459  
      * Converts the given {@link InputSource} to a DOM document
 460  
      *
 461  
      * @param in is the data to be parsed
 462  
      * @return the parsed document
 463  
      */
 464  
     @Converter
 465  
     public Document toDOMDocument(InputSource in) throws IOException, SAXException, ParserConfigurationException {
 466  0
         DocumentBuilder documentBuilder = getDocumentBuilderFactory().newDocumentBuilder();
 467  0
         return documentBuilder.parse(in);
 468  
     }
 469  
 
 470  
     /**
 471  
      * Converts the given {@link String} to a DOM document
 472  
      *
 473  
      * @param text is the data to be parsed
 474  
      * @return the parsed document
 475  
      */
 476  
     @Converter
 477  
     public Document toDOMDocument(String text) throws IOException, SAXException, ParserConfigurationException {
 478  96
         return toDOMDocument(text.getBytes());
 479  
     }
 480  
 
 481  
     /**
 482  
      * Converts the given {@link File} to a DOM document
 483  
      *
 484  
      * @param file is the data to be parsed
 485  
      * @return the parsed document
 486  
      */
 487  
     @Converter
 488  
     public Document toDOMDocument(File file) throws IOException, SAXException, ParserConfigurationException {
 489  0
         DocumentBuilder documentBuilder = getDocumentBuilderFactory().newDocumentBuilder();
 490  0
         return documentBuilder.parse(file);
 491  
     }
 492  
 
 493  
 
 494  
     /**
 495  
      * Create a DOM document from the given source.
 496  
      *
 497  
      * @param source
 498  
      * @return
 499  
      * @throws TransformerException
 500  
      * @throws ParserConfigurationException
 501  
      * @throws IOException
 502  
      * @throws SAXException
 503  
      */
 504  
     @Converter
 505  
     public Document toDOMDocument(Source source) throws TransformerException, ParserConfigurationException, IOException, SAXException {
 506  0
         Node node = toDOMNode(source);
 507  0
         return toDOMDocument(node);
 508  
     }
 509  
 
 510  
     /**
 511  
      * Create a DOM document from the given Node.
 512  
      * If the node is an document, just cast it,
 513  
      * if the node is an root element, retrieve its
 514  
      * owner element or create a new document and import
 515  
      * the node.
 516  
      *
 517  
      * @param node
 518  
      * @return
 519  
      * @throws ParserConfigurationException
 520  
      * @throws TransformerException
 521  
      */
 522  
     @Converter
 523  
     public Document toDOMDocument(Node node) throws ParserConfigurationException, TransformerException {
 524  
         // If the node is the document, just cast it
 525  0
         if (node instanceof Document) {
 526  0
             return (Document) node;
 527  
         // If the node is an element
 528  0
         } else if (node instanceof Element) {
 529  0
             Element elem = (Element) node;
 530  
             // If this is the root element, return its owner document
 531  0
             if (elem.getOwnerDocument().getDocumentElement() == elem) {
 532  0
                 return elem.getOwnerDocument();
 533  
             // else, create a new doc and copy the element inside it
 534  
             } else {
 535  0
                 Document doc = createDocument();
 536  0
                 doc.appendChild(doc.importNode(node, true));
 537  0
                 return doc;
 538  
             }
 539  
         // other element types are not handled
 540  
         } else {
 541  0
             throw new TransformerException("Unable to convert DOM node to a Document");
 542  
         }
 543  
     }
 544  
 
 545  
     // Properties
 546  
     //-------------------------------------------------------------------------
 547  
     public DocumentBuilderFactory getDocumentBuilderFactory() {
 548  102
         if (documentBuilderFactory == null) {
 549  66
             documentBuilderFactory = createDocumentBuilderFactory();
 550  
         }
 551  102
         return documentBuilderFactory;
 552  
     }
 553  
 
 554  
     public void setDocumentBuilderFactory(DocumentBuilderFactory documentBuilderFactory) {
 555  0
         this.documentBuilderFactory = documentBuilderFactory;
 556  0
     }
 557  
 
 558  
 
 559  
     // Helper methods
 560  
     //-------------------------------------------------------------------------
 561  
     public DocumentBuilderFactory createDocumentBuilderFactory() {
 562  66
         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
 563  66
         factory.setNamespaceAware(true);
 564  66
         factory.setIgnoringElementContentWhitespace(true);
 565  66
         factory.setIgnoringComments(true);
 566  66
         return factory;
 567  
     }
 568  
 
 569  
 
 570  
     public DocumentBuilder createDocumentBuilder() throws ParserConfigurationException {
 571  6
         DocumentBuilderFactory factory = getDocumentBuilderFactory();
 572  6
         return factory.newDocumentBuilder();
 573  
     }
 574  
 
 575  
     public Document createDocument() throws ParserConfigurationException {
 576  0
         DocumentBuilder builder = createDocumentBuilder();
 577  0
         return builder.newDocument();
 578  
     }
 579  
 
 580  
     public TransformerFactory getTransformerFactory() {
 581  6
         if (transformerFactory == null) {
 582  6
             transformerFactory = createTransformerFactory();
 583  
         }
 584  6
         return transformerFactory;
 585  
     }
 586  
 
 587  
     public void setTransformerFactory(TransformerFactory transformerFactory) {
 588  0
         this.transformerFactory = transformerFactory;
 589  0
     }
 590  
 
 591  
     public Transformer createTransfomer() throws TransformerConfigurationException {
 592  3
         TransformerFactory factory = getTransformerFactory();
 593  3
         return factory.newTransformer();
 594  
     }
 595  
 
 596  
     public TransformerFactory createTransformerFactory() {
 597  6
         TransformerFactory answer = TransformerFactory.newInstance();
 598  6
         return answer;
 599  
     }
 600  
 
 601  
 }