View Javadoc

1   /*******************************************************************************
2    *  Copyright (c) 2005, 2006, 2007 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.jbi4ejb.processor.transform;
9   
10  import it.imolinfo.jbi4ejb.Logger;
11  import it.imolinfo.jbi4ejb.LoggerFactory;
12  import it.imolinfo.jbi4ejb.configuration.InterfaceExtractorUtil;
13  import it.imolinfo.jbi4ejb.jbi.Messages;
14  
15  import java.io.IOException;
16  import java.io.InputStream;
17  import java.io.InputStreamReader;
18  import java.io.Reader;
19  import java.io.StringReader;
20  import java.io.StringWriter;
21  import java.lang.reflect.Constructor;
22  
23  import javax.jbi.messaging.MessagingException;
24  import javax.jbi.messaging.NormalizedMessage;
25  import javax.xml.parsers.DocumentBuilder;
26  import javax.xml.parsers.DocumentBuilderFactory;
27  import javax.xml.parsers.ParserConfigurationException;
28  import javax.xml.stream.XMLInputFactory;
29  import javax.xml.stream.XMLStreamException;
30  import javax.xml.stream.XMLStreamReader;
31  import javax.xml.transform.OutputKeys;
32  import javax.xml.transform.Result;
33  import javax.xml.transform.Source;
34  import javax.xml.transform.Transformer;
35  import javax.xml.transform.TransformerConfigurationException;
36  import javax.xml.transform.TransformerException;
37  import javax.xml.transform.TransformerFactory;
38  import javax.xml.transform.dom.DOMResult;
39  import javax.xml.transform.dom.DOMSource;
40  import javax.xml.transform.sax.SAXSource;
41  import javax.xml.transform.stream.StreamResult;
42  import javax.xml.transform.stream.StreamSource;
43  
44  import org.codehaus.xfire.util.stax.W3CDOMStreamReader;
45  import org.w3c.dom.Document;
46  import org.w3c.dom.Element;
47  import org.w3c.dom.Node;
48  import org.xml.sax.InputSource;
49  import org.xml.sax.SAXException;
50  import org.xml.sax.XMLReader;
51  
52  /**
53   * Taken from servicemix-core <code>SourceTransformer</code> and partially
54   * from <code>StAXSoureTransformer</code> class. 
55   * // TODO Add<code>StaxSource</code> support
56   * 
57   * @author <a href="mailto:mpiraccini@imolinfo.it">Marco Piraccini</a>
58   */
59  
60  public class SourceTransformer {
61      
62      /*
63       * When converting a DOM tree to a SAXSource,
64       * we try to use Xalan internal DOM parser if
65       * available.  Else, transform the DOM tree
66       * to a String and build a SAXSource on top of
67       * it.
68       */
69      /** The Constant dom2SaxClass. */
70      private static final Class dom2SaxClass;
71      
72      /** The Constant LOG. */
73      private static final Logger LOG
74      = LoggerFactory.getLogger(SourceTransformer.class); 
75      private static final Messages MESSAGES
76      = Messages.getMessages(SourceTransformer.class);
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     /**
110      * Converts the given input Source into the required result.
111      * 
112      * @param source the source to transform
113      * @param result the result of the transformation
114      * 
115      * @throws TransformerException if some transformation error occurs
116      */
117     public void toResult(Source source, Result result) throws TransformerException {
118         if (source == null) {
119             return;
120         }
121         Transformer transformer = createTransfomer();
122         if (transformer == null) {
123         	String msg=MESSAGES.getString("EJB000701_Could_not_create_transformer");
124             LOG.error(msg);
125             throw new TransformerException(msg);
126         }
127         transformer.setOutputProperty(OutputKeys.ENCODING, defaultCharset);
128         transformer.transform(source, result);
129     }
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             	String msg=MESSAGES.getString("EJB000702_No_input_stream_or_reader_available");
413                 LOG.error(msg);
414                 throw new IOException(msg);   
415             }
416         }
417         return new DOMSource(document, systemId);
418     }
419 
420 
421     /**
422      * Static initializer
423      */
424     static {
425         Class cl = null;
426         try {
427             cl = Class.forName("org.apache.xalan.xsltc.trax.DOM2SAX");
428         } catch (Throwable t) {
429             // Static initializer, do nothing...
430         	LOG.error("EJB000703_Static_initializer", new Object[]{t.getMessage()});
431             
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("EJB000704_Exception_in_toSAXSourceFromDOM", new Object[]{e.getMessage()});
455                 LOG.error(msg,e);
456                 throw new TransformerException(msg,e);   
457             }
458         } else {
459             String str = toString(source);
460             StringReader reader = new StringReader(str);
461             return new SAXSource(new InputSource(reader));
462         }
463     }
464 
465     /**
466      * To DOM source from SAX.
467      * 
468      * @param source
469      *          The source
470      * 
471      * @return the DOM source
472      * 
473      * @throws IOException
474      *             If some problem occurs
475      * @throws SAXException
476      *             If some problem occurs
477      * @throws ParserConfigurationException
478      *             If some problem occurs
479      * @throws TransformerException
480      *             If some problem occurs
481      */
482     public DOMSource toDOMSourceFromSAX(SAXSource source) throws IOException, SAXException, ParserConfigurationException, TransformerException {
483         return new DOMSource(toDOMNodeFromSAX(source));
484     }
485 
486     /**
487      * To DOM node from SAX.
488      * 
489      * @param source
490      *          The Source
491      * 
492      * @return the node
493      * 
494      * @throws ParserConfigurationException
495      *             If some problem occurs
496      * @throws IOException
497      *             If some problem occurs
498      * @throws SAXException
499      *             If some problem occurs
500      * @throws TransformerException
501      *             If some problem occurs
502      */
503     public Node toDOMNodeFromSAX(SAXSource source) throws ParserConfigurationException, IOException, SAXException, TransformerException {
504         DOMResult result = new DOMResult();
505         toResult(source, result);
506         return result.getNode();
507     }
508 
509     /**
510      * Converts the given TRaX Source into a W3C DOM node.
511      * 
512      * @param source
513      *          The source
514      * 
515      * @return
516      *      The Node
517      * 
518      * @throws SAXException
519      *             If some problem occurs
520      * @throws IOException
521      *             If some problem occurs
522      * @throws ParserConfigurationException
523      *             If some problem occurs
524      * @throws TransformerException
525      *             If some problem occurs
526      */
527     public Node toDOMNode(Source source) throws TransformerException, ParserConfigurationException, IOException, SAXException {
528         DOMSource domSrc = toDOMSource(source);
529         if (domSrc != null) {
530             return domSrc.getNode();
531         } else {
532             return null;
533         }
534     }
535 
536     /**
537      * Avoids multple parsing to DOM by caching the DOM representation in the
538      * message as a property so future calls will avoid the reparse - and avoid
539      * issues with stream based Source instances.
540      * 
541      * @param message
542      *            the normalized message
543      * 
544      * @return the W3C DOM node for this message
545      * 
546      * @throws SAXException
547      *             If some problem occurs
548      * @throws IOException
549      *             If some problem occurs
550      * @throws ParserConfigurationException
551      *             If some problem occurs
552      * @throws MessagingException
553      *             If some problem occurs
554      * @throws TransformerException
555      *             If some problem occurs
556      */
557     public Node toDOMNode(NormalizedMessage message) throws MessagingException, TransformerException, ParserConfigurationException, IOException, SAXException {
558         Source content = message.getContent();
559         Node node = toDOMNode(content);
560         return node;
561     }
562 
563     /**
564      * Create a DOM element from the normalized message.
565      * 
566      * @param message
567      * 
568      * @return
569      *      The DOM element
570      * @throws MessagingException
571      *             If some problem occurs
572      * @throws TransformerException
573      *             If some problem occurs
574      * @throws ParserConfigurationException
575      *             If some problem occurs
576      * @throws IOException
577      * @throws SAXException
578      */
579     public Element toDOMElement(NormalizedMessage message) throws MessagingException, TransformerException, ParserConfigurationException, IOException, SAXException {
580         Node node = toDOMNode(message);
581         return toDOMElement(node);
582     }
583 
584     /**
585      * Create a DOM element from the given source.
586      * 
587      * @param source
588      *      The Source
589      * 
590      * @return
591      *      The DOM element
592      * 
593      * @throws TransformerException
594      *             If some problem occurs
595      * @throws ParserConfigurationException
596      *             If some problem occurs
597      * @throws IOException
598      *             If some problem occurs
599      * @throws SAXException
600      *             If some problem occurs
601      */
602     public Element toDOMElement(Source source) throws TransformerException, ParserConfigurationException, IOException, SAXException {
603         Node node = toDOMNode(source);
604         return toDOMElement(node);
605     }
606 
607     /**
608      * Create a DOM element from the DOM node. Simply cast if the node is an
609      * Element, or return the root element if it is a Document.
610      * 
611      * @param node
612      *          The DOM node
613      * @return
614      *          The DOM element     
615      * @throws TransformerException
616      *             If some problem occurs
617      */
618     public Element toDOMElement(Node node) throws TransformerException {
619         // If the node is an document, return the root element
620         if (node instanceof Document) {
621             return ((Document) node).getDocumentElement();
622             // If the node is an element, just cast it
623         } else if (node instanceof Element) {
624             return (Element) node;
625             // Other node types are not handled
626         } else {
627         	String msg=MESSAGES.getString("EJB000705_Unable_to_convert_DOM_node_to_Element");
628             LOG.error(msg);
629             throw new TransformerException(msg);  
630         }
631     }
632 
633     /**
634      * Create a DOM document from the given normalized message.
635      * 
636      * @param message
637      *          The NormalizedMessage
638      * @return
639      *          The Document
640      * 
641      * @throws MessagingException
642      *             If some problem occurs
643      * @throws TransformerException
644      *             If some problem occurs
645      * @throws ParserConfigurationException
646      *             If some problem occurs
647      * @throws IOException
648      *             If some problem occurs
649      * @throws SAXException
650      *             If some problem occurs
651      */
652     public Document toDOMDocument(NormalizedMessage message) throws MessagingException, TransformerException, ParserConfigurationException, IOException, SAXException {
653         Node node = toDOMNode(message);
654         return toDOMDocument(node);
655     }
656 
657     /**
658      * Create a DOM document from the given source.
659      * 
660      * @param source
661      *          The Source
662      * 
663      * @return
664      *          The DOM document
665      * 
666      * @throws TransformerException
667      *             If some problem occurs
668      * @throws ParserConfigurationException
669      *             If some problem occurs
670      * @throws IOException
671      *             If some problem occurs
672      * @throws SAXException
673      *             If some problem occurs
674      */
675     public Document toDOMDocument(Source source) throws TransformerException, ParserConfigurationException, IOException, SAXException {
676         Node node = toDOMNode(source);
677         return toDOMDocument(node);
678     }
679 
680     /**
681      * Create a DOM document from the given Node. If the node is an document,
682      * just cast it, if the node is an root element, retrieve its owner element
683      * or create a new document and import the node.
684      * 
685      * @param node
686      *      The Node
687      * 
688      * @return
689      *      The DOM document
690      * 
691      * @throws ParserConfigurationException
692      *             If some problem occurs
693      * @throws TransformerException
694      *             If some problem occurs
695      */
696     public Document toDOMDocument(Node node) throws ParserConfigurationException, TransformerException {
697         // If the node is the document, just cast it
698         if (node instanceof Document) {
699             return (Document) node;
700             // If the node is an element
701         } else if (node instanceof Element) {
702             Element elem = (Element) node;
703             // If this is the root element, return its owner document
704             if (elem.getOwnerDocument().getDocumentElement() == elem) {
705                 return elem.getOwnerDocument();
706                 // else, create a new doc and copy the element inside it
707             } else {
708                 Document doc = createDocument();
709                 doc.appendChild(doc.importNode(node, true));
710                 return doc;
711             }
712             // other element types are not handled
713         } else {
714         	String msg=MESSAGES.getString("EJB000706_Unable_to_convert_DOM_node_to_Document");
715             LOG.error(msg);
716             throw new TransformerException(msg);
717         }
718     }
719 
720     // Properties
721     //-------------------------------------------------------------------------
722     /**
723      * Gets the document builder factory.
724      * 
725      * @return the document builder factory
726      */
727     public DocumentBuilderFactory getDocumentBuilderFactory() {
728         if (documentBuilderFactory == null) {
729             documentBuilderFactory = createDocumentBuilderFactory();
730         }
731         return documentBuilderFactory;
732     }
733 
734     /**
735      * Sets the document builder factory.
736      * 
737      * @param documentBuilderFactory
738      *            the new document builder factory
739      */
740     public void setDocumentBuilderFactory(DocumentBuilderFactory documentBuilderFactory) {
741         this.documentBuilderFactory = documentBuilderFactory;
742     }
743 
744 
745     // Helper methods
746     //-------------------------------------------------------------------------
747     /**
748      * Creates the document builder factory.
749      * 
750      * @return the document builder factory
751      */
752     public DocumentBuilderFactory createDocumentBuilderFactory() {
753         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
754         factory.setNamespaceAware(true);
755         factory.setIgnoringElementContentWhitespace(true);
756         factory.setIgnoringComments(true);
757         return factory;
758     }
759 
760 
761     /**
762      * Creates the document builder.
763      * 
764      * @return the document builder
765      * 
766      * @throws ParserConfigurationException
767      *             If some problem occurs
768      */
769     public DocumentBuilder createDocumentBuilder() throws ParserConfigurationException {
770         DocumentBuilderFactory factory = getDocumentBuilderFactory();
771         return factory.newDocumentBuilder();
772     }
773 
774     /**
775      * Creates the document.
776      * 
777      * @return the document
778      * 
779      * @throws ParserConfigurationException
780      *             If some problem occurs
781      */
782     public Document createDocument() throws ParserConfigurationException {
783         DocumentBuilder builder = createDocumentBuilder();
784         return builder.newDocument();
785     }
786 
787     /**
788      * Gets the transformer factory.
789      * 
790      * @return the transformer factory
791      */
792     public TransformerFactory getTransformerFactory() {
793         if (transformerFactory == null) {
794             transformerFactory = createTransformerFactory();
795         }
796         return transformerFactory;
797     }
798 
799     /**
800      * Sets the transformer factory.
801      * 
802      * @param transformerFactory
803      *            the new transformer factory
804      */
805     public void setTransformerFactory(TransformerFactory transformerFactory) {
806         this.transformerFactory = transformerFactory;
807     }
808 
809     /**
810      * Creates the transfomer.
811      * 
812      * @return the transformer
813      * 
814      * @throws TransformerConfigurationException
815      *             If some problem occurs
816      */
817     public Transformer createTransfomer() throws TransformerConfigurationException {
818         TransformerFactory factory = getTransformerFactory();
819         return factory.newTransformer();
820     }
821 
822     /**
823      * Creates the transformer factory.
824      * 
825      * @return the transformer factory
826      */
827     public TransformerFactory createTransformerFactory() {
828         TransformerFactory answer = TransformerFactory.newInstance();
829         return answer;
830     }
831 
832     /**
833      * To XML stream reader.
834      * 
835      * @param source
836      *          The Source
837      * 
838      * @return the XML stream reader
839      * 
840      * @throws XMLStreamException
841      *             If some problem occurs
842      * @throws TransformerException
843      *             If some problem occurs
844      */
845     public XMLStreamReader toXMLStreamReader(Source source) throws XMLStreamException, TransformerException {
846 //      Uncomment to support StaxSource
847 //      if (source instanceof StaxSource) {
848 //      return ((StaxSource) source).getXMLStreamReader();
849 //      }
850         // It seems that woodstox 2.9.3 throws some NPE in the servicemix-soap
851         // when using DOM, so use our own dom / stax parser
852         if (source instanceof DOMSource) {
853             Node n = ((DOMSource) source).getNode();
854             
855             Element el = null;
856             if (n instanceof Document) {
857                 el = ((Document) n).getDocumentElement();
858             } else if (n instanceof Element ) {
859                 el =(Element) n;
860             }             
861             if (el != null) {
862                 return new W3CDOMStreamReader(el);
863             }
864         }
865         XMLInputFactory factory = getInputFactory();
866         try {
867             return factory.createXMLStreamReader(source);
868         } catch (XMLStreamException e) {
869             return factory.createXMLStreamReader(toReaderFromSource(source));
870         }
871     }
872 
873     // Implementation methods
874     //-------------------------------------------------------------------------
875     /**
876      * Creates the input factory.
877      * 
878      * @return the XML input factory
879      */
880     protected XMLInputFactory createInputFactory() {
881         XMLInputFactory answer = XMLInputFactory.newInstance();
882         return answer;
883     }
884 
885     // Properties
886     //-------------------------------------------------------------------------
887     /**
888      * Gets the input factory.
889      * 
890      * @return the input factory
891      */
892     public XMLInputFactory getInputFactory() {
893         if (inputFactory == null) {
894             inputFactory = createInputFactory();
895         }
896         return inputFactory;
897     }    
898 }