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.jaxb;
8   
9   import org.mule.api.MuleEvent;
10  import org.mule.api.lifecycle.InitialisationException;
11  import org.mule.api.transformer.DataType;
12  import org.mule.api.transformer.TransformerException;
13  import org.mule.api.transport.OutputHandler;
14  import org.mule.config.i18n.CoreMessages;
15  import org.mule.transformer.AbstractTransformer;
16  import org.mule.transformer.types.DataTypeFactory;
17  
18  import java.io.ByteArrayOutputStream;
19  import java.io.IOException;
20  import java.io.OutputStream;
21  import java.io.StringWriter;
22  import java.io.Writer;
23  
24  import javax.xml.bind.JAXBContext;
25  import javax.xml.bind.JAXBException;
26  import javax.xml.bind.Marshaller;
27  import javax.xml.parsers.DocumentBuilderFactory;
28  
29  import org.w3c.dom.Document;
30  
31  /**
32   * Allows marshaling of Java objects to XML using JAXB 2.  A specific sourceClass can be set on this transformer, this
33   * is the expected source object type.  If no external {@link javax.xml.bind.JAXBContext} is set on the transformer, but
34   * the 'sourceClass' is set, a {@link javax.xml.bind.JAXBContext} will be created using the sourceClass.
35   *
36   * @since 3.0
37   */
38  public class JAXBMarshallerTransformer extends AbstractTransformer
39  {
40      protected JAXBContext jaxbContext;
41  
42      protected Class<?> sourceClass;
43  
44      public JAXBMarshallerTransformer()
45      {
46          setReturnDataType(DataTypeFactory.create(OutputStream.class));
47          registerSourceType(DataTypeFactory.OBJECT);
48      }
49  
50      public JAXBMarshallerTransformer(JAXBContext jaxbContext, DataType returnType)
51      {
52          this();
53          this.jaxbContext = jaxbContext;
54          setReturnDataType(returnType);
55      }
56  
57      @Override
58      public void initialise() throws InitialisationException
59      {
60          super.initialise();
61          if (jaxbContext == null)
62          {
63              throw new InitialisationException(CoreMessages.objectIsNull("jaxbContext"), this);
64          }
65      }
66  
67      @Override
68      protected Object doTransform(final Object src, String encoding) throws TransformerException
69      {
70          try
71          {
72              final Marshaller m = jaxbContext.createMarshaller();
73              if (getReturnClass().equals(String.class))
74              {
75                  Writer w = new StringWriter();
76                  m.marshal(src, w);
77                  return w.toString();
78              }
79              else if (getReturnClass().isAssignableFrom(Writer.class))
80              {
81                  Writer w = new StringWriter();
82                  m.marshal(src, w);
83                  return w;
84              }
85              else if (Document.class.isAssignableFrom(getReturnClass()))
86              {
87                  DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
88                  Document doc = factory.newDocumentBuilder().newDocument();
89                  m.marshal(src, doc);
90                  return doc;
91              }
92              else if (OutputStream.class.isAssignableFrom(getReturnClass()))
93              {
94                  ByteArrayOutputStream out = new ByteArrayOutputStream();
95                  m.marshal(src, out);
96                  return out;
97              }
98              else if (OutputHandler.class.equals(getReturnClass()))
99              {
100                 return new OutputHandler()
101                 {
102                     public void write(MuleEvent event, OutputStream out) throws IOException
103                     {
104                         try
105                         {
106                             m.marshal(src, out);
107                         }
108                         catch (JAXBException e)
109                         {
110                             IOException iox = new IOException("failed to mashal objec tto XML");
111                             iox.initCause(e);
112                             throw iox;
113                         }
114                     }
115                 };
116             }
117             else
118             {
119                 throw new TransformerException(CoreMessages.transformerInvalidReturnType(getReturnClass(), getName()));
120             }
121 
122         }
123         catch (Exception e)
124         {
125             throw new TransformerException(this, e);
126         }
127     }
128 
129     public JAXBContext getJaxbContext()
130     {
131         return jaxbContext;
132     }
133 
134     public void setJaxbContext(JAXBContext jaxbContext)
135     {
136         this.jaxbContext = jaxbContext;
137     }
138 
139     public Class<?> getSourceClass()
140     {
141         return sourceClass;
142     }
143 
144     public void setSourceClass(Class<?> sourceClass)
145     {
146         this.sourceClass = sourceClass;
147     }
148 }