View Javadoc
1   package ejava.examples.ejbwar.inventory.rs;
2   
3   import java.io.IOException;
4   
5   import java.io.OutputStream;
6   import java.lang.annotation.Annotation;
7   import java.lang.reflect.Type;
8   
9   import javax.ws.rs.Produces;
10  import javax.ws.rs.WebApplicationException;
11  import javax.ws.rs.core.Context;
12  import javax.ws.rs.core.MediaType;
13  import javax.ws.rs.core.MultivaluedMap;
14  import javax.ws.rs.ext.ContextResolver;
15  import javax.ws.rs.ext.MessageBodyWriter;
16  import javax.ws.rs.ext.Provider;
17  import javax.ws.rs.ext.Providers;
18  import javax.xml.bind.JAXBContext;
19  import javax.xml.bind.JAXBException;
20  import javax.xml.bind.Marshaller;
21  import javax.xml.bind.annotation.XmlRootElement;
22  
23  /**
24   * Put this class in your JAX-RS application to have XML output formatted
25   * so that it is easier to read.
26   */
27  @Provider
28  @Produces(MediaType.APPLICATION_XML)
29  public class PrettyPrinter implements MessageBodyWriter<Object> {
30  
31      @Context protected Providers providers;
32  
33      public long getSize(Object object, Class<?> type, Type genericType,
34              Annotation[] methodAnnotations, MediaType mediaType) {
35          return -1; //says we don't know
36      }
37  
38      /**
39       * Return true for any JAXB class
40       */
41      public boolean isWriteable(Class<?> type, Type genericType, 
42              Annotation[] methodAnnotations, MediaType mediaType) {
43          if (MediaType.APPLICATION_XML_TYPE == mediaType) {
44              for(Class<?> clazz = type;clazz != null; clazz=clazz.getSuperclass()) {
45                  if (clazz.isAnnotationPresent(XmlRootElement.class)) {
46                      return true;
47                  }
48              }
49          }
50          return false;
51      }
52  
53      /**
54       * Write the provided JAXB object using formatted output.
55       */
56      public void writeTo(Object object, Class<?> type, Type genericType,
57              Annotation[] methodAnnotations, MediaType mediaType,
58              MultivaluedMap<String, Object> httpHeaders, OutputStream os)
59              throws IOException, WebApplicationException {
60  
61      	//get a JAXBContext that can marshall the JAXBObject
62          JAXBContext ctx = null;
63          ContextResolver<JAXBContext> resolver = 
64              providers.getContextResolver(JAXBContext.class, MediaType.APPLICATION_XML_TYPE);
65          if (resolver != null) {
66              ctx = resolver.getContext(type);
67          }
68          
69          //if none is found, try a default one
70          if (ctx == null) {
71              try { ctx = JAXBContext.newInstance(type); } 
72              catch (JAXBException ex) {throw new RuntimeException("error creating ad-hoc jaxbContext", ex);}
73          }
74  
75          //marshall the object to the provided stream
76          try {
77              Marshaller marshaller = ctx.createMarshaller();
78              marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
79              marshaller.marshal(object, os);
80              os.flush();
81          } catch (JAXBException ex) {
82              throw new RuntimeException("error marshalling XML", ex);
83          } finally {}
84      }
85  }