View Javadoc

1   /* This file is part of COPAL (COntext Provisioning for All).
2    *
3    * COPAL is a part of SM4All (Smart hoMes for All) project.
4    *
5    * COPAL is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU Lesser General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    *
10   * COPAL is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU Lesser General Public License for more details.
14   *
15   * You should have received a copy of the GNU Lesser General Public License
16   * along with COPAL. If not, see <http://www.gnu.org/licenses/>.
17   */
18  package at.ac.tuwien.infosys.sm4all.copal.rest.provider;
19  
20  import java.io.OutputStream;
21  import java.lang.annotation.Annotation;
22  import java.lang.reflect.Type;
23  import javax.ws.rs.Produces;
24  import javax.ws.rs.WebApplicationException;
25  import javax.ws.rs.core.MediaType;
26  import javax.ws.rs.core.MultivaluedMap;
27  import javax.ws.rs.core.Response.Status;
28  import javax.ws.rs.ext.MessageBodyWriter;
29  import javax.ws.rs.ext.Provider;
30  import javax.xml.parsers.DocumentBuilderFactory;
31  import javax.xml.parsers.ParserConfigurationException;
32  import javax.xml.transform.OutputKeys;
33  import javax.xml.transform.Transformer;
34  import javax.xml.transform.TransformerConfigurationException;
35  import javax.xml.transform.TransformerException;
36  import javax.xml.transform.TransformerFactory;
37  import javax.xml.transform.dom.DOMSource;
38  import javax.xml.transform.stream.StreamResult;
39  import org.w3c.dom.Document;
40  import org.w3c.dom.Element;
41  import at.ac.tuwien.infosys.sm4all.copal.api.event.xml.Constants;
42  import at.ac.tuwien.infosys.sm4all.copal.api.event.xml.query.XMLContextQueries;
43  import at.ac.tuwien.infosys.sm4all.copal.rest.model.ContextQueries;
44  
45  /**
46   * A {@link MessageBodyWriter} that transforms an instance of
47   * {@link ContextQueries} into <code>application/xml</code>.
48   * 
49   * @author sanjin
50   */
51  @Provider
52  @Produces("application/xml")
53  public class XMLContextQueriesWriter implements
54          MessageBodyWriter<ContextQueries> {
55  
56      private final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
57      private final TransformerFactory transformerFactory = TransformerFactory.newInstance();
58  
59      /**
60       * Creates an instance of <code>application/xml</code>
61       * {@link ContextQueries} {@link MessageBodyWriter}.
62       */
63      public XMLContextQueriesWriter() {
64          super();
65  
66          this.documentBuilderFactory.setNamespaceAware(true);
67  
68      }
69  
70      @Override
71      public long getSize(final ContextQueries queries, final Class<?> klass,
72              final Type genericType, final Annotation[] annotations,
73              final MediaType mediaType) {
74          return -1;
75      }
76  
77      @Override
78      public boolean isWriteable(final Class<?> klass, final Type genericType,
79              final Annotation[] annotations, final MediaType mediaType) {
80          return ContextQueries.class.isAssignableFrom(klass);
81      }
82  
83      @Override
84      public void writeTo(final ContextQueries queries, final Class<?> klass,
85              final Type genericType, final Annotation[] annotations,
86              final MediaType mediaType,
87              final MultivaluedMap<String, Object> httpHeaders,
88              final OutputStream out) throws WebApplicationException {
89          try {
90              final Transformer transformer = this.transformerFactory.newTransformer();
91              transformer.setOutputProperty(OutputKeys.INDENT, "yes");
92  
93              final Document document = this.documentBuilderFactory.newDocumentBuilder().newDocument();
94              final Element context = document.createElementNS(
95                      Constants.COPAL_NAMESPACE_URI, Constants.COPAL_PREFIX
96                              + ":Context");
97              new XMLContextQueries(context).marshal(queries.toArray());
98              document.appendChild(context);
99  
100             final StreamResult result = new StreamResult(out);
101             final DOMSource source = new DOMSource(document);
102             transformer.transform(source, result);
103         } catch (final TransformerConfigurationException ex) {
104             throw new WebApplicationException(ex, Status.INTERNAL_SERVER_ERROR);
105         } catch (final ParserConfigurationException ex) {
106             throw new WebApplicationException(ex, Status.INTERNAL_SERVER_ERROR);
107         } catch (final TransformerException ex) {
108             throw new WebApplicationException(ex, Status.INTERNAL_SERVER_ERROR);
109         }
110     }
111 }