View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.module.xml.transformer;
8   
9   import org.mule.api.MuleEvent;
10  import org.mule.api.MuleMessage;
11  import org.mule.api.transformer.DiscoverableTransformer;
12  import org.mule.api.transport.OutputHandler;
13  import org.mule.module.xml.util.XMLUtils;
14  import org.mule.transformer.types.DataTypeFactory;
15  
16  import java.io.IOException;
17  import java.io.OutputStream;
18  
19  import javax.xml.stream.XMLStreamReader;
20  import javax.xml.stream.XMLStreamWriter;
21  import javax.xml.transform.Source;
22  import javax.xml.transform.TransformerFactoryConfigurationError;
23  import javax.xml.transform.stream.StreamResult;
24  
25  import org.dom4j.Document;
26  
27  public class XmlToOutputHandler extends AbstractXmlTransformer implements DiscoverableTransformer
28  {
29  
30      private int priorityWeighting = DiscoverableTransformer.DEFAULT_PRIORITY_WEIGHTING;
31  
32      public XmlToOutputHandler()
33      {
34          registerSourceType(DataTypeFactory.STRING);
35          registerSourceType(DataTypeFactory.BYTE_ARRAY);
36          registerSourceType(DataTypeFactory.create(Source.class));
37          registerSourceType(DataTypeFactory.create(Document.class));
38          registerSourceType(DataTypeFactory.create(org.w3c.dom.Document.class));
39          registerSourceType(DataTypeFactory.create(org.w3c.dom.Element.class));
40          registerSourceType(DataTypeFactory.INPUT_STREAM);
41          registerSourceType(DataTypeFactory.create(OutputHandler.class));
42          registerSourceType(DataTypeFactory.create(XMLStreamReader.class));
43          registerSourceType(DataTypeFactory.create(DelayedResult.class));
44          setReturnDataType(DataTypeFactory.create(OutputHandler.class));
45      }
46  
47      @Override
48      public Object transformMessage(MuleMessage message, final String encoding)
49      {
50          final Object src = message.getPayload();
51          return new OutputHandler()
52          {
53              public void write(MuleEvent event, OutputStream out) throws IOException
54              {
55                  writeXml(src, encoding, out);
56              }
57          };
58      }
59  
60      protected void writeXml(final Object src, final String encoding, OutputStream out)
61          throws TransformerFactoryConfigurationError, IOException
62      {
63          try
64          {
65              if (src instanceof XMLStreamReader)
66              {
67                  // Unfortunately, the StAX source doesn't copy/serialize correctly so
68                  // we have to do this little hack.
69                  XMLStreamReader reader = (XMLStreamReader)src;
70                  XMLStreamWriter writer = getXMLOutputFactory().createXMLStreamWriter(out);
71                  
72                  try {
73                      writer.writeStartDocument();
74                      XMLUtils.copy(reader, writer);
75                      writer.writeEndDocument();
76                  } finally {
77                      writer.close();
78                      reader.close();
79                  }
80              }
81              else if (src instanceof DelayedResult)
82              {
83                  DelayedResult result = (DelayedResult) src;
84                  
85                  StreamResult streamResult = new StreamResult(out);
86                  result.write(streamResult);
87              }
88              else
89              {
90                  writeToStream(src, encoding, out);
91              }
92          }
93          catch (Exception e)
94          {
95              IOException ioe = new IOException(e.toString());
96              ioe.initCause(e);
97              throw ioe;
98          }
99      }
100 
101     public int getPriorityWeighting()
102     {
103         return priorityWeighting;
104     }
105 
106     public void setPriorityWeighting(int priorityWeighting)
107     {
108         this.priorityWeighting = priorityWeighting;
109     }
110     
111 }