/** * Copyright (C) 2011-2015 The XDocReport Team <xdocreport@googlegroups.com> * * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package fr.opensagres.xdocreport.remoting.reporting.server; import java.io.IOException; import java.io.OutputStream; import java.io.StringReader; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import javax.activation.DataSource; import javax.ws.rs.Consumes; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.ResponseBuilder; import javax.ws.rs.core.StreamingOutput; import org.apache.cxf.jaxrs.ext.multipart.Multipart; import org.xml.sax.SAXException; import fr.opensagres.xdocreport.converter.IConverter; import fr.opensagres.xdocreport.converter.Options; import fr.opensagres.xdocreport.converter.XDocConverterException; import fr.opensagres.xdocreport.core.XDocReportException; import fr.opensagres.xdocreport.core.io.IOUtils; import fr.opensagres.xdocreport.core.logging.LogUtils; import fr.opensagres.xdocreport.core.utils.HttpHeaderUtils; import fr.opensagres.xdocreport.core.utils.StringUtils; import fr.opensagres.xdocreport.document.IXDocReport; import fr.opensagres.xdocreport.document.XDocReport; import fr.opensagres.xdocreport.document.json.JSONObject; import fr.opensagres.xdocreport.document.registry.XDocReportRegistry; import fr.opensagres.xdocreport.remoting.reporting.ReportingService; import fr.opensagres.xdocreport.template.formatter.FieldsMetadata; import fr.opensagres.xdocreport.template.formatter.FieldsMetadataXMLSerializer; /** * Reporting REST Web Service implementation. */ @Path( "/" ) public class ReportingServiceImpl implements ReportingService { private static final Logger LOGGER = LogUtils.getLogger( ReportingServiceImpl.class ); @POST @Consumes( MediaType.WILDCARD ) @Produces( MediaType.WILDCARD ) @Path( "/report" ) public Response report( @Multipart( "templateDocument" ) DataSource templateDocument, @Multipart( "templateEngineKind" ) String templateEngineKind, @Multipart( value = "metadata", required = false ) String xmlFieldsMetadata, @Multipart( "data" ) String data, @Multipart( value = "dataType", required = false ) String dataType, @Multipart( value="outFileName", required = false ) String outFileName, @Multipart( value = "outFormat", required = false ) String outFormat, @Multipart( value = "outFormatVia", required = false ) final String via ) { try { FieldsMetadata metadata = getFieldsMetadata( xmlFieldsMetadata ); // Load report final IXDocReport report = XDocReport.loadReport( templateDocument.getInputStream(), templateEngineKind, metadata, XDocReportRegistry.getRegistry() ); return doReport( report, data, dataType, outFileName, outFormat, via ); } catch ( Exception e ) { throw new RuntimeException( e ); } } private FieldsMetadata getFieldsMetadata( String xmlFieldsMetadata ) throws SAXException, IOException { FieldsMetadata metadata = null; if ( StringUtils.isNotEmpty( xmlFieldsMetadata ) ) { metadata = FieldsMetadataXMLSerializer.getInstance().load( new StringReader( xmlFieldsMetadata ) ); } return metadata; } @POST @Consumes( MediaType.WILDCARD ) @Produces( MediaType.WILDCARD ) @Path( "/report2" ) public Response report2( String reportId, @Multipart( "data" ) String data, @Multipart( value = "dataType", required = false ) String dataType, @Multipart( "templateEngineKind" ) final String templateEngineKind, @Multipart( "outFileName" ) final String outFileName, @Multipart( value = "outFormat", required = false ) String outFormat, @Multipart( value = "outFormatVia", required = false ) final String via ) { try { // TODO : manage FieldsMetadata FieldsMetadata metadata = null; // Load report final IXDocReport report = null; return doReport( report, data, dataType, outFileName, outFormat, via ); } catch ( Exception e ) { throw new RuntimeException( e ); } } private Response doReport( final IXDocReport report, String data, String dataType, final String outFileName, final String outFormat, final String via ) throws Exception { // Transform string data to Map. final Map contextMap = toMap( data, dataType ); Options options = getOptions( outFormat, via ); StreamingOutput output = new StreamingOutput() { public void write( OutputStream out ) throws IOException, WebApplicationException { try { long start = System.currentTimeMillis(); if ( StringUtils.isNotEmpty( outFormat ) ) { Options options = getOptions( outFormat, via ); report.convert( contextMap, options, out ); } else { report.process( contextMap, out ); } if ( LOGGER.isLoggable( Level.INFO ) ) { LOGGER.info( "Time spent to generate report " + report.getId() + ": " + ( System.currentTimeMillis() - start ) + " ms " ); } } catch ( XDocReportException e ) { if ( LOGGER.isLoggable( Level.SEVERE ) ) { LOGGER.log( Level.SEVERE, "Converter error", e ); } throw new WebApplicationException( e ); } catch ( RuntimeException e ) { if ( LOGGER.isLoggable( Level.SEVERE ) ) { LOGGER.log( Level.SEVERE, "RuntimeException", e ); } throw new WebApplicationException( e ); } finally { IOUtils.closeQuietly( out ); } } }; // 5) Create the JAX-RS response builder. MediaType mediaType = getMediaType( report, options ); ResponseBuilder responseBuilder = Response.ok( output, mediaType ); if ( StringUtils.isNotEmpty( outFileName ) ) { // The generated report document must be downloaded, add the well // // content-disposition header. responseBuilder.header( HttpHeaderUtils.CONTENT_DISPOSITION_HEADER, HttpHeaderUtils.getAttachmentFileName( outFileName ) ); } return responseBuilder.build(); } private MediaType getMediaType( IXDocReport report, Options options ) throws XDocConverterException { if ( options == null ) { return MediaType.valueOf( report.getMimeMapping().getMimeType() ); } IConverter converter = report.getConverter( options ); return MediaType.valueOf( converter.getMimeMapping().getMimeType() ); } private Options getOptions( final String outFormat, final String via ) { if ( StringUtils.isEmpty( outFormat ) ) { return null; } Options options = Options.getTo( outFormat ); if ( StringUtils.isNotEmpty( via ) ) { options.via( via ); } return options; } protected Map toMap( String data, String dataType ) throws Exception { // TODO : use well serializer of the data according dataType (json, xml, etc) return new JSONObject( data ); } }