All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fr.opensagres.xdocreport.document.AbstractXDocReport Maven / Gradle / Ivy

There is a newer version: 2.0.6
Show newest version
/**
 * Copyright (C) 2011-2015 The XDocReport Team 
 *
 * 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;

import static fr.opensagres.xdocreport.core.utils.StringUtils.EMPTY_STRING_ARRAY;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.logging.Level;
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.IEntryOutputStreamProvider;
import fr.opensagres.xdocreport.core.io.IEntryReaderProvider;
import fr.opensagres.xdocreport.core.io.IEntryWriterProvider;
import fr.opensagres.xdocreport.core.io.XDocArchive;
import fr.opensagres.xdocreport.core.logging.LogUtils;
import fr.opensagres.xdocreport.core.utils.StringUtils;
import fr.opensagres.xdocreport.document.dump.DumperOptions;
import fr.opensagres.xdocreport.document.dump.DumperRegistry;
import fr.opensagres.xdocreport.document.dump.IDumper;
import fr.opensagres.xdocreport.document.images.DefaultImageHandler;
import fr.opensagres.xdocreport.document.images.IImageRegistry;
import fr.opensagres.xdocreport.document.preprocessor.IXDocPreprocessor;
import fr.opensagres.xdocreport.document.preprocessor.sax.BufferedElement;
import fr.opensagres.xdocreport.document.registry.TextStylingRegistry;
import fr.opensagres.xdocreport.document.registry.XDocReportRegistry;
import fr.opensagres.xdocreport.template.FieldsExtractor;
import fr.opensagres.xdocreport.template.IContext;
import fr.opensagres.xdocreport.template.ITemplateEngine;
import fr.opensagres.xdocreport.template.TemplateContextHelper;
import fr.opensagres.xdocreport.template.formatter.FieldsMetadata;
import fr.opensagres.xdocreport.template.formatter.IDocumentFormatter;

/**
 * Abstract class for {@link IXDocReport} to implement to manage docx, odt...
 */
public abstract class AbstractXDocReport
    implements IXDocReport
{

    private static final Logger LOGGER = LogUtils.getLogger( AbstractXDocReport.class.getName() );

    private static final long serialVersionUID = -6632379345569386476L;

    /**
     * Map of {@link IXDocPreprocessor} to execute for an entry of the zipped XML Document (odt, docx...).
     */
    private Map> preprocessors =
        new LinkedHashMap>();

/**
     * id of the {@link IXDocReport}. This id is used to cache an instance of {@link IXDocReport} with
     * {@link XDocReportRegistry#loadReport(InputStream) and get instance from cache with
     * 
     * @link XDocReportRegistry#getReport(String)}.
     */
    private String id;

    /**
     * Template engine to use to merge Java model with the XML files of the from entries of the zipped XML Document
     * (odt, docx...) defined by {@link AbstractXDocReport#getXMLEntries()}.
     */
    private ITemplateEngine templateEngine;

    /**
     * Zipped XML Document (odt, docx) which is the original XML Document..
     */
    private XDocArchive originalArchive = null;

    /**
     * Zipped XML Document (odt, docx) which is the original XML Document preprocessed.
     */
    private XDocArchive preprocessedArchive = null;

    /**
     * XML entries which define XML document to merge with Java model with template engine.
     */
    private String[] xmlEntries;

    /**
     * Fields metadata used to manage lazy loop for table row.
     */
    private FieldsMetadata fieldsMetadata;

    /**
     * True if preprocessing was done et false otherwise.
     */
    private boolean preprocessed;

    /**
     * Cache or not for original document archive.
     */
    private boolean cacheOriginalDocument = false;

    /**
     * Custom data.
     */
    private Map data = null;

    private long lastModified;

    /**
     * Map of {@link BufferedElement} used for text styling to
     */
    private Map elementsCache;

    protected AbstractXDocReport()
    {
        // Register preprocessor.
        registerPreprocessors();
        this.preprocessed = false;
    }

    /*
     * (non-Javadoc)
     * @see fr.opensagres.xdocreport.core.document.IXDocReport#getId()
     */
    public String getId()
    {
        return id;
    }

    /*
     * (non-Javadoc)
     * @see fr.opensagres.xdocreport.core.document.IXDocReport#setId(java.lang.String )
     */
    public void setId( String id )
    {
        this.id = id;
    }

    /*
     * (non-Javadoc)
     * @see fr.opensagres.xdocreport.core.document.IXDocReport#load(java.io.InputStream )
     */
    public void load( InputStream sourceStream )
        throws IOException, XDocReportException
    {
        if ( preprocessed )
        {
            preprocessed = false;
        }
        // Load zipped XML Document (odt, docx...)
        setDocumentArchive( XDocArchive.readZip( sourceStream ) );
    }

    /*
     * (non-Javadoc)
     * @see fr.opensagres.xdocreport.core.document.IXDocReport#setDocumentArchive (fr.opensagres
     * .xdocreport.core.document.XDocArchive)
     */
    public void setDocumentArchive( XDocArchive documentArchive )
        throws IOException, XDocReportException
    {
        this.lastModified = System.currentTimeMillis();
        this.preprocessed = false;
        if ( cacheOriginalDocument )
        {
            this.originalArchive = documentArchive;
            this.preprocessedArchive = documentArchive.createCopy();
        }
        else
        {
            this.originalArchive = null;
            this.preprocessedArchive = documentArchive;
        }
        // Execute preprocessor and modify the original zipped XML Document
        doPreprocessorIfNeeded();
    }

    /*
     * (non-Javadoc)
     * @see fr.opensagres.xdocreport.document.IXDocReport#getOriginalDocumentArchive ()
     */
    public XDocArchive getOriginalDocumentArchive()
    {
        return originalArchive;
    }

    /*
     * (non-Javadoc)
     * @see fr.opensagres.xdocreport.core.document.IXDocReport#getDocumentArchive()
     */
    public XDocArchive getPreprocessedDocumentArchive()
    {
        return preprocessedArchive;
    }

    /**
     * Returns template engine (velocity, freemarker..) to use to merge Java model with the XML files of the from
     * entries of the zipped XML Document (odt, docx...) defined by {@link AbstractXDocReport#getXMLEntries()}.
     * 
     * @return
     */
    public ITemplateEngine getTemplateEngine()
    {
        return templateEngine;
    }

    /**
     * Register template engine (velocity, freemarker..) to use to merge Java model with the XML files of the from
     * entries of the zipped XML Document (odt, docx...) defined by {@link AbstractXDocReport#getXMLEntries()}.
     */
    public void setTemplateEngine( ITemplateEngine templateEngine )
    {
        this.templateEngine = templateEngine;
    }

    /**
     * Register a processor for the entry name.
     * 
     * @param entryName
     * @param preprocessor
     */
    public void addPreprocessor( String entryName, IXDocPreprocessor preprocessor )
    {
        Collection entryPreprocessors = preprocessors.get( entryName );
        if ( entryPreprocessors == null )
        {
            entryPreprocessors = new ArrayList();
            preprocessors.put( entryName, entryPreprocessors );
        }
        entryPreprocessors.add( preprocessor );
    }

    /**
     * Remove processor for the entry name.
     * 
     * @param entryName
     */
    public void removePreprocessor( String entryName )
    {
        preprocessors.remove( entryName );
    }

    /**
     * Clear processor.
     */
    public void removeAllPreprocessors()
    {
        preprocessors.clear();
    }

    /**
     * Set fields metadata used to manage lazy loop for table row.
     */
    public void setFieldsMetadata( FieldsMetadata fieldsMetadata )
    {
        this.fieldsMetadata = fieldsMetadata;
        ITemplateEngine templateEngine = this.getTemplateEngine();
        if ( templateEngine != null && fieldsMetadata != null )
        {
            this.fieldsMetadata.setTemplateEngineKind( templateEngine.getKind() );
        }
    }

    /**
     * Returns fields metadata used to manage lazy loop for table row.
     * 
     * @return
     */
    public FieldsMetadata getFieldsMetadata()
    {
        return fieldsMetadata;
    }

    /**
     * Create fields metadata.
     * 
     * @return
     */
    public FieldsMetadata createFieldsMetadata()
    {
        FieldsMetadata fieldsMetadata = new FieldsMetadata();
        setFieldsMetadata( fieldsMetadata );
        return fieldsMetadata;
    }

    public void preprocess()
        throws XDocReportException, IOException
    {
        doPreprocessorIfNeeded();
    }

    /**
     * Execute processors registered to modify entry names of the original document archive. Processors use
     * {@link FieldsMetadata} and {@link IDocumentFormatter} (coming from {@link ITemplateEngine#getDocumentFormatter()}
     * to manage lazy loop for table row.
     * 
     * @throws XDocReportException
     * @throws IOException
     */
    private void doPreprocessorIfNeeded()
        throws XDocReportException, IOException
    {
        if ( preprocessed )
        {
            // preprocessing is already done
            return;
        }
        if ( templateEngine == null )
        {
            // template engine is not set, so preprocessing cannot be done
            return;
        }
        Map sharedContext = new HashMap();
        if ( fieldsMetadata != null && fieldsMetadata.getFieldsAsTextStyling().size() > 0 )
        {
            elementsCache = new HashMap();
            sharedContext.put( DocumentContextHelper.ELEMENTS_KEY, elementsCache );
        }
        onBeforePreprocessing( sharedContext, preprocessedArchive );
        try
        {
            IDocumentFormatter formatter = internalGetTemplateEngine().getDocumentFormatter();
            
            // Loop for each preprocessor registered
            for ( Entry> entry : preprocessors.entrySet() )
            {
                String preprocessorName = entry.getKey();
                Collection entryPreprocessors = entry.getValue();
                if ( preprocessedArchive.hasEntry( preprocessorName ) )
                {
                    for ( IXDocPreprocessor preprocessor : entryPreprocessors )
                    {
                        // XML Document contains a XML file which must be
                        // preprocessed
                        preprocessor.preprocess( preprocessorName, preprocessedArchive, fieldsMetadata, formatter,
                                                 sharedContext );
                    }
                }
                else
                {
                    // Test if it's wilcard?
                    Set entriesNameFromWilcard = preprocessedArchive.getEntryNames( preprocessorName );
                    if ( entriesNameFromWilcard.size() > 0 )
                    {
                        for ( String entryNameFromWilcard : entriesNameFromWilcard )
                        {
                            for ( IXDocPreprocessor preprocessor : entryPreprocessors )
                            {
                                preprocessor.preprocess( entryNameFromWilcard, preprocessedArchive, fieldsMetadata,

                                formatter, sharedContext );
                            }
                        }
                    }
                    else
                    {
                        // entry not found, create it?
                        entryPreprocessors = entry.getValue();
                        for ( IXDocPreprocessor preprocessor : entryPreprocessors )
                        {
                            if ( preprocessor.create( preprocessorName, preprocessedArchive, fieldsMetadata, formatter,
                                                      sharedContext ) )
                            {
                                break;
                            }
                        }
                    }
                }
            }
        }
        finally
        {
            onAfterPreprocessing( sharedContext, preprocessedArchive );
            // Preprocessing is done
            preprocessed = true;
            sharedContext.clear();
            sharedContext = null;
        }
    }

    /**
     * On before preprocessing.
     * 
     * @param sharedContext
     * @param preprocessedArchive
     */
    protected void onBeforePreprocessing( Map sharedContext, XDocArchive preprocessedArchive )
        throws XDocReportException
    {
        // Do nothing
    }

    /**
     * On after preprocessing.
     * 
     * @param sharedContext
     * @param preprocessedArchive
     */
    protected void onAfterPreprocessing( Map sharedContext, XDocArchive preprocessedArchive )
        throws XDocReportException
    {
        // Do nothing
    }

    /**
     * Returns XML entries which define XML document to merge with Java model with template engine.
     * 
     * @return
     */
    public String[] getXMLEntries()
    {
        return xmlEntries;
    }

    /**
     * Set XML entries which define XML document to merge with Java model with template engine.
     * 
     * @param xmlEntries
     */
    public void setXMLEntries( String[] xmlEntries )
    {
        this.xmlEntries = xmlEntries;
    }

    /**
     * Create an empty context to register Java model.
     */
    public IContext createContext()
        throws XDocReportException
    {
        return internalGetTemplateEngine().createContext();
    }

    //@Override
    public IContext createContext( Map contextMap )
        throws XDocReportException
    {
        return internalGetTemplateEngine().createContext( contextMap );
    }

    public void process( Map contextMap, OutputStream out )
        throws XDocReportException, IOException
    {
        process( contextMap, null, out );
    }

    public void process( Map contextMap, String entryName, OutputStream out )
        throws XDocReportException, IOException
    {
        process( createContext( contextMap ), entryName, out );
    }

    public void process( IContext context, OutputStream out )
        throws XDocReportException, IOException
    {
        process( context, null, out );
    }

    /**
     * Generate report by merging Java model frm the context with XML Document (odt, docx...) preprocessed and store the
     * result into output stream.
     */
    public void process( IContext context, String entryName, OutputStream out )
        throws XDocReportException, IOException
    {
        // 1) Start process report generation
        long startTime = -1;
        if ( LOGGER.isLoggable( Level.FINE ) )
        {
            startTime = System.currentTimeMillis();
            LOGGER.fine( "Start process report " );
        }
        XDocArchive outputArchive = null;
        try
        {
            // 2) Force getting the template engine (freemarker, velocity...)
            internalGetTemplateEngine();

            // 3) Execute preprocessors to modify original XML Document (odt,
            // docx..) only if preprocessing was not done.
            doPreprocessorIfNeeded();

            // 4) Copy original archive to returns
            outputArchive = internalGetDocumentArchive().createCopy();

            // 5) Loop for each entries (XML file from the zipped XML
            // document (odt, docx...)
            // to merge it with Java model from the context with template
            // engine (freemarker, velocity).
            processTemplateEngine( context, outputArchive );

            doPostprocessIfNeeded( outputArchive );

            if ( StringUtils.isNotEmpty( entryName ) )
            {
                if ( !outputArchive.hasEntry( entryName ) )
                {
                    throw new XDocReportException( "No entry for the entry name=" + entryName );
                }
                // 6) save the merged XML entry into ouput stream
                XDocArchive.writeEntry( outputArchive, entryName, out );
            }
            else
            {
                // 6) save the merged XML document archive into ouput stream
                XDocArchive.writeZip( outputArchive, out );
            }
            // 7) End process report generation
            if ( LOGGER.isLoggable( Level.FINE ) )
            {

                LOGGER.fine( "End process report done with " + ( System.currentTimeMillis() - startTime ) + "(ms)." );
            }

        }
        catch ( Throwable e )
        {
            // Error while report generation
            if ( LOGGER.isLoggable( Level.FINE ) )
            {
                LOGGER.fine( "End process report with error done with " + ( System.currentTimeMillis() - startTime )
                    + "(ms)." );
                LOGGER.throwing( getClass().getName(), "process", e );
            }
            if ( e instanceof RuntimeException )
            {
                throw (RuntimeException) e;
            }
            if ( e instanceof IOException )
            {
                throw (IOException) e;
            }
            if ( e instanceof XDocReportException )
            {
                throw (XDocReportException) e;
            }
            throw new XDocReportException( e );
        }
        finally
        {
            if ( outputArchive != null )
            {
                outputArchive.dispose();
            }
            outputArchive = null;
        }
    }

    protected void doPostprocessIfNeeded( XDocArchive outputArchive )
    {
        // Empty default impl to avoid breaking compat
    }

    public void save( ProcessState processState, OutputStream out )
        throws IOException, XDocReportException
    {
        if ( processState == ProcessState.PREPROCESSED )
        {
            XDocArchive.writeZip( preprocessedArchive, out );
        }
        else
        {
            checkOriginalArchive();
            XDocArchive.writeZip( originalArchive, out );
        }

    }

    public void saveEntry( String entryName, ProcessState processState, OutputStream out )
        throws IOException, XDocReportException
    {
        if ( processState == ProcessState.PREPROCESSED )
        {
            XDocArchive.writeEntry( preprocessedArchive, entryName, out );
        }
        else
        {
            checkOriginalArchive();
            XDocArchive.writeEntry( originalArchive, entryName, out );
        }
    }

    private void checkOriginalArchive()
        throws XDocReportException
    {
        if ( originalArchive == null )
        {
            throw new XDocReportException(
                                           "Original document archive is not available. Call IXDocReport#setCacheOriginalDocument(true) before loading document." );
        }
    }

    public void extractFields( FieldsExtractor extractor )
        throws XDocReportException, IOException
    {
        extractFields( extractor, internalGetTemplateEngine() );
    }

    public void extractFields( FieldsExtractor extractor, ITemplateEngine templateEngine )
        throws XDocReportException, IOException
    {
        if ( templateEngine == null )
        {
            throw new XDocReportException( "ItemplateEngine cannot be null to extract fields." );
        }
        // force the preprocessing (see http://code.google.com/p/xdocreport/issues/detail?id=186)
        doPreprocessorIfNeeded();
        // Loop for each entries (XML file from the zipped XML
        // document (odt, docx...) to extract declared fields .
        String[] xmlEntries = internalGetXMLEntries();
        String entryName = null;
        for ( int i = 0; i < xmlEntries.length; i++ )
        {
            entryName = xmlEntries[i];
            if ( preprocessedArchive.hasEntry( entryName ) )
            {
                // extract fields
                templateEngine.extractFields( preprocessedArchive, entryName, extractor );
            }
            else
            {
                // Test if it's wilcard?
                Set entriesNameFromWilcard = preprocessedArchive.getEntryNames( entryName );
                for ( String entryNameFromWilcard : entriesNameFromWilcard )
                {
                    // extract fields
                    templateEngine.extractFields( preprocessedArchive, entryNameFromWilcard, extractor );
                }
            }
        }
    }

    public IConverter getConverter( Options options )
        throws XDocConverterException
    {
        return ConverterRegistry.getRegistry().findConverter( getKind(), options.getTo(), options.getVia() );
    }

    public void convert( Map contextMap, Options options, OutputStream out )
        throws XDocReportException, XDocConverterException, IOException
    {
        convert( createContext( contextMap ), options, out );
    }

    public void convert( final IContext context, Options options, OutputStream out )
        throws XDocReportException, XDocConverterException, IOException
    {
        // 1) Start process report generation
        long startTime = -1;
        if ( LOGGER.isLoggable( Level.FINE ) )
        {
            // Debug start process
            startTime = System.currentTimeMillis();
            LOGGER.fine( "Start convert report " );
        }
        XDocArchive outputArchive = null;
        try
        {
            IConverter converter = getConverter( options );
            // 2) Execute preprocessors to modify original XML Document
            // (odt,
            // docx..) only if preprocessing was not done.
            doPreprocessorIfNeeded();

            // 4) Copy original arhvive to returns
            outputArchive = internalGetDocumentArchive().createCopy();

            // 5) Loop for each entries (XML file from the zipped XML
            // document (odt, docx...)
            // to merge it with Java model from the context with template
            // engine (freemarker, velocity).
            processTemplateEngine( context, outputArchive );

            if ( converter.canSupportEntries() )
            {
                converter.convert( outputArchive, out, options );
            }
            else
            {
                // Converter cannot supper input entries provider,
                // rebuild a zip and set it as input stream.
                converter.convert( XDocArchive.getInputStream( outputArchive ), out, options );
            }

            // 7) End process report generation
            if ( LOGGER.isLoggable( Level.FINE ) )
            {
                LOGGER.fine( "End convert report done with " + ( System.currentTimeMillis() - startTime )
                    + "(ms)." );
            }
        }
        catch ( Throwable e )
        {
            // Error while report generation
            if ( LOGGER.isLoggable( Level.FINE ) )
            {
                LOGGER.fine( "End convert report with error done with " + ( System.currentTimeMillis() - startTime )
                    + "(ms)." );
                LOGGER.throwing( getClass().getName(), "convert", e );
            }
            if ( e instanceof RuntimeException )
            {
                throw (RuntimeException) e;
            }
            if ( e instanceof IOException )
            {
                throw (IOException) e;
            }
            if ( e instanceof XDocReportException )
            {
                throw (XDocReportException) e;
            }
            if ( e instanceof XDocConverterException )
            {
                throw (XDocConverterException) e;
            }
            throw new XDocConverterException( e );

        }
        finally
        {
            if ( outputArchive != null )
            {
                outputArchive.dispose();
            }
            outputArchive = null;
        }
    }

    private void processTemplateEngine( final IContext context, XDocArchive outputArchive )
        throws XDocReportException, IOException
    {
        String[] xmlEntries = internalGetXMLEntries();

        onBeforeProcessTemplateEngine( context, outputArchive );
        String entryName = null;
        for ( int i = 0; i < xmlEntries.length; i++ )
        {
            entryName = xmlEntries[i];
            if ( outputArchive.hasEntry( entryName ) )
            {
                // 5.1) merge current XML file with Java model from the
                // context with template engine (freemarker, velocity).
                templateEngine.process( getId(), entryName, outputArchive, outputArchive, context );
            }
            else
            {
                // Test if it's wilcard?
                Set entriesNameFromWilcard = internalGetDocumentArchive().getEntryNames( entryName );
                for ( String entryNameFromWilcard : entriesNameFromWilcard )
                {
                    // 5.2) merge current XML file with Java model from the
                    // context with template engine (freemarker, velocity).
                    templateEngine.process( getId(), entryNameFromWilcard, outputArchive, outputArchive, context );
                }
            }
        }
        onAfterProcessTemplateEngine( context, outputArchive );
    }

    /**
     * On before process template engine.
     * 
     * @param context
     * @param outputArchive
     * @throws XDocReportException
     */
    protected void onBeforeProcessTemplateEngine( final IContext context, XDocArchive outputArchive )
        throws XDocReportException
    {

        // 1) Register text styling registry
        DocumentContextHelper.putTextStylingRegistry( context, TextStylingRegistry.getRegistry() );

        // 2) Register ImageRegistry if needed
        IImageRegistry imageRegistry = null;
        if ( fieldsMetadata != null && fieldsMetadata.hasFieldsAsImage() )
        {
            imageRegistry = createImageRegistry( outputArchive, outputArchive, outputArchive );
            if ( imageRegistry != null )
            {
                DocumentContextHelper.putImageRegistry( context, imageRegistry );

                // Register default image handler if needed.
                if ( DocumentContextHelper.getImageHandler( context ) == null )
                {
                    DocumentContextHelper.putImageHandler( context, DefaultImageHandler.getInstance() );
                }
                imageRegistry.preProcess();
            }
        }

        // 3) Register context
        TemplateContextHelper.putContext( context );

        // 4) Add Bufferered element cache used for text styling
        if ( elementsCache != null )
        {
            DocumentContextHelper.putElementsCache( context, elementsCache );
        }

        // 5) Register template engine
        TemplateContextHelper.putTemplateEngine( context, templateEngine );
    }

    /**
     * On after process template engine.
     * 
     * @param context
     * @param outputArchive
     * @throws XDocReportException
     */
    protected void onAfterProcessTemplateEngine( IContext context, XDocArchive outputArchive )
        throws XDocReportException
    {
        IImageRegistry imageRegistry = DocumentContextHelper.getImageRegistry( context );
        if ( imageRegistry != null )
        {
            imageRegistry.postProcess();
        }
    }

    /**
     * Returns template engine (freemarker, velocity...) to use for the report generation and throws
     * {@link XDocReportException} if template engien is not defined.
     * 
     * @return
     * @throws XDocReportException
     */
    private ITemplateEngine internalGetTemplateEngine()
        throws XDocReportException
    {
        if ( templateEngine == null )
        {
            throw new XDocReportException(
                                           "Null template engine. Set template engine with IXDocReport#setTemplateEngine." );
        }
        return templateEngine;
    }

    /**
     * Retruns zipped XML document (odt, docx...) and throws {@link XDocReportException} if it is not defined.
     * 
     * @return
     * @throws XDocReportException
     */
    private XDocArchive internalGetDocumentArchive()
        throws XDocReportException
    {
        if ( preprocessedArchive == null )
        {
            throw new XDocReportException(
                                           "Null document archive (odt, docx). Load document archive (docx, odt....file) with IXDocReport#load." );
        }
        return preprocessedArchive;
    }

    /**
     * Returns XML entries which define XML document to merge with Java model with template engine. If custom XML
     * entries is not defined, {@link AbstractXDocReport#getDefaultXMLEntries()} are used.
     * 
     * @return
     */
    private String[] internalGetXMLEntries()
    {
        String[] entries = getXMLEntries();
        if ( entries != null )
        {
            return entries;
        }

        entries = getDefaultXMLEntries();
        if ( entries != null )
        {
            return entries;
        }
        return EMPTY_STRING_ARRAY;
    }

    /**
     * Returns default entries which define XML document to merge with Java model with template engine for odt, docx...
     * 
     * @return
     */
    protected abstract String[] getDefaultXMLEntries();

    /**
     * Returns XML entries which define XML document to merge with Java model with template engine. If custom XML
     * entries is not defined, {@link AbstractXDocReport#getDefaultXMLEntries()} are used.
     * 
     * @return
     */
    // private String[] internalGetXMLEntriesForConversion() {
    // String[] entries = getDefaultXMLEntriesForConversion();
    // if (entries != null) {
    // return entries;
    // }
    // return EMPTY_STRING_ARRAY;
    // }

    /*
     * (non-Javadoc)
     * @see fr.opensagres.xdocreport.core.document.IXDocReport#setData(java.lang. String, java.lang.Object)
     */
    public void setData( String key, Object value )
    {
        if ( data == null )
        {
            data = new HashMap();
        }
        data.put( key, value );
    }

    /*
     * (non-Javadoc)
     * @see fr.opensagres.xdocreport.core.document.IXDocReport#getData(java.lang. String)
     */
    @SuppressWarnings( "unchecked" )
    public  T getData( String key )
    {
        if ( data == null )
        {
            return null;
        }
        return (T) data.get( key );
    }

    /*
     * (non-Javadoc)
     * @see fr.opensagres.xdocreport.core.document.IXDocReport#clearData(java.lang .String)
     */
    public void clearData( String key )
    {
        if ( data == null )
        {
            return;
        }
        data.remove( key );
    }

    public void setCacheOriginalDocument( boolean cacheOriginalDocument )
    {
        this.cacheOriginalDocument = cacheOriginalDocument;
        if ( cacheOriginalDocument )
        {
            if ( originalArchive == null && preprocessedArchive != null )
            {
                originalArchive = preprocessedArchive.createCopy();
            }
        }
        else
        {
            originalArchive = null;
        }
    }

    /**
     * Returns default entries which define XML document to use for conversion.
     * 
     * @return
     */
    // protected abstract String[] getDefaultXMLEntriesForConversion();

    /**
     * Register preprocessors.
     */
    protected abstract void registerPreprocessors();

    /**
     * Returns true if report was processed and false otherwise.
     * 
     * @return
     */
    public boolean isPreprocessed()
    {
        return preprocessed;
    }

    /**
     * Returns the last modified time when the report is loaded.
     * 
     * @return
     */
    public long getLastModified()
    {
        return lastModified;
    }

    /**
     * Create an image registry.
     * 
     * @return
     */
    protected abstract IImageRegistry createImageRegistry( IEntryReaderProvider readerProvider,
                                                           IEntryWriterProvider writerProvider,
                                                           IEntryOutputStreamProvider outputStreamProvider );

    public void dump( IContext context, DumperOptions options, OutputStream out )
        throws IOException, XDocReportException
    {
        XDocArchive archive = getOriginalDocumentArchive();
        if ( archive == null )
        {
            throw new XDocReportException(
                                           "Dump cannot be done. IXDocReport#getOriginalDocumentArchive is null. Please call IXDocReport#setCacheOriginalDocument(true) after the loads of the report." );
        }
        dump( context, XDocArchive.getInputStream( archive ), options, out );
    }

    public void dump( IContext context, InputStream documentIn, DumperOptions options, OutputStream out )
        throws IOException, XDocReportException
    {
        if ( documentIn == null )
        {
            throw new XDocConverterException( "Dump cannot be done. Dump fo the report input stream cannot be null." );
        }
        getDumper( options ).dump( this, documentIn, context, options, out );

    }

    public IDumper getDumper( DumperOptions options )
        throws XDocReportException
    {
        return DumperRegistry.getRegistry().findDumper( options.getKind() );
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy