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

fr.opensagres.poi.xwpf.converter.core.styles.AbstractValueProvider 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.poi.xwpf.converter.core.styles;

import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDocDefaults;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyle;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblStylePr;

import fr.opensagres.poi.xwpf.converter.core.utils.StringUtils;

public abstract class AbstractValueProvider
    implements IValueProvider
{

    public Value getValue( XWPFElement element, XWPFStylesDocument stylesDocument )
    {
        // long start = System.currentTimeMillis();
        Value value = internalGetValue( element, stylesDocument );
        // System.err.println( "value=" + value + " with " + ( System.currentTimeMillis() - start ) + "ms" );
        return value;

    };

    public Value internalGetValue( XWPFElement element, XWPFStylesDocument stylesDocument )
    {
        // 1) Inline style : search value retrieved from the XWPF element (XWPFParagraph, XWPFTable etc)
        Value value = getValueFromElement( element, stylesDocument );
        if ( value != null )
        {
            // Value declared in the inline style, return it.
            return value;
        }
        if ( stylesDocument == null )
        {
            return null;
        }
        // 2) External styles: search value declared in a style.
        return getValueFromStyles( element, stylesDocument );
    }

    public Value getValueFromStyles( XWPFElement element, XWPFStylesDocument stylesDocument )
    {

        // 1) At first get from cache or compute the default value
        String key = getKey( element, stylesDocument, null, null );
        // search from the cache
        Object defaultValue = stylesDocument.getValue( key );
        if ( defaultValue == null )
        {
            // compute the default value and cache it
            defaultValue = getDefaultValue( element, stylesDocument );
            if ( defaultValue == null )
            {
                defaultValue = XWPFStylesDocument.EMPTY_VALUE;
            }
            updateValueCache( stylesDocument, key, defaultValue );
        }

        // 2) Search value from the linked style
        Object result = getValueFromStyleIds( element, stylesDocument, defaultValue );
        if ( result != null )
        {
            return getValueOrNull( result );
        }
        // 3) Search if the XWPF element (paragraph or run) belongs to table which is styled.
        XWPFTableCell cell = getParentTableCell( element );
        if ( cell != null )
        {
            XWPFTable table = cell.getTableRow().getTable();
            String tableStyleID = table.getStyleID();
            if ( StringUtils.isNotEmpty( tableStyleID ) )
            {
                // the current XWPFElement paragraph, run, etc belongs to a cell of a table which is styled.

                // 1) search styles from , , etc
                TableCellInfo cellInfo = stylesDocument.getTableCellInfo( cell );
                result = getValueFromTableStyleId( element, stylesDocument, tableStyleID, cellInfo );
                if ( result != null )
                {
                    return getValueOrNull( result );
                }
                // no styles founded, search from the 
                result = getValueFromStyleId( element, stylesDocument, tableStyleID, defaultValue );
                if ( result != null )
                {
                    return getValueOrNull( result );
                }
            }
        }
        updateValueCache( stylesDocument, key, defaultValue );
        return getValueOrNull( defaultValue );
    }

    private Object getValueFromTableStyleId( XWPFElement element, XWPFStylesDocument stylesDocument,
                                             String tableStyleID, TableCellInfo cellInfo )
    {
        if ( StringUtils.isEmpty( tableStyleID ) )
        {
            return null;
        }

        Object value = getValueFromTableStyleIdRow( element, stylesDocument, tableStyleID, cellInfo );
        if ( value != null )
        {
            return value;
        }
        if ( cellInfo.canApplyFirstCol() )
        {
            Object result = getValueFromTableStyleIdFirstCol( element, stylesDocument, tableStyleID );
            if ( result != null )
            {
                return result;
            }
        }
        else if ( cellInfo.canApplyLastCol() )
        {
            Object result = getValueFromTableStyleIdLastCol( element, stylesDocument, tableStyleID );
            if ( result != null )
            {
                return result;
            }
        }
        return null;
    }

    private Object getValueFromTableStyleIdRow( XWPFElement element, XWPFStylesDocument stylesDocument,
                                                String tableStyleID, TableCellInfo cellInfo )
    {
        if ( cellInfo.canApplyFirstRow() )
        {
            Object value = getValueFromTableStyleIdFirstRow( element, stylesDocument, tableStyleID );
            if ( value != null )
            {
                return value;
            }

        }
        else if ( cellInfo.canApplyLastRow() )
        {
            Object result = getValueFromTableStyleIdLastRow( element, stylesDocument, tableStyleID );
            if ( result != null )
            {
                return result;
            }
        }
        return null;
    }

    private Object getValueFromTableStyleIdFirstRow( XWPFElement element, XWPFStylesDocument stylesDocument,
                                                     String tableStyleID )
    {
        return getValueFromTableStyleId( element,
                                         stylesDocument,
                                         tableStyleID,
                                         org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblStyleOverrideType.FIRST_ROW );
    }

    private Object getValueFromTableStyleIdLastRow( XWPFElement element, XWPFStylesDocument stylesDocument,
                                                    String tableStyleID )
    {
        return getValueFromTableStyleId( element,
                                         stylesDocument,
                                         tableStyleID,
                                         org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblStyleOverrideType.LAST_ROW );
    }

    private Object getValueFromTableStyleIdFirstCol( XWPFElement element, XWPFStylesDocument stylesDocument,
                                                     String tableStyleID )
    {
        return getValueFromTableStyleId( element,
                                         stylesDocument,
                                         tableStyleID,
                                         org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblStyleOverrideType.FIRST_COL );
    }

    private Object getValueFromTableStyleIdLastCol( XWPFElement element, XWPFStylesDocument stylesDocument,
                                                    String tableStyleID )
    {
        return getValueFromTableStyleId( element,
                                         stylesDocument,
                                         tableStyleID,
                                         org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblStyleOverrideType.LAST_COL );
    }

    private Object getValueFromTableStyleId( XWPFElement element,
                                             XWPFStylesDocument stylesDocument,
                                             String tableStyleID,
                                             org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblStyleOverrideType.Enum type )
    {
        Object defaultValue = XWPFStylesDocument.EMPTY_VALUE;
        if ( StringUtils.isEmpty( tableStyleID ) )
        {
            return null;
        }

        // Search from cache
        String key = getKey( element, stylesDocument, tableStyleID, type );
        Object result = stylesDocument.getValue( key );
        if ( result != null )
        {
            return getValueOrNull( result );
        }
        // Value is not computed, compute it

        // Get the table style
        CTStyle style = stylesDocument.getStyle( tableStyleID );
        if ( style == null )
        {
            // should never come
            stylesDocument.setValue( key, defaultValue );
            return null;
        }

        // try to compute it
        Object value = null;
        CTTblStylePr tblStylePr = stylesDocument.getTableStyle( tableStyleID, type );
        if ( tblStylePr != null )
        {
            value = getValueFromTableStyle( tblStylePr, stylesDocument );
            if ( value != null )
            {
                // Value is computed, cache it and return it.
                stylesDocument.setValue( key, value );
                return value;
            }

            // Check if style has ancestor with basedOn
            value = getValueFromTableStyleId( element, stylesDocument, getBasisStyleID( style ), type );
        }
        value = value != null ? value : defaultValue;
        updateValueCache( stylesDocument, key, value );
        return getValueOrNull( value );
    }

    private Value getValueOrNull( Object result )
    {
        return result.equals( XWPFStylesDocument.EMPTY_VALUE ) ? null : (Value) result;
    }

    public Object getValueFromStyleIds( XWPFElement element, XWPFStylesDocument stylesDocument, Object defaultValue )
    {
        String[] styleIds = getStyleID( element );
        if ( styleIds != null )
        {
            String styleId = null;
            for ( int i = 0; i < styleIds.length; i++ )
            {
                styleId = styleIds[i];
                Object value = getValueFromStyleId( element, stylesDocument, styleId, defaultValue );
                if ( value != null )
                {
                    return getValueOrNull( value );
                }
            }
        }
        return null;
    }

    public abstract Value getValueFromElement( XWPFElement element, XWPFStylesDocument stylesDocument );

    protected Value getDefaultValue( XWPFElement element, XWPFStylesDocument stylesDocument )
    {
        Value value = getValueFromDefaultStyle( element, stylesDocument );
        if ( value != null )
        {
            return value;
        }
        value = getValueFromDocDefaultsStyle( element, stylesDocument );
        if ( value != null )
        {
            return value;
        }
        return getStaticValue( element, stylesDocument );
    }

    protected Value getStaticValue( XWPFElement element, XWPFStylesDocument stylesDocument )
    {
        return null;
    }

    private Object getValueFromStyleId( XWPFElement element, XWPFStylesDocument stylesDocument, String styleId,
                                        Object defaultValue )
    {

        if ( StringUtils.isEmpty( styleId ) )
        {
            return null;
        }

        // Search from cache
        String key = getKey( element, stylesDocument, styleId, null );
        Object result = stylesDocument.getValue( key );
        if ( result != null )
        {
            return result;
        }

        // Value is not computed, compute it

        // Get the style
        CTStyle style = stylesDocument.getStyle( styleId );
        if ( style == null )
        {
            // should never come
            stylesDocument.setValue( key, defaultValue );
            return null;
        }

        // try to compute value
        Object value = getValueFromStyle( style, stylesDocument );
        if ( value != null )
        {
            // Value is computed, cache it and return it.
            stylesDocument.setValue( key, value );
            return value;
        }

        // Check if style has ancestor with basedOn
        value = getValueFromStyleId( element, stylesDocument, getBasisStyleID( style ), defaultValue );
        value = value != null ? value : defaultValue;
        updateValueCache( stylesDocument, key, value );
        return value;
    }

    private void updateValueCache( XWPFStylesDocument stylesDocument, String key, Object value )
    {
        if ( value != null )
        {
            // Value is computed, cache it and return it.
            stylesDocument.setValue( key, value );
        }
        else
        {
            stylesDocument.setValue( key, XWPFStylesDocument.EMPTY_VALUE );
        }
    }

    protected String getKey( XWPFElement element, XWPFStylesDocument stylesDocument, String styleId,
                             org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblStyleOverrideType.Enum type )
    {
        return getKeyBuffer( element, stylesDocument, styleId, type ).toString();
    }

    protected StringBuilder getKeyBuffer( XWPFElement element,
                                          XWPFStylesDocument stylesDocument,
                                          String styleId,
                                          org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblStyleOverrideType.Enum type )
    {
        StringBuilder key = new StringBuilder( this.getClass().getName() );
        if ( StringUtils.isNotEmpty( styleId ) )
        {
            key.append( "_" ).append( styleId ).toString();
        }
        if ( type != null )
        {
            key.append( "_table" );
            key.append( type.intValue() );
        }
        return key;
    }

    private String getBasisStyleID( CTStyle style )
    {
        if ( style.getBasedOn() != null )
            return style.getBasedOn().getVal();
        else
            return null;
    }

    protected abstract String[] getStyleID( XWPFElement element );

    protected abstract Value getValueFromStyle( CTStyle style, XWPFStylesDocument stylesDocument );

    protected abstract Value getValueFromTableStyle( CTTblStylePr tblStylePr, XWPFStylesDocument stylesDocument );

    protected Value getValueFromDefaultStyle( XWPFElement element, XWPFStylesDocument stylesDocument )
    {
        Value value = null;
        CTStyle style = getDefaultStyle( element, stylesDocument );
        if ( style != null )
        {
            value = getValueFromStyle( style, stylesDocument );
        }
        return value;
    }

    protected Value getValueFromDocDefaultsStyle( XWPFElement element, XWPFStylesDocument stylesDocument )
    {
        CTDocDefaults docDefaults = stylesDocument.getDocDefaults();
        if ( docDefaults == null )
        {
            return null;
        }
        Value value = getValueFromDocDefaultsStyle( docDefaults, stylesDocument );
        if ( value != null )
        {
            return value;
        }
        return null;
    }

    protected abstract Value getValueFromDocDefaultsStyle( CTDocDefaults docDefaults, XWPFStylesDocument stylesDocument );

    protected abstract CTStyle getDefaultStyle( XWPFElement element, XWPFStylesDocument stylesDocument );

    /**
     * Returns the table cell which is the parent of the XWPF element and null otherwise
     * 
     * @param element
     * @return
     */
    protected abstract XWPFTableCell getParentTableCell( XWPFElement element );

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy