View Javadoc

1    /****************************************************************************
2    * Copyright (c) 2005, 2006, 2007, 2008, 2009 Imola Informatica.
3    * All rights reserved. This program and the accompanying materials
4    * are made available under the terms of the LGPL License v2.1
5    * which accompanies this distribution, and is available at
6    * http://www.gnu.org/licenses/lgpl.html
7    ****************************************************************************/
8   package it.imolinfo.jbi4corba.jbi.processor.transform;
9   
10  import it.imolinfo.jbi4corba.Logger;
11  import it.imolinfo.jbi4corba.LoggerFactory;
12  import it.imolinfo.jbi4corba.jbi.Messages;
13  
14  import java.io.IOException;
15  import java.io.InputStream;
16  import java.io.InputStreamReader;
17  import java.io.Reader;
18  import java.io.StringReader;
19  import java.io.StringWriter;
20  import java.lang.reflect.Constructor;
21  
22  import javax.jbi.messaging.MessagingException;
23  import javax.jbi.messaging.NormalizedMessage;
24  import javax.xml.parsers.DocumentBuilder;
25  import javax.xml.parsers.DocumentBuilderFactory;
26  import javax.xml.parsers.ParserConfigurationException;
27  import javax.xml.stream.XMLInputFactory;
28  import javax.xml.stream.XMLStreamException;
29  import javax.xml.stream.XMLStreamReader;
30  import javax.xml.transform.OutputKeys;
31  import javax.xml.transform.Result;
32  import javax.xml.transform.Source;
33  import javax.xml.transform.Transformer;
34  import javax.xml.transform.TransformerConfigurationException;
35  import javax.xml.transform.TransformerException;
36  import javax.xml.transform.TransformerFactory;
37  import javax.xml.transform.dom.DOMResult;
38  import javax.xml.transform.dom.DOMSource;
39  import javax.xml.transform.sax.SAXSource;
40  import javax.xml.transform.stream.StreamResult;
41  import javax.xml.transform.stream.StreamSource;
42  
43  import org.apache.cxf.staxutils.W3CDOMStreamReader;
44  import org.w3c.dom.Document;
45  import org.w3c.dom.Element;
46  import org.w3c.dom.Node;
47  import org.xml.sax.InputSource;
48  import org.xml.sax.SAXException;
49  import org.xml.sax.XMLReader;
50  
51  /**
52   * Taken from servicemix-core <code>SourceTransformer</code> and partially
53   * from <code>StAXSoureTransformer</code> class. 
54   * 
55   * @author <a href="mailto:mpiraccini@imolinfo.it">Marco Piraccini</a>
56   */
57  @SuppressWarnings("unchecked")
58  public class SourceTransformer {
59      
60      /*
61       * When converting a DOM tree to a SAXSource,
62       * we try to use Xalan internal DOM parser if
63       * available.  Else, transform the DOM tree
64       * to a String and build a SAXSource on top of
65       * it.
66       */
67      /** The Constant dom2SaxClass. */
68      private static final Class dom2SaxClass;
69      
70      /** The Constant LOG. */
71      private static final Logger LOG
72      = LoggerFactory.getLogger(SourceTransformer.class);
73      private static final Messages MESSAGES = 
74      	Messages.getMessages(SourceTransformer.class);
75  
76      
77  
78      /** The Constant DEFAULT_CHARSET_PROPERTY. */
79      private static final String DEFAULT_CHARSET_PROPERTY = "org.apache.servicemix.default.charset";
80      
81      /** The default charset. */
82      private static String defaultCharset = System.getProperty(DEFAULT_CHARSET_PROPERTY, "UTF-8");    
83  
84      /** The document builder factory. */
85      private DocumentBuilderFactory documentBuilderFactory;
86      
87      /** The transformer factory. */
88      private TransformerFactory transformerFactory;
89  
90      /** The input factory. */
91      private XMLInputFactory inputFactory;   
92  
93      /**
94       * Instantiates a new source transformer.
95       */
96      public SourceTransformer() {
97      }
98  
99      /**
100      * Instantiates a new source transformer.
101      * 
102      * @param documentBuilderFactory the <code>DocumentBuilderFactory</code>
103      */
104     public SourceTransformer(DocumentBuilderFactory documentBuilderFactory) {
105         this.documentBuilderFactory = documentBuilderFactory;
106     }
107 
108     /**
109      * Converts the given input Source into the required result.
110      * 
111      * @param source the source to transform
112      * @param result the result of the transformation
113      * 
114      * @throws TransformerException if some transformation error occurs
115      */
116     public void toResult(Source source, Result result) throws TransformerException {
117         if (source == null) {
118             return;
119         }
120         Transformer transformer = createTransfomer();
121         if (transformer == null) {
122         	String msg=MESSAGES.getString("CRB001000_Could_not_create_transformer_JAXP_misconfigured");
123             LOG.error(msg);
124             throw new TransformerException(msg);
125 
126 
127         }
128         transformer.setOutputProperty(OutputKeys.ENCODING, defaultCharset);
129         transformer.transform(source, result);
130     }
131 
132     /**
133      * Converts the given input Source into text.
134      * 
135      * @param source the source 
136      * 
137      * @return
138      *      The String verions of the source
139      * 
140      * @throws TransformerException if some transformation error occurs
141      */
142     public String toString(Source source) throws TransformerException {
143         if (source == null) {
144             return null;
145         } else if (source instanceof StringSource) {
146             return ((StringSource) source).getText();
147         } else {
148             StringWriter buffer = new StringWriter();
149             toResult(source, new StreamResult(buffer));
150             return buffer.toString();
151         }
152     }
153 
154     /**
155      * Converts the given input Node into text.
156      * 
157      * @param node the Dom node
158      * 
159      * @return
160      *      The <code>Node</code> as a String
161      * 
162      * @throws TransformerException if some transformation error occurs
163      */
164     public String toString(Node node) throws TransformerException {
165         return toString(new DOMSource(node));
166     }
167 
168     /**
169      * Converts the content of the given message to a String.
170      * 
171      * @param message The message
172      * 
173      * @return The message content as String
174      *          
175      * @throws SAXException
176      *             If some problem occurs
177      * @throws IOException
178      *             If some problem occurs
179      * @throws ParserConfigurationException
180      *             If some problem occurs
181      * @throws MessagingException
182      *             If some problem occurs
183      * @throws TransformerException
184      *             If some problem occurs
185      */
186     public String contentToString(NormalizedMessage message) throws MessagingException, TransformerException, ParserConfigurationException, IOException, SAXException {
187         return toString(message.getContent());
188     }
189 
190     /**
191      * Converts the source instance to a {@link DOMSource} or returns null if
192      * the conversion is not supported (making it easy to derive from this class
193      * to add new kinds of conversion).
194      * 
195      * @param source
196      *      The source to transform
197      * 
198      * @return
199      *      The DOMSource from the source.
200      * 
201      * @throws ParserConfigurationException
202      *             If some problem occurs
203      * @throws IOException
204      *             If some problem occurs
205      * @throws SAXException
206      *             If some problem occurs
207      * @throws TransformerException
208      *             If some problem occurs
209      */
210     public DOMSource toDOMSource(Source source) throws ParserConfigurationException, IOException, SAXException, TransformerException {
211         if (source instanceof DOMSource) {
212             return (DOMSource) source;
213         }
214         else if (source instanceof SAXSource) {
215             return toDOMSourceFromSAX((SAXSource) source);
216         }
217         else if (source instanceof StreamSource) {
218             return toDOMSourceFromStream((StreamSource) source);
219         }
220         else {
221             return null;
222         }
223     }
224 
225     /**
226      * To DOM source.
227      * 
228      * @param message
229      *          The NormalizedMessage
230      * 
231      * @return the source
232      * 
233      * @throws MessagingException
234      *             If some problem occurs
235      * @throws TransformerException
236      *             If some problem occurs
237      * @throws ParserConfigurationException
238      *             If some problem occurs
239      * @throws IOException
240      *             If some problem occurs
241      * @throws SAXException
242      *             If some problem occurs
243      */
244     public Source toDOMSource(NormalizedMessage message) throws MessagingException, TransformerException, ParserConfigurationException, IOException, SAXException {
245         Node node = toDOMNode(message);
246         return new DOMSource(node);
247     }
248 
249     /**
250      * Converts the source instance to a {@link SAXSource} or returns null if
251      * the conversion is not supported (making it easy to derive from this class
252      * to add new kinds of conversion).
253      * 
254      * @param source The source to transform
255      * 
256      * @return the SAXSource from the Source
257      * 
258      * @throws IOException
259      *             If some problem occurs
260      * @throws SAXException
261      *             If some problem occurs
262      * @throws TransformerException
263      *             If some problem occurs
264      */
265     public SAXSource toSAXSource(Source source) throws IOException, SAXException, TransformerException {
266         if (source instanceof SAXSource) {
267             return (SAXSource) source;
268         }
269         else if (source instanceof DOMSource) {
270             return toSAXSourceFromDOM((DOMSource) source);
271         }
272         else if (source instanceof StreamSource) {
273             return toSAXSourceFromStream((StreamSource) source);
274         }
275         else {
276             return null;
277         }
278     }
279 
280     /**
281      * To stream source.
282      * 
283      * @param source
284      *          The Source
285      * 
286      * @return the stream source
287      * 
288      * @throws TransformerException
289      *             If some problem occurs
290      */
291     public StreamSource toStreamSource(Source source) throws TransformerException {
292         if (source instanceof StreamSource) {
293             return (StreamSource) source;
294         } else if (source instanceof DOMSource) {
295             return toStreamSourceFromDOM((DOMSource) source);
296         } else if (source instanceof SAXSource) {
297             return toStreamSourceFromSAX((SAXSource) source);
298         } else {
299             return null;
300         }
301     }
302 
303     /**
304      * To stream source from SAX.
305      * 
306      * @param source
307      *          The Source
308      * @return the stream source
309      * 
310      * @throws TransformerException
311      *             If some problem occurs
312      */
313     public StreamSource toStreamSourceFromSAX(SAXSource source) throws TransformerException {
314         InputSource inputSource = source.getInputSource();
315         if (inputSource != null) {
316             if (inputSource.getCharacterStream() != null) {
317                 return new StreamSource(inputSource.getCharacterStream());
318             }
319             if (inputSource.getByteStream() != null) {
320                 return new StreamSource(inputSource.getByteStream());
321             }
322         }
323         String result = toString(source);
324         return new StringSource(result);
325     }
326 
327     /**
328      * To stream source from DOM.
329      * 
330      * @param source
331      *          The DOMSource
332      * 
333      * @return the stream source
334      * 
335      * @throws TransformerException
336      *             If some problem occurs
337      */
338     public StreamSource toStreamSourceFromDOM(DOMSource source) throws TransformerException {
339         String result = toString(source);
340         return new StringSource(result);
341     }
342 
343     /**
344      * To SAX source from stream.
345      * 
346      * @param source
347      *          The Source
348      * @return the SAX source
349      */
350     public SAXSource toSAXSourceFromStream(StreamSource source) {
351         InputSource inputSource;
352         if (source.getReader() != null) {
353             inputSource = new InputSource(source.getReader());
354         } else {
355             inputSource = new InputSource(source.getInputStream());
356         }
357         inputSource.setSystemId(source.getSystemId());
358         inputSource.setPublicId(source.getPublicId());
359         return new SAXSource(inputSource);
360     }
361 
362     /**
363      * To reader from source.
364      * 
365      * @param src
366      *          The source
367      * 
368      * @return the reader
369      * 
370      * @throws TransformerException
371      *             If some problem occurs
372      */
373     public Reader toReaderFromSource(Source src) throws TransformerException {
374         StreamSource stSrc = toStreamSource(src);
375         Reader r = stSrc.getReader();
376         if (r == null) {
377             r = new InputStreamReader(stSrc.getInputStream());
378         }
379         return r;
380     }
381 
382     /**
383      * To DOM source from stream.
384      * 
385      * @param source
386      *          The stream source
387      * 
388      * @return the DOM source
389      * 
390      * @throws ParserConfigurationException
391      *             If some problem occurs
392      * @throws IOException
393      *             If some problem occurs
394      * @throws SAXException
395      *             If some problem occurs
396      */
397     public DOMSource toDOMSourceFromStream(StreamSource source) throws ParserConfigurationException, IOException, SAXException {
398         DocumentBuilder builder = createDocumentBuilder();                
399         String systemId = source.getSystemId();
400         Document document = null;
401         Reader reader = source.getReader();
402         if (reader != null) {
403             document = builder.parse(new InputSource(reader));
404         } else {
405             InputStream inputStream = source.getInputStream();
406             if (inputStream != null) {
407                 InputSource inputsource = new InputSource(inputStream);
408                 inputsource.setSystemId(systemId);
409                 document = builder.parse(inputsource);
410             }
411             else {
412                 throw new IOException("No input stream or reader available");
413             }
414         }
415         return new DOMSource(document, systemId);
416     }
417 
418 
419     /**
420      * Static initializer
421      */
422     static {
423         Class cl = null;
424         try {
425             cl = Class.forName("org.apache.xalan.xsltc.trax.DOM2SAX");
426         } catch (Throwable t) {
427             // Static initializer, do nothing...
428         	String msg=MESSAGES.getString("CRB001001_Static_inizializer_do_nothing", 
429         			new Object[] {t.getMessage()});
430         	// Not a "real" error
431             LOG.debug(msg);        
432         }
433         dom2SaxClass = cl;
434     }
435 
436     /**
437      * To SAX source from DOM.
438      * 
439      * @param source
440      *          The DOMSource
441      * 
442      * @return the SAX source
443      * 
444      * @throws TransformerException
445      *             If some problem occurs  
446      */
447     public SAXSource toSAXSourceFromDOM(DOMSource source) throws TransformerException {
448         if (dom2SaxClass != null) {
449             try {
450                 Constructor cns = dom2SaxClass.getConstructor(new Class[] { Node.class });
451                 XMLReader converter = (XMLReader) cns.newInstance(new Object[] { source.getNode() });
452                 return new SAXSource(converter, new InputSource());
453             } catch (Exception e) {
454             	String msg=MESSAGES.getString("CRB001002_To_SAX_source_from_DOM");
455                 LOG.error(msg,e);
456                 throw new TransformerException(msg,e);
457 
458             }
459         } else {
460             String str = toString(source);
461             StringReader reader = new StringReader(str);
462             return new SAXSource(new InputSource(reader));
463         }
464     }
465 
466     /**
467      * To DOM source from SAX.
468      * 
469      * @param source
470      *          The source
471      * 
472      * @return the DOM source
473      * 
474      * @throws IOException
475      *             If some problem occurs
476      * @throws SAXException
477      *             If some problem occurs
478      * @throws ParserConfigurationException
479      *             If some problem occurs
480      * @throws TransformerException
481      *             If some problem occurs
482      */
483     public DOMSource toDOMSourceFromSAX(SAXSource source) throws IOException, SAXException, ParserConfigurationException, TransformerException {
484         return new DOMSource(toDOMNodeFromSAX(source));
485     }
486 
487     /**
488      * To DOM node from SAX.
489      * 
490      * @param source
491      *          The Source
492      * 
493      * @return the node
494      * 
495      * @throws ParserConfigurationException
496      *             If some problem occurs
497      * @throws IOException
498      *             If some problem occurs
499      * @throws SAXException
500      *             If some problem occurs
501      * @throws TransformerException
502      *             If some problem occurs
503      */
504     public Node toDOMNodeFromSAX(SAXSource source) throws ParserConfigurationException, IOException, SAXException, TransformerException {
505         DOMResult result = new DOMResult();
506         toResult(source, result);
507         return result.getNode();
508     }
509 
510     /**
511      * Converts the given TRaX Source into a W3C DOM node.
512      * 
513      * @param source
514      *          The source
515      * 
516      * @return
517      *      The Node
518      * 
519      * @throws SAXException
520      *             If some problem occurs
521      * @throws IOException
522      *             If some problem occurs
523      * @throws ParserConfigurationException
524      *             If some problem occurs
525      * @throws TransformerException
526      *             If some problem occurs
527      */
528     public Node toDOMNode(Source source) throws TransformerException, ParserConfigurationException, IOException, SAXException {
529         DOMSource domSrc = toDOMSource(source);
530         if (domSrc != null) {
531             return domSrc.getNode();
532         } else {
533             return null;
534         }
535     }
536 
537     /**
538      * Avoids multple parsing to DOM by caching the DOM representation in the
539      * message as a property so future calls will avoid the reparse - and avoid
540      * issues with stream based Source instances.
541      * 
542      * @param message
543      *            the normalized message
544      * 
545      * @return the W3C DOM node for this message
546      * 
547      * @throws SAXException
548      *             If some problem occurs
549      * @throws IOException
550      *             If some problem occurs
551      * @throws ParserConfigurationException
552      *             If some problem occurs
553      * @throws MessagingException
554      *             If some problem occurs
555      * @throws TransformerException
556      *             If some problem occurs
557      */
558     public Node toDOMNode(NormalizedMessage message) throws MessagingException, TransformerException, ParserConfigurationException, IOException, SAXException {
559         Source content = message.getContent();
560         Node node = toDOMNode(content);
561         return node;
562     }
563 
564     /**
565      * Create a DOM element from the normalized message.
566      * 
567      * @param message
568      * 
569      * @return
570      *      The DOM element
571      * @throws MessagingException
572      *             If some problem occurs
573      * @throws TransformerException
574      *             If some problem occurs
575      * @throws ParserConfigurationException
576      *             If some problem occurs
577      * @throws IOException
578      * @throws SAXException
579      */
580     public Element toDOMElement(NormalizedMessage message) throws MessagingException, TransformerException, ParserConfigurationException, IOException, SAXException {
581         Node node = toDOMNode(message);
582         return toDOMElement(node);
583     }
584 
585     /**
586      * Create a DOM element from the given source.
587      * 
588      * @param source
589      *      The Source
590      * 
591      * @return
592      *      The DOM element
593      * 
594      * @throws TransformerException
595      *             If some problem occurs
596      * @throws ParserConfigurationException
597      *             If some problem occurs
598      * @throws IOException
599      *             If some problem occurs
600      * @throws SAXException
601      *             If some problem occurs
602      */
603     public Element toDOMElement(Source source) throws TransformerException, ParserConfigurationException, IOException, SAXException {
604         Node node = toDOMNode(source);
605         return toDOMElement(node);
606     }
607 
608     /**
609      * Create a DOM element from the DOM node. Simply cast if the node is an
610      * Element, or return the root element if it is a Document.
611      * 
612      * @param node
613      *          The DOM node
614      * @return
615      *          The DOM element     
616      * @throws TransformerException
617      *             If some problem occurs
618      */
619     public Element toDOMElement(Node node) throws TransformerException {
620         // If the node is an document, return the root element
621         if (node instanceof Document) {
622             return ((Document) node).getDocumentElement();
623             // If the node is an element, just cast it
624         } else if (node instanceof Element) {
625             return (Element) node;
626             // Other node types are not handled
627         } else {
628         	String msg=MESSAGES.getString("CRB001003_Unable_to_convert_DOM_node_to_an_Element");
629             LOG.error(msg);
630             throw new TransformerException(msg);
631 
632         }
633     }
634 
635     /**
636      * Create a DOM document from the given normalized message.
637      * 
638      * @param message
639      *          The NormalizedMessage
640      * @return
641      *          The Document
642      * 
643      * @throws MessagingException
644      *             If some problem occurs
645      * @throws TransformerException
646      *             If some problem occurs
647      * @throws ParserConfigurationException
648      *             If some problem occurs
649      * @throws IOException
650      *             If some problem occurs
651      * @throws SAXException
652      *             If some problem occurs
653      */
654     public Document toDOMDocument(NormalizedMessage message) throws MessagingException, TransformerException, ParserConfigurationException, IOException, SAXException {
655         Node node = toDOMNode(message);
656         return toDOMDocument(node);
657     }
658 
659     /**
660      * Create a DOM document from the given source.
661      * 
662      * @param source
663      *          The Source
664      * 
665      * @return
666      *          The DOM document
667      * 
668      * @throws TransformerException
669      *             If some problem occurs
670      * @throws ParserConfigurationException
671      *             If some problem occurs
672      * @throws IOException
673      *             If some problem occurs
674      * @throws SAXException
675      *             If some problem occurs
676      */
677     public Document toDOMDocument(Source source) throws TransformerException, ParserConfigurationException, IOException, SAXException {
678         Node node = toDOMNode(source);
679         return toDOMDocument(node);
680     }
681 
682     /**
683      * Create a DOM document from the given Node. If the node is an document,
684      * just cast it, if the node is an root element, retrieve its owner element
685      * or create a new document and import the node.
686      * 
687      * @param node
688      *      The Node
689      * 
690      * @return
691      *      The DOM document
692      * 
693      * @throws ParserConfigurationException
694      *             If some problem occurs
695      * @throws TransformerException
696      *             If some problem occurs
697      */
698     public Document toDOMDocument(Node node) throws ParserConfigurationException, TransformerException {
699         // If the node is the document, just cast it
700         if (node instanceof Document) {
701             return (Document) node;
702             // If the node is an element
703         } else if (node instanceof Element) {
704             Element elem = (Element) node;
705             // If this is the root element, return its owner document
706             if (elem.getOwnerDocument().getDocumentElement() == elem) {
707                 return elem.getOwnerDocument();
708                 // else, create a new doc and copy the element inside it
709             } else {
710                 Document doc = createDocument();
711                 doc.appendChild(doc.importNode(node, true));
712                 return doc;
713             }
714             // other element types are not handled
715         } else {
716         	String msg=MESSAGES.getString("CRB001004_Unable_to_convert_DOM_node_to_a_Document");
717             LOG.error(msg);
718             throw new TransformerException(msg);
719         }
720     }
721 
722     // Properties
723     //-------------------------------------------------------------------------
724     /**
725      * Gets the document builder factory.
726      * 
727      * @return the document builder factory
728      */
729     public DocumentBuilderFactory getDocumentBuilderFactory() {
730         if (documentBuilderFactory == null) {
731             documentBuilderFactory = createDocumentBuilderFactory();
732         }
733         return documentBuilderFactory;
734     }
735 
736     /**
737      * Sets the document builder factory.
738      * 
739      * @param documentBuilderFactory
740      *            the new document builder factory
741      */
742     public void setDocumentBuilderFactory(DocumentBuilderFactory documentBuilderFactory) {
743         this.documentBuilderFactory = documentBuilderFactory;
744     }
745 
746 
747     // Helper methods
748     //-------------------------------------------------------------------------
749     /**
750      * Creates the document builder factory.
751      * 
752      * @return the document builder factory
753      */
754     public DocumentBuilderFactory createDocumentBuilderFactory() {
755         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
756         factory.setNamespaceAware(true);        
757         factory.setIgnoringElementContentWhitespace(true);
758         factory.setIgnoringComments(true);
759         return factory;
760     }
761 
762 
763     /**
764      * Creates the document builder.
765      * 
766      * @return the document builder
767      * 
768      * @throws ParserConfigurationException
769      *             If some problem occurs
770      */
771     public DocumentBuilder createDocumentBuilder() throws ParserConfigurationException {
772         DocumentBuilderFactory factory = getDocumentBuilderFactory();
773         factory.setNamespaceAware(true);        
774         return factory.newDocumentBuilder();
775     }
776 
777     /**
778      * Creates the document.
779      * 
780      * @return the document
781      * 
782      * @throws ParserConfigurationException
783      *             If some problem occurs
784      */
785     public Document createDocument() throws ParserConfigurationException {
786         DocumentBuilder builder = createDocumentBuilder();        
787         return builder.newDocument();
788     }
789 
790     /**
791      * Gets the transformer factory.
792      * 
793      * @return the transformer factory
794      */
795     public TransformerFactory getTransformerFactory() {
796         if (transformerFactory == null) {
797             transformerFactory = createTransformerFactory();
798         }
799         return transformerFactory;
800     }
801 
802     /**
803      * Sets the transformer factory.
804      * 
805      * @param transformerFactory
806      *            the new transformer factory
807      */
808     public void setTransformerFactory(TransformerFactory transformerFactory) {
809         this.transformerFactory = transformerFactory;
810     }
811 
812     /**
813      * Creates the transfomer.
814      * 
815      * @return the transformer
816      * 
817      * @throws TransformerConfigurationException
818      *             If some problem occurs
819      */
820     public Transformer createTransfomer() throws TransformerConfigurationException {
821         TransformerFactory factory = getTransformerFactory();
822         return factory.newTransformer();
823     }
824 
825     /**
826      * Creates the transformer factory.
827      * 
828      * @return the transformer factory
829      */
830     public TransformerFactory createTransformerFactory() {
831         TransformerFactory answer = TransformerFactory.newInstance();
832         return answer;
833     }
834 
835     /**
836      * To XML stream reader.
837      * 
838      * @param source
839      *          The Source
840      * 
841      * @return the XML stream reader
842      * 
843      * @throws XMLStreamException
844      *             If some problem occurs
845      * @throws TransformerException
846      *             If some problem occurs
847      */
848     public XMLStreamReader toXMLStreamReader(Source source) throws XMLStreamException, TransformerException {
849 //      Uncomment to support StaxSource
850 //      if (source instanceof StaxSource) {
851 //      return ((StaxSource) source).getXMLStreamReader();
852 //      }
853         // It seems that woodstox 2.9.3 throws some NPE in the servicemix-soap
854         // when using DOM, so use our own dom / stax parser
855         if (source instanceof DOMSource) {
856             Node n = ((DOMSource) source).getNode();
857             
858             Element el = null;
859             if (n instanceof Document) {
860                 el = ((Document) n).getDocumentElement();
861             } else if (n instanceof Element ) {
862                 el =(Element) n;
863             }             
864             if (el != null) {
865                 return new W3CDOMStreamReader(el);
866             }
867         }
868         XMLInputFactory factory = getInputFactory();
869         try {
870             return factory.createXMLStreamReader(source);
871         } catch (XMLStreamException e) {
872             return factory.createXMLStreamReader(toReaderFromSource(source));
873         }
874     }
875 
876     // Implementation methods
877     //-------------------------------------------------------------------------
878     /**
879      * Creates the input factory.
880      * 
881      * @return the XML input factory
882      */
883     protected XMLInputFactory createInputFactory() {
884         XMLInputFactory answer = XMLInputFactory.newInstance();
885         return answer;
886     }
887 
888     // Properties
889     //-------------------------------------------------------------------------
890     /**
891      * Gets the input factory.
892      * 
893      * @return the input factory
894      */
895     public XMLInputFactory getInputFactory() {
896         if (inputFactory == null) {
897             inputFactory = createInputFactory();
898         }
899         return inputFactory;
900     }    
901 }