/** * 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.document.internal; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; import java.util.logging.Logger; import fr.opensagres.xdocreport.converter.ConverterRegistry; 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.XDocArchive; import fr.opensagres.xdocreport.core.logging.LogUtils; import fr.opensagres.xdocreport.document.IXDocReport; import fr.opensagres.xdocreport.document.ProcessState; import fr.opensagres.xdocreport.document.domain.DataContext; import fr.opensagres.xdocreport.document.domain.ReportId; import fr.opensagres.xdocreport.document.registry.XDocReportRegistry; import fr.opensagres.xdocreport.template.IContext; import fr.opensagres.xdocreport.template.formatter.FieldsMetadata; public class XDocReportServiceImpl { private static final Logger LOGGER = LogUtils.getLogger( XDocReportServiceImpl.class ); public static final XDocReportServiceImpl INSTANCE = new XDocReportServiceImpl(); private boolean cacheOriginalDocument; public List<ReportId> listReports() { XDocReportRegistry registry = getXDocReportRegistry(); Collection<IXDocReport> reports = registry.getCachedReports(); List<ReportId> reportIDs = new ArrayList<ReportId>(); for ( IXDocReport docReport : reports ) { ReportId aReport = new ReportId( docReport.getId(), docReport.getTemplateEngine().getId(), new Date( docReport.getLastModified() ) ); reportIDs.add( aReport ); } return reportIDs; } /** * @param reportID the report ID which was registered in the registry. * @param dataContext "live" data to be merged in the template * @param options optional, used to customize the output in the case if convertion must be done. * @return the merged content eventually converted in another format (PDF or HTML) */ public byte[] process( String reportId, List<DataContext> dataContext, Options options ) throws XDocReportException { XDocReportRegistry registry = getXDocReportRegistry(); IXDocReport report = registry.getReport( reportId ); if ( report == null ) { throw new XDocReportException( "Cannot find report with the id=" + reportId ); } return process( report, dataContext, options ); } /** * @param document the template in a binary form * @param fieldsMetadatas fields metadata used to generate for instance lzy loop for ODT, Docx..row table. * @param templateEngineID the template engine ID.... * @param dataContext "live" data to be merged in the template * @param options optional, used to customize the output in the case if convertion must be done. * @return the merged content eventually converted in another format (PDF or HTML) */ public byte[] process( byte[] document, FieldsMetadata fieldsMetadata, String templateEngineId, List<DataContext> dataContext, Options options ) throws XDocReportException { // 1) Load report without cache it to the registry IXDocReport report = loadReport( getXDocReportRegistry(), "", document, fieldsMetadata, templateEngineId, false, isCacheOriginalDocument() ); // 2) Create context + Process report generation return process( report, dataContext, options ); } private byte[] process( IXDocReport report, List<DataContext> dataContext, Options options ) throws XDocReportException { try { // 2) Create context IContext context = createContext( report, dataContext ); // 3) Process report generation ByteArrayOutputStream out = new ByteArrayOutputStream(); if ( options == null ) { // Process report.process( context, out ); } else { // Converter report.convert( context, options, out ); } return out.toByteArray(); } catch ( Throwable e ) { throw new XDocReportException( e ); } } private IContext createContext( IXDocReport report, List<DataContext> dataContexts ) throws XDocReportException { IContext context; try { context = report.createContext(); for ( DataContext dataContext : dataContexts ) { context.put( dataContext.getKey(), dataContext.getValue() ); } return context; } catch ( XDocReportException e ) { throw new XDocReportException( e ); } } public void registerReport( String reportId, byte[] document, FieldsMetadata fieldsMetadata, String templateEngineId ) throws XDocReportException { // Load report and cache it to the registry loadReport( getXDocReportRegistry(), reportId, document, fieldsMetadata, templateEngineId, true, isCacheOriginalDocument() ); System.out.println( getXDocReportRegistry().getCachedReports() ); } private IXDocReport loadReport( XDocReportRegistry registry, String reportId, byte[] document, FieldsMetadata fieldsMetadata, String templateEngineId, boolean cacheReport, boolean cacheOriginalDocument ) throws XDocReportException { // 1) Get sourceStream InputStream sourceStream = getInputStream( document ); // 2) Load report IXDocReport report = null; try { report = registry.loadReport( sourceStream, reportId, templateEngineId, cacheReport ); } catch ( Throwable e ) { throw new XDocReportException( e ); } // 6) Set FieldsMetaData report.setFieldsMetadata( fieldsMetadata ); // 7) Set cache report.setCacheOriginalDocument( cacheOriginalDocument ); return report; } private ByteArrayInputStream getInputStream( byte[] document ) throws XDocReportException { if ( document == null ) { throw new XDocReportException( "Byte array of the document cannot be null." ); } return new ByteArrayInputStream( document ); } public byte[] convert( byte[] document, Options options ) throws XDocReportException { try { IConverter converter = ConverterRegistry.getRegistry().findConverter( options ); InputStream in = getInputStream( document ); ByteArrayOutputStream out = new ByteArrayOutputStream(); converter.convert( in, out, options ); return out.toByteArray(); } catch ( XDocConverterException e ) { throw new XDocReportException( e ); } } public void unregisterReport( String reportId ) { XDocReportRegistry registry = getXDocReportRegistry(); registry.unregisterReport( reportId ); } public byte[] download( String reportID, String processState ) throws XDocReportException { XDocArchive archive = null; ByteArrayOutputStream out = new ByteArrayOutputStream(); IXDocReport report = getXDocReportRegistry().getReport( reportID ); if(report==null) throw new XDocReportException( "report not found " +reportID); if ( ProcessState.ORIGINAL.name().equalsIgnoreCase( processState ) ) { archive = report.getOriginalDocumentArchive().createCopy(); } else if ( ProcessState.PREPROCESSED.name().equalsIgnoreCase( processState ) ) { archive = report.getPreprocessedDocumentArchive().createCopy(); } else { throw new XDocReportException( "processState should be " + ProcessState.ORIGINAL + " or "+ ProcessState.PREPROCESSED ); } try { XDocArchive.writeZip( archive, out ); } catch ( IOException e ) { LOGGER.severe( e.getMessage() ); throw new XDocReportException(e.getMessage()); } return out.toByteArray(); } protected XDocReportRegistry getXDocReportRegistry() { return XDocReportRegistry.getRegistry(); } public boolean isCacheOriginalDocument() { return cacheOriginalDocument; } public void setCacheOriginalDocument( boolean cacheOriginalDocument ) { this.cacheOriginalDocument = cacheOriginalDocument; } }