/** * Copyright 2005-2014 Restlet * * The contents of this file are subject to the terms of one of the following * open source licenses: Apache 2.0 or or EPL 1.0 (the "Licenses"). You can * select the license that you prefer but you may not use this file except in * compliance with one of these Licenses. * * You can obtain a copy of the Apache 2.0 license at * http://www.opensource.org/licenses/apache-2.0 * * You can obtain a copy of the EPL 1.0 license at * http://www.opensource.org/licenses/eclipse-1.0 * * See the Licenses for the specific language governing permissions and * limitations under the Licenses. * * Alternatively, you can obtain a royalty free commercial license with less * limitations, transferable or non-transferable, directly at * http://restlet.com/products/restlet-framework * * Restlet is a registered trademark of Restlet S.A.S. */ package org.restlet.ext.jaxrs.internal.provider; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.logging.Logger; import javax.ws.rs.Consumes; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.ext.MessageBodyReader; import javax.ws.rs.ext.MessageBodyWriter; import javax.ws.rs.ext.Provider; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import javax.xml.transform.stream.StreamSource; import org.restlet.Context; import org.restlet.ext.jaxrs.internal.exceptions.ImplementationException; import org.restlet.ext.jaxrs.internal.util.Util; /** * Provider for {@link JAXBElement}s. * * @author Stephan Koops * @see MessageBodyReader * @see MessageBodyWriter */ @Provider @Produces({ "application/xml", MediaType.TEXT_XML, "application/*+xml" }) @Consumes({ "application/xml", MediaType.TEXT_XML, "application/*+xml" }) public class JaxbElementProvider extends AbstractJaxbProvider<JAXBElement<?>> { private final Logger logger = Context.getCurrentLogger(); @Override Logger getLogger() { return this.logger; } /** * @see MessageBodyReader#isReadable(Class, Type, Annotation[]) */ @Override public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { if (!JAXBElement.class.isAssignableFrom(type)) { return false; } return Util.getGenericClass(genericType) != null; } /** * @see MessageBodyWriter#isWriteable(Class, Type, Annotation[]) */ @Override public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { if (!type.isAssignableFrom(JAXBElement.class)) { return false; } return Util.getGenericClass(genericType) != null; } /** * @see MessageBodyReader#readFrom(Class, Type, MediaType, Annotation[], * MultivaluedMap, InputStream) */ @Override public JAXBElement<?> readFrom(Class<JAXBElement<?>> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpResponseHeaders, InputStream entityStream) throws IOException { final Class<?> clazz = Util.getGenericClass(genericType); if (clazz == null) { throw new ImplementationException( "The JaxbElement provider has gotten a type it could not unmarshal. Perhaps is the JaxbElementProvider not consistent to itself."); } try { final JAXBContext jaxbContext = getJaxbContext(clazz); final Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); JAXBElement<?> je = unmarshaller.unmarshal(new StreamSource( entityStream), type); return je; } catch (JAXBException e) { final String message = "Could not unmarshal to " + type.getName(); throw logAndIOExc(getLogger(), message, e); } } /** * @see MessageBodyWriter#writeTo(Object, Class, Type, Annotation[], * MediaType, MultivaluedMap, OutputStream) */ @Override public void writeTo(JAXBElement<?> jaxbElement, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpResponseHeaders, OutputStream entityStream) throws IOException { marshal(jaxbElement.getValue(), entityStream); } }