View Javadoc
1   package org.apache.maven.plugin.failsafe.xmlsummary;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import javax.xml.bind.JAXBContext;
23  import javax.xml.bind.JAXBElement;
24  import javax.xml.bind.JAXBException;
25  import javax.xml.bind.Marshaller;
26  import javax.xml.bind.PropertyException;
27  import javax.xml.bind.Unmarshaller;
28  import javax.xml.bind.annotation.XmlRootElement;
29  import javax.xml.bind.helpers.DefaultValidationEventHandler;
30  import javax.xml.namespace.QName;
31  import javax.xml.transform.stream.StreamSource;
32  import java.io.File;
33  import java.io.IOException;
34  import java.io.StringWriter;
35  import java.io.Writer;
36  import java.nio.charset.Charset;
37  import java.util.Collections;
38  import java.util.Map;
39  import java.util.Map.Entry;
40  
41  import static javax.xml.bind.JAXBContext.newInstance;
42  import static javax.xml.bind.Marshaller.JAXB_ENCODING;
43  import static javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT;
44  import static javax.xml.bind.Marshaller.JAXB_FRAGMENT;
45  
46  /**
47   * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
48   * @since 2.20
49   */
50  public final class JAXB
51  {
52      private JAXB()
53      {
54          throw new IllegalStateException( "Not instantiated constructor." );
55      }
56  
57      public static <T> T unmarshal( File source, Class<T> rootXmlNode ) throws JAXBException
58      {
59          return unmarshal( source, rootXmlNode, Collections.<String, Object>emptyMap() );
60      }
61  
62      public static <T> T unmarshal( File source, Class<T> rootXmlNode, Map<String, ?> props )
63              throws JAXBException
64      {
65          Class<?>[] classesToBeBound = { rootXmlNode };
66          JAXBContext ctx = newInstance( classesToBeBound );
67          Unmarshaller unmarshaller = ctx.createUnmarshaller();
68          properties( props, unmarshaller );
69          unmarshaller.setEventHandler( new DefaultValidationEventHandler() );
70          JAXBElement<T> element = unmarshaller.unmarshal( new StreamSource( source ), rootXmlNode );
71          return element.getValue();
72      }
73  
74      public static <T> String marshal( T bean, Charset encoding ) throws JAXBException, IOException
75      {
76          return marshal( bean, Collections.<String, Object>emptyMap(), encoding ).toString();
77      }
78  
79      @SuppressWarnings( "unchecked" )
80      public static <T> StringWriter marshal( T bean, Map<String, Object> props, Charset encoding )
81              throws JAXBException, IOException
82      {
83          return marshal( bean, (Class<T>) bean.getClass(), props, encoding );
84      }
85  
86      public static <T> StringWriter marshal( T bean, Class<T> type, Map<String, Object> props, Charset encoding )
87              throws JAXBException, IOException
88      {
89          JAXBElement<T> rootElement = buildJaxbElement( bean, type );
90          return marshal( rootElement, type, props, encoding );
91      }
92  
93      public static <T> StringWriter marshal( JAXBElement<T> rootElement, Class<T> type,
94                                              Map<String, Object> props, Charset encoding )
95              throws JAXBException, IOException
96      {
97          StringWriter destination = new StringWriter( 256 );
98          marshal( rootElement, type, props, destination, encoding );
99          destination.flush();
100         return destination;
101     }
102 
103     public static <T> void marshal( JAXBElement<T> rootElement, Class<T> type, Map<String, Object> props,
104                                     Writer destination, Charset encoding ) throws JAXBException
105     {
106         Class<?>[] classesToBeBound = { type };
107         JAXBContext context = newInstance( classesToBeBound );
108         Marshaller marshaller = context.createMarshaller();
109         marshaller.setProperty( JAXB_ENCODING, encoding.name() );
110         marshaller.setProperty( JAXB_FORMATTED_OUTPUT, true );
111         marshaller.setProperty( JAXB_FRAGMENT, true );
112         properties( props, marshaller );
113         marshaller.marshal( rootElement, destination );
114     }
115 
116     private static <T> JAXBElement<T> buildJaxbElement( T bean, Class<T> type )
117     {
118         XmlRootElement xmlRootElement = type.getAnnotation( XmlRootElement.class );
119         if ( xmlRootElement == null )
120         {
121             return null;
122         }
123         QName root = new QName( "", xmlRootElement.name() );
124         return new JAXBElement<T>( root, type, bean );
125     }
126 
127     private static void properties( Map<String, ?> props, Unmarshaller unmarshaller ) throws PropertyException
128     {
129         for ( Entry<String, ?> e : props.entrySet() )
130         {
131             unmarshaller.setProperty( e.getKey(), e.getValue() );
132         }
133     }
134 
135     private static void properties( Map<String, ?> props, Marshaller marshaller ) throws PropertyException
136     {
137         for ( Entry<String, ?> e : props.entrySet() )
138         {
139             marshaller.setProperty( e.getKey(), e.getValue() );
140         }
141     }
142 }