package org.odata4j.producer.resources; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import javax.ws.rs.Produces; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.ext.MessageBodyWriter; import javax.ws.rs.ext.Provider; import org.odata4j.core.ODataConstants; import org.odata4j.format.writer.BufferOrFileResponseHolder; import com.sun.jersey.core.util.ReaderWriter; @Provider @Produces({ ODataConstants.APPLICATION_ATOM_XML_CHARSET_UTF8, ODataConstants.APPLICATION_XML_CHARSET_UTF8, ODataConstants.APPLICATION_JAVASCRIPT_VERBOSE_CHARSET_UTF8, ODataConstants.TEXT_JAVASCRIPT_CHARSET_UTF8 }) public class ODataWriteResponseProvider implements MessageBodyWriter<BufferOrFileResponseHolder> { /** * Called before writeTo to ascertain the length in bytes of the serialized form of responseHolder. * A non-negative return value is used in a HTTP Content-Length header<br><br> * * We always return the value of -1 so that it is not set in the content header. * * @param responseHolder - the response holder which is the instance to write * @param type - the class of object that is to be written. * @param genericType - the type of object to be written, obtained either by reflection of a resource method return type or by inspection of the returned instance. * @param annotations - an array of the annotations on the resource method that returns the object. * @param mediaType - the media type of the HTTP entity. * @return the size */ @Override public long getSize(BufferOrFileResponseHolder responseHolder, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { return -1; } /** * Ascertain if the MessageBodyWriter supports a particular type. * * @param type - the class of object that is to be written. * @param genericType - the type of object to be written, obtained either by reflection of a resource method return type or by inspection of the returned instance. * @param annotations - an array of the annotations on the resource method that returns the object. * @param mediaType - the media type of the HTTP entity. * @return true, if is writeable */ @Override public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { return BufferOrFileResponseHolder.class.isAssignableFrom(type); } /** * Write a type to an HTTP response. The response header map is mutable but any changes must be made before writing to the output stream * since the headers will be flushed prior to writing the response body. * * @param responseHolder - the response holder which is the instance to write * @param type - the class of object that is to be written. * @param genericType - the type of object to be written, obtained either by reflection of a resource method return type or by inspection of the returned instance. * @param annotations - an array of the annotations on the resource method that returns the object. * @param mediaType - the media type of the HTTP entity. * @param valueMap - a mutable map of the HTTP response headers * @param outputStream - the OutputStream for the HTTP entity. The implementation should not close the output stream. * @throws IOException Signals that an I/O exception has occurred. * @throws WebApplicationException the web application exception */ @Override public void writeTo(BufferOrFileResponseHolder responseHolder, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> valueMap, OutputStream outputStream) throws IOException, WebApplicationException { if (responseHolder.isFileUsedForStorage()) { FileInputStream fileInputStream = null; try { fileInputStream = new FileInputStream(responseHolder.getResponseFile()); //The data is written to the output stream provided by the Jersey hook into MessageBodyWriter ReaderWriter.writeTo(fileInputStream, outputStream); //Flush any remaining data held in the writer outputStream.flush(); } finally { //Close the input stream to the file if (fileInputStream != null) { fileInputStream.close(); fileInputStream = null; } // Delete the temp file that was created if (responseHolder.getResponseFile() != null && responseHolder.getResponseFile().exists()) { responseHolder.getResponseFile().delete(); } } } else { //Write contents of buffer to the outputstream ReaderWriter.writeToAsString(responseHolder.getBuffer().toString(), outputStream, mediaType); } } }