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

fr.opensagres.xdocreport.document.docx.preprocessor.sax.DocxBufferedDocument Maven / Gradle / Ivy

/**
 * 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.docx.preprocessor.sax;

import static fr.opensagres.xdocreport.document.docx.DocxConstants.FLDCHARTYPE_ATTR;
import static fr.opensagres.xdocreport.document.docx.DocxConstants.ID_ATTR;
import static fr.opensagres.xdocreport.document.docx.DocxConstants.INSTR_ATTR;
import static fr.opensagres.xdocreport.document.docx.DocxConstants.NAME_ATTR;
import static fr.opensagres.xdocreport.document.docx.DocxConstants.R_NS;
import static fr.opensagres.xdocreport.document.docx.DocxConstants.W_NS;
import static fr.opensagres.xdocreport.document.docx.DocxUtils.isBookmarkEnd;
import static fr.opensagres.xdocreport.document.docx.DocxUtils.isBookmarkStart;
import static fr.opensagres.xdocreport.document.docx.DocxUtils.isDrawing;
import static fr.opensagres.xdocreport.document.docx.DocxUtils.isEndnoteReference;
import static fr.opensagres.xdocreport.document.docx.DocxUtils.isFldChar;
import static fr.opensagres.xdocreport.document.docx.DocxUtils.isFldSimple;
import static fr.opensagres.xdocreport.document.docx.DocxUtils.isFootnoteReference;
import static fr.opensagres.xdocreport.document.docx.DocxUtils.isHyperlink;
import static fr.opensagres.xdocreport.document.docx.DocxUtils.isP;
import static fr.opensagres.xdocreport.document.docx.DocxUtils.isR;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

import fr.opensagres.xdocreport.core.utils.StringUtils;
import fr.opensagres.xdocreport.core.utils.XMLUtils;
import fr.opensagres.xdocreport.document.docx.DocxUtils;
import fr.opensagres.xdocreport.document.docx.preprocessor.sax.hyperlinks.HyperlinkBufferedRegion;
import fr.opensagres.xdocreport.document.docx.preprocessor.sax.notes.endnotes.EndnoteReferenceBufferedRegion;
import fr.opensagres.xdocreport.document.docx.preprocessor.sax.notes.footnotes.FootnoteReferenceBufferedRegion;
import fr.opensagres.xdocreport.document.images.AbstractImageRegistry;
import fr.opensagres.xdocreport.document.images.IImageRegistry;
import fr.opensagres.xdocreport.document.images.ImageProviderInfo;
import fr.opensagres.xdocreport.document.preprocessor.sax.BufferedElement;
import fr.opensagres.xdocreport.document.preprocessor.sax.TransformedBufferedDocument;
import fr.opensagres.xdocreport.template.TemplateContextHelper;
import fr.opensagres.xdocreport.template.formatter.FieldMetadata;
import fr.opensagres.xdocreport.template.formatter.FieldsMetadata;
import fr.opensagres.xdocreport.template.formatter.IDocumentFormatter;

public class DocxBufferedDocument
    extends TransformedBufferedDocument
{

    protected final DocXBufferedDocumentContentHandler handler;

    private PBufferedRegion currentPRegion;

    private FldSimpleBufferedRegion currentFldSimpleRegion;

    private RBufferedRegion currentRRegion;

    private BookmarkBufferedRegion currentBookmark;

    private HyperlinkBufferedRegion currentHyperlink;

    public DocxBufferedDocument( DocXBufferedDocumentContentHandler handler )
    {
        this.handler = handler;
    }

    protected BufferedElement createElement( BufferedElement parent, String uri, String localName, String name,
                                             Attributes attributes )
        throws SAXException
    {

        if ( isFldChar( uri, localName, name ) && currentRRegion != null )
        {
            // w:fdlChar element
            String fldCharType = attributes.getValue( W_NS, FLDCHARTYPE_ATTR );
            currentRRegion.setFldCharType( fldCharType );
            return super.createElement( parent, uri, localName, name, attributes );
        }

        if ( isP( uri, localName, name ) )
        {
            // w:p element
            currentPRegion = new PBufferedRegion( this, getCurrentElement(), uri, localName, name, attributes );
            return currentPRegion;
        }

        if ( isR( uri, localName, name ) && currentFldSimpleRegion == null )
        {
            // w:r element
            currentRRegion = new RBufferedRegion( handler, parent, uri, localName, name, attributes );

            HyperlinkBufferedRegion hyperlink = getCurrentHyperlink();
            if ( hyperlink != null )
            {
                hyperlink.addRegion( currentRRegion );
            }
            else
            {
                PBufferedRegion pRegion = getCurrentPRegion();
                if ( pRegion != null )
                {
                    pRegion.addRegion( currentRRegion );
                }
            }
            return currentRRegion;
        }

        if ( isFldSimple( uri, localName, name ) )
        {
            // w:fldSimple element
            // start of fldSimple mergefield, add the fieldName of mergefield
            // and ignore element
            String instrText = attributes.getValue( W_NS, INSTR_ATTR );
            FieldMetadata fieldAsTextStyling = handler.getFieldAsTextStyling( instrText );
            instrText = handler.processRowIfNeeded( attributes.getValue( W_NS, INSTR_ATTR ) );
            currentFldSimpleRegion = new FldSimpleBufferedRegion( handler, parent, uri, localName, name, attributes );
            currentFldSimpleRegion.setInstrText( instrText, fieldAsTextStyling );
            // boolean addElement = false;
            if ( currentFldSimpleRegion.getFieldName() == null )
            {
                // super.doStartElement(uri, localName, name, attributes);
                // addElement = true;
            }
            // currentRegion = currentFldSimpleRegion;
            return currentFldSimpleRegion;
        }

        if ( isBookmarkStart( uri, localName, name ) )
        {
            // 
            String bookmarkName = attributes.getValue( W_NS, NAME_ATTR );
            FieldsMetadata fieldsMetadata = handler.getFieldsMetadata();
            if ( fieldsMetadata != null )
            {
                String imageFieldName = fieldsMetadata.getImageFieldName( bookmarkName );
                if ( imageFieldName != null )
                {
                    currentBookmark =
                        new BookmarkBufferedRegion( bookmarkName, imageFieldName, parent, uri, localName,
                                                    imageFieldName, attributes );

                    IDocumentFormatter formatter = handler.getFormatter();
                    if ( formatter != null )
                    {
                        // insert before start bookmark image script (Velocity,
                        // Freemarker)
                        // #set($___imageInfo=${___imageRegistry.registerImage($logo,'logo',$___context)})
                        // #if($___imageInfo.notRemoveImageTemplate)
                        String set =
                            formatter.getSetDirective( IImageRegistry.IMAGE_INFO,
                                                       formatter.getFunctionDirective( false,
                                                                                       TemplateContextHelper.IMAGE_REGISTRY_KEY,
                                                                                       IImageRegistry.REGISTER_IMAGE_METHOD,
                                                                                       handler.processRowIfNeeded( currentBookmark.getImageFieldName(),
                                                                                                                   true ),
                                                                                       "'"
                                                                                           + currentBookmark.getBookmarkName()
                                                                                           + "'",
                                                                                       TemplateContextHelper.CONTEXT_KEY ),
                                                       false );
                        String imageInfoIf =
                            formatter.getStartIfDirective( formatter.formatAsSimpleField( false,
                                                                                          AbstractImageRegistry.IMAGE_INFO,
                                                                                          ImageProviderInfo.NOT_REMOVE_IMAGE_TEMPLATE_METHOD ),
                                                           false );
                        StringBuilder before = new StringBuilder();
                        before.append( set );
                        before.append( imageInfoIf );
                        currentBookmark.setContentBeforeStartTagElement( before.toString() );

                    }
                    return currentBookmark;
                }
            }
            return super.createElement( parent, uri, localName, name, attributes );
        }

        if ( isBookmarkEnd( uri, localName, name ) )
        {
            BufferedElement bookmarkEnd = super.createElement( parent, uri, localName, name, attributes );
            if ( currentBookmark != null )
            {
                IDocumentFormatter formatter = handler.getFormatter();
                if ( formatter != null )
                {
                    // #end (of #if($___imageInfo.notRemoveImageTemplate))
                    bookmarkEnd.setContentAfterEndTagElement( formatter.getEndIfDirective( AbstractImageRegistry.IMAGE_INFO ) );
                }
            }
            currentBookmark = null;
            return bookmarkEnd;
        }

        if ( isDrawing( uri, localName, name ) )
        {

            BufferedElement element = super.createElement( parent, uri, localName, name, attributes );
            if ( StringUtils.isNotEmpty( handler.getStartNoParse() ) )
            {
                element.setContentBeforeStartTagElement( handler.getEndNoParse() );
                element.setContentAfterEndTagElement( handler.getStartNoParse() );
            }
            return element;
        }

        if ( isHyperlink( uri, localName, name ) )
        {
            // 
            int idIndex = attributes.getIndex( R_NS, ID_ATTR );
            if ( idIndex != -1 )
            {
                String attrName = attributes.getQName( idIndex );
                AttributesImpl attributesImpl = XMLUtils.toAttributesImpl( attributes );
                attributesImpl.removeAttribute( idIndex );
                String id = attributes.getValue( idIndex );
                currentHyperlink = new HyperlinkBufferedRegion( handler, parent, uri, localName, name, attributesImpl );
                currentHyperlink.setId( attrName, id );
                return currentHyperlink;
            }
            return super.createElement( parent, uri, localName, name, attributes );

        }
        if ( isFootnoteReference( uri, localName, name ) )
        {

            // 
            int idIndex = attributes.getIndex( W_NS, ID_ATTR );
            if ( idIndex != -1 )
            {
                String attrName = attributes.getQName( idIndex );
                AttributesImpl attributesImpl = XMLUtils.toAttributesImpl( attributes );
                attributesImpl.removeAttribute( idIndex );
                String id = attributes.getValue( idIndex );
                FootnoteReferenceBufferedRegion noteReference =
                    new FootnoteReferenceBufferedRegion( handler, parent, uri, localName, name, attributesImpl );
                noteReference.setId( attrName, id );
                if ( currentRRegion != null )
                {
                    currentRRegion.setContainsNote( true );
                }
                return noteReference;
            }
            return super.createElement( parent, uri, localName, name, attributes );

        }
        if ( isEndnoteReference( uri, localName, name ) )
        {

            // 
            int idIndex = attributes.getIndex( W_NS, ID_ATTR );
            if ( idIndex != -1 )
            {
                String attrName = attributes.getQName( idIndex );
                AttributesImpl attributesImpl = XMLUtils.toAttributesImpl( attributes );
                attributesImpl.removeAttribute( idIndex );
                String id = attributes.getValue( idIndex );
                EndnoteReferenceBufferedRegion noteReference =
                    new EndnoteReferenceBufferedRegion( handler, parent, uri, localName, name, attributesImpl );
                noteReference.setId( attrName, id );
                if ( currentRRegion != null )
                {
                    currentRRegion.setContainsNote( true );
                }
                return noteReference;
            }
            return super.createElement( parent, uri, localName, name, attributes );
        }
        return super.createElement( parent, uri, localName, name, attributes );
    }

    public BookmarkBufferedRegion getCurrentBookmark()
    {
        return currentBookmark;
    }

    public FldSimpleBufferedRegion getCurrentFldSimpleRegion()
    {
        return currentFldSimpleRegion;
    }

    public HyperlinkBufferedRegion getCurrentHyperlink()
    {
        return currentHyperlink;
    }

    public PBufferedRegion getCurrentPRegion()
    {
        return currentPRegion;
    }

    public RBufferedRegion getCurrentRRegion()
    {
        return currentRRegion;
    }

    @Override
    public void onEndEndElement( String uri, String localName, String name )
    {
        if ( isP( uri, localName, name ) && currentPRegion != null )
        {
            super.onEndEndElement( uri, localName, name );
            currentPRegion.process();
            // currentRegion = currentPRegion.getParent();
            currentPRegion = null;
            return;
        }

        if ( isR( uri, localName, name ) && currentRRegion != null && currentFldSimpleRegion == null )
        {
            super.onEndEndElement( uri, localName, name );
            // boolean hasScript = processScriptBeforeAfter( currentRRegion );
            // if ( hasScript )
            // {
            // currentRRegion.reset();
            // }
            currentRRegion = null;
            return;
        }

        if ( isFldSimple( uri, localName, name ) && currentFldSimpleRegion != null )
        {
            // it's end of fldSimple and it's Mergefield; ignore the element
            boolean hasScript = processScriptBeforeAfter( currentFldSimpleRegion );
            if ( hasScript )
            {
                currentFldSimpleRegion.reset();
            }
            super.onEndEndElement( uri, localName, name );
            // currentRegion = currentFldSimpleRegion.getParent();
            currentFldSimpleRegion = null;
            return;
        }

        if ( isHyperlink( uri, localName, name ) )
        {
            // 
            HyperlinkBufferedRegion hyperlink = (HyperlinkBufferedRegion) currentHyperlink;
            super.onEndEndElement( uri, localName, name );
            if ( hyperlink != null )
            {
                hyperlink.process();
            }
            currentHyperlink = null;
            return;
        }

        super.onEndEndElement( uri, localName, name );
    }

    public boolean processScriptBeforeAfter( MergefieldBufferedRegion mergefield )
    {
        String fieldName = mergefield.getFieldName();
        if ( fieldName == null )
        {
            return false;
        }
        else
        {
            String endNoParse = handler.getEndNoParse();
            if ( endNoParse != null )
            {
                // ex: ]]#@before-row#foreach($d in $developers)#[[
                if ( fieldName.startsWith( endNoParse ) )
                {
                    // ex: @before-row#foreach($d in $developers)#[[
                    fieldName = fieldName.substring( endNoParse.length(), fieldName.length() );
                }
            }
            String startNoParse = handler.getStartNoParse();
            if ( startNoParse != null )
            {
                if ( fieldName.endsWith( startNoParse ) )
                {
                    // ex: @before-row#foreach($d in $developers)
                    fieldName = fieldName.substring( 0, fieldName.length() - startNoParse.length() );
                }
            }

            boolean hasScript = handler.processScriptBefore( fieldName );
            if ( hasScript )
            {
                return hasScript;
            }
            else
            {
                return handler.processScriptAfter( fieldName );
            }
        }
    }

    @Override
    protected boolean isTable( String uri, String localName, String name )
    {
        return DocxUtils.isTable( uri, localName, name );
    }

    @Override
    protected boolean isTableRow( String uri, String localName, String name )
    {
        return DocxUtils.isTableRow( uri, localName, name );
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy