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

fr.opensagres.xdocreport.document.odt.textstyling.ODTDocumentHandler Maven / Gradle / Ivy

There is a newer version: 2.1.0
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.odt.textstyling;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

import fr.opensagres.xdocreport.core.utils.StringUtils;
import fr.opensagres.xdocreport.document.odt.template.ODTContextHelper;
import fr.opensagres.xdocreport.document.preprocessor.sax.BufferedElement;
import fr.opensagres.xdocreport.document.textstyling.AbstractDocumentHandler;
import fr.opensagres.xdocreport.document.textstyling.IDocumentHandler.TextLocation;
import fr.opensagres.xdocreport.document.textstyling.properties.HeaderProperties;
import fr.opensagres.xdocreport.document.textstyling.properties.ListItemProperties;
import fr.opensagres.xdocreport.document.textstyling.properties.ListProperties;
import fr.opensagres.xdocreport.document.textstyling.properties.ParagraphProperties;
import fr.opensagres.xdocreport.document.textstyling.properties.SpanProperties;
import fr.opensagres.xdocreport.document.textstyling.properties.TableCellProperties;
import fr.opensagres.xdocreport.document.textstyling.properties.TableProperties;
import fr.opensagres.xdocreport.document.textstyling.properties.TableRowProperties;
import fr.opensagres.xdocreport.template.IContext;

public class ODTDocumentHandler
    extends AbstractDocumentHandler
{
    private Stack paragraphsStack;

    private boolean insideHeader = false;

    private Stack spanStack;

    private int listDepth = 0;

    private List lastItemAlreadyClosed = new ArrayList();

    protected final IODTStylesGenerator styleGen;

    private boolean paragraphWasInserted;

    private boolean closeHeader;

    public ODTDocumentHandler( BufferedElement parent, IContext context, String entryName )
    {
        super( parent, context, entryName );
        styleGen = ODTContextHelper.getStylesGenerator( context );
        this.paragraphWasInserted = false;
        this.closeHeader = false;
    }

    public void startDocument()
    {
        this.paragraphsStack = new Stack();
        this.spanStack = new Stack();
    }

    public void endDocument()
        throws IOException
    {
        endParagraphIfNeeded();
    }

    private void endParagraphIfNeeded()
        throws IOException
    {
        if ( !paragraphsStack.isEmpty() )
        {
            paragraphsStack.size();
            for ( int i = 0; i < paragraphsStack.size(); i++ )
            {
                internalEndParagraph();
            }
            paragraphsStack.clear();
        }
    }

    public void startBold()
        throws IOException
    {
        internalStartSpan( styleGen.getBoldStyleName(), true );
    }

    public void endBold()
        throws IOException
    {
        internalEndSpan();
    }

    public void startItalics()
        throws IOException
    {
        internalStartSpan( styleGen.getItalicStyleName(), true );
    }

    public void endItalics()
        throws IOException
    {
        internalEndSpan();
    }

    public void startUnderline()
        throws IOException
    {
        internalStartSpan( styleGen.getUnderlineStyleName(), true );
    }

    public void endUnderline()
        throws IOException
    {
        internalEndSpan();
    }

    public void startStrike()
        throws IOException
    {
        internalStartSpan( styleGen.getStrikeStyleName(), true );
    }

    public void endStrike()
        throws IOException
    {
        internalEndSpan();
    }

    public void startSubscript()
        throws IOException
    {
        internalStartSpan( styleGen.getSubscriptStyleName(), true );
    }

    public void endSubscript()
        throws IOException
    {
        internalEndSpan();
    }

    public void startSuperscript()
        throws IOException
    {
        internalStartSpan( styleGen.getSuperscriptStyleName(), true );

    }

    public void endSuperscript()
        throws IOException
    {
        internalEndSpan();
    }

    @Override
    public void handleString( String content )
        throws IOException
    {
        // Re-escape ODT special characters, xml parsing removes them.
        content = StringUtils.xmlUnescape( content );
        content = StringUtils.xmlEscape( content );

        if ( insideHeader )
        {
            super.write( content );
        }
        else
        {
            startSpanIfNeeded();

            super.write( content );

            internalEndSpan();
        }
    }

    private void startSpanIfNeeded()
        throws IOException
    {
        boolean spanNeeded = true;

        for ( Integer depth : spanStack )
        {
            if ( depth != 0 )
            {
                spanNeeded = false;
                break;
            }
        }

        if ( spanNeeded )
        {
            internalStartSpan( styleGen.getTextStyleName( null ), true );
        }
        else
        {
            // Push 0 so nothing is closed
            spanStack.push( 0 );
        }
    }

    private void internalStartSpan( String styleName, boolean push )
        throws IOException
    {
        startParagraphIfNeeded();

        super.write( "" );

        if ( push )
        {
            spanStack.push( 1 );
        }
    }

    private void internalEndSpan()
        throws IOException
    {
        Integer depth;

        depth = spanStack.pop();

        while ( depth > 0 )
        {
            super.write( "" );
            depth--;
        }
    }

    private void startParagraphIfNeeded()
        throws IOException
    {

        if ( ( paragraphWasInserted && paragraphsStack.isEmpty() ) || closeHeader )
        {
            internalStartParagraph( false, (String) null );
        }
    }

    public void startParagraph( ParagraphProperties properties )
        throws IOException
    {
        if ( paragraphsStack.isEmpty() || !paragraphsStack.peek() )
        {
            super.setTextLocation( TextLocation.End );
            internalStartParagraph( false, properties );
        }
    }

    public void endParagraph()
        throws IOException
    {
        // paragraphs inside a list are skipped
        // if ( !paragraphsStack.peek() )
        // {
        internalEndParagraph();
        // }
    }

    private void internalStartParagraph( boolean containerIsList, ParagraphProperties properties )
        throws IOException
    {
        String styleName = null;
        if ( properties != null )
        {

            if ( properties.isPageBreakAfter() )
            {
                styleName = styleGen.getParaBreakAfterStyleName();
            }
            else if ( properties.isPageBreakBefore() )
            {
                styleName = styleGen.getParaBreakBeforeStyleName();
            }
            else
            {
                styleName = styleGen.getTextStyleName( properties );
            }
        }
        internalStartParagraph( containerIsList, styleName );

        // if ( properties != null )
        // {
        // // Remove "span" added by internalStartParagraph
        // // spanStack.pop();
        //
        // // Process properties
        // // startSpan( properties );
        // }
    }

    private void internalStartParagraph( boolean containerIsList, String styleName )
        throws IOException
    {
        closeHeader = false;
        if ( styleName == null )
        {
            super.write( "" );
        }
        else
        {
            super.write( "" );

        }
        paragraphWasInserted = true;
        paragraphsStack.push( containerIsList );

        // Put a 0 in the stack, endSpan is called when a paragraph is ended
        spanStack.push( 0 );
    }

    private void internalEndParagraph()
        throws IOException
    {
        if ( !paragraphsStack.isEmpty() )
        {
            // Close any spans from paragraph style
            internalEndSpan();

            super.write( "" );
            paragraphsStack.pop();
        }
    }

    public void startHeading( int level, HeaderProperties properties )
        throws IOException
    {
        endParagraphIfNeeded();
        super.setTextLocation( TextLocation.End );
        super.write( "" );
        insideHeader = true;
        closeHeader = false;
    }

    public void endHeading( int level )
        throws IOException
    {
        super.write( "" );
        insideHeader = false;
        closeHeader = true;
        // startParagraph();
    }

    @Override
    protected void doStartOrderedList( ListProperties properties )
        throws IOException
    {
        internalStartList( styleGen.getOLStyleName() );
    }

    @Override
    protected void doEndOrderedList()
        throws IOException
    {
        internalEndList();
    }

    @Override
    protected void doStartUnorderedList( ListProperties properties )
        throws IOException
    {
        internalStartList( styleGen.getULStyleName() );
    }

    @Override
    protected void doEndUnorderedList()
        throws IOException
    {
        internalEndList();
    }

    protected String itemStyle = "";

    protected void internalStartList( String style )
        throws IOException
    {
        closeHeader = false;
        super.setTextLocation( TextLocation.End );
        if ( listDepth == 0 )
        {
            endParagraphIfNeeded();
            lastItemAlreadyClosed.add( listDepth, false );
        }
        else
        {
            // close item for nested lists
            // super.write( "" );
            endParagraph();
            lastItemAlreadyClosed.add( listDepth, true );
        }
        if ( style != null )
        {
            super.write( "" );
            itemStyle = style;
        }
        else
        {
            super.write( "" );
        }
        listDepth++;
    }

    protected void internalEndList()
        throws IOException
    {
        super.write( "" );
        listDepth--;
        if ( listDepth == 0 )
        {
            // startParagraph();
        }
    }

    public void startListItem( ListItemProperties properties )
        throws IOException
    {
        if ( itemStyle != null )
        {
            super.write( "" );
            internalStartParagraph( true, itemStyle + styleGen.getListItemParagraphStyleNameSuffix() );
        }
        else
        {
            super.write( "" );
            internalStartParagraph( true, (String) null );
        }
    }

    public void endListItem()
        throws IOException
    {
        if ( lastItemAlreadyClosed.size() > listDepth && lastItemAlreadyClosed.get( listDepth ) )
        {
            lastItemAlreadyClosed.add( listDepth, false );
        }
        else
        {
            // endParagraph();
        }
        endParagraphIfNeeded();
        super.write( "" );
    }

    public void startSpan( SpanProperties properties )
        throws IOException
    {
        internalStartSpan( styleGen.getTextStyleName( properties ), true );
    }

    public void endSpan()
        throws IOException
    {
        internalEndSpan();
    }

    public void handleReference( String ref, String label )
        throws IOException
    {
        // FIXME: generate text:p only if needed.
        // startParagraph();
        super.write( "" );
        super.write( label );
        super.write( "" );
        // endParagraph();
    }

    public void handleImage( String ref, String label )
        throws IOException
    {
        // TODO: implements
    }

    public void handleLineBreak()
        throws IOException
    {
        super.write( "" );
    }

    protected void doStartTable( TableProperties properties )
        throws IOException
    {
        endParagraphIfNeeded();
        // odf table cannot be generated now, because here we don't know the table column count required to generate
        // table:table-column
        // that's here temp writer is used.
        pushTempWriter();
    }

    public void doEndTable( TableProperties properties )
        throws IOException
    {
        super.setTextLocation( TextLocation.End );
        StringBuilder startTable = new StringBuilder( "" );
        startTable.append( "" );
        startTable.append( "" );
        popTempWriter( startTable.toString() );
        super.write( "" );
    }

    protected void doStartTableRow( TableRowProperties properties )
        throws IOException
    {
        super.write( "" );
    }

    protected void doEndTableRow()
        throws IOException
    {
        super.write( "" );
    }

    protected void doStartTableCell( TableCellProperties properties )
        throws IOException
    {
        super.write( "" );
        internalStartParagraph( false, (String) null );
    }

    public void doEndTableCell()
        throws IOException
    {
        endParagraph();
        super.write( "" );
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy