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.lifecycle.InitialisationException;
10  import org.mule.api.transformer.DataType;
11  import org.mule.api.transformer.TransformerException;
12  import org.mule.config.i18n.CoreMessages;
13  import org.mule.transformer.AbstractTransformer;
14  import org.mule.transformer.types.DataTypeFactory;
15  
16  import java.io.File;
17  import java.io.InputStream;
18  import java.io.StringReader;
19  import java.io.Writer;
20  import java.net.URL;
21  
22  import javax.xml.bind.JAXBContext;
23  import javax.xml.bind.JAXBElement;
24  import javax.xml.bind.JAXBException;
25  import javax.xml.bind.Unmarshaller;
26  import javax.xml.stream.XMLEventReader;
27  import javax.xml.stream.XMLStreamReader;
28  import javax.xml.transform.Source;
29  
30  import org.w3c.dom.Node;
31  
32  /**
33   * Allows un-marshaling of XML generated by JAXB to a Java object graph. By default the returnType for this transformer is {@link Object}
34   * If a specific returnType is set and ff no external {@link javax.xml.bind.JAXBContext} is set on the transformer, then a
35   * {@link javax.xml.bind.JAXBContext} will be created using the returnType.
36   *
37   * @since 3.0
38   */
39  public class JAXBUnmarshallerTransformer extends AbstractTransformer
40  {
41      protected JAXBContext jaxbContext;
42  
43      public JAXBUnmarshallerTransformer()
44      {
45          registerSourceType(DataTypeFactory.STRING);
46          registerSourceType(DataTypeFactory.create(Writer.class));
47          registerSourceType(DataTypeFactory.create(File.class));
48          registerSourceType(DataTypeFactory.create(URL.class));
49          registerSourceType(DataTypeFactory.create(Node.class));
50          registerSourceType(DataTypeFactory.INPUT_STREAM);
51          registerSourceType(DataTypeFactory.create(Source.class));
52          registerSourceType(DataTypeFactory.create(XMLStreamReader.class));
53          registerSourceType(DataTypeFactory.create(XMLEventReader.class));
54      }
55  
56      public JAXBUnmarshallerTransformer(JAXBContext jaxbContext, DataType returnType)
57      {
58          this();
59          this.jaxbContext = jaxbContext;
60          setReturnDataType(returnType);
61      }
62  
63      @Override
64      public void initialise() throws InitialisationException
65      {
66          super.initialise();
67          if (jaxbContext == null)
68          {
69              if(Object.class.equals(getReturnDataType().getType()))
70              {
71                  throw new InitialisationException(CoreMessages.objectIsNull("jaxbContext"), this);
72              }
73              else
74              {
75                  try
76                  {
77                      jaxbContext = JAXBContext.newInstance(getReturnDataType().getType());
78                  }
79                  catch (JAXBException e)
80                  {
81                      throw new InitialisationException(e, this);
82                  }
83              }
84          }
85      }
86  
87      @Override
88      protected Object doTransform(Object src, String encoding) throws TransformerException
89      {
90          try
91          {
92              final Unmarshaller u = jaxbContext.createUnmarshaller();
93              Object result = null;
94              if (src instanceof String)
95              {
96                  result = u.unmarshal(new StringReader((String) src));
97              }
98              else if (src instanceof File)
99              {
100                 result = u.unmarshal((File) src);
101             }
102             else if (src instanceof URL)
103             {
104                 result = u.unmarshal((URL) src);
105             }
106             else if (src instanceof InputStream)
107             {
108                 result = u.unmarshal((InputStream) src);
109             }
110             else if (src instanceof Node)
111             {
112                 result = u.unmarshal((Node) src, getReturnClass());
113             }
114             else if (src instanceof Source)
115             {
116                 result = u.unmarshal((Source) src, getReturnClass());
117             }
118             else if (src instanceof XMLStreamReader)
119             {
120                 result = u.unmarshal((XMLStreamReader) src, getReturnClass());
121             }
122             else if (src instanceof XMLEventReader)
123             {
124                 result = u.unmarshal((XMLEventReader) src, getReturnClass());
125             }
126             if (result != null)
127             {
128                 // If we get a JAXB element, return its contents
129                 if (result instanceof JAXBElement)
130                 {
131                     result = ((JAXBElement)result).getValue();
132                 }
133             }
134             return result;
135         }
136         catch (Exception e)
137         {
138             throw new TransformerException(this, e);
139         }
140     }
141 
142     public JAXBContext getJaxbContext()
143     {
144         return jaxbContext;
145     }
146 
147     public void setJaxbContext(JAXBContext jaxbContext)
148     {
149         this.jaxbContext = jaxbContext;
150     }
151 }