Package com.sun.star.report.pentaho.layoutprocessor

Source Code of com.sun.star.report.pentaho.layoutprocessor.AbstractReportElementLayoutController

/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/


package com.sun.star.report.pentaho.layoutprocessor;

import com.sun.star.report.pentaho.model.OfficeGroupSection;
import com.sun.star.report.pentaho.model.ReportElement;

import org.jfree.report.DataFlags;
import org.jfree.report.DataRow;
import org.jfree.report.DataSourceException;
import org.jfree.report.ReportDataFactoryException;
import org.jfree.report.ReportProcessingException;
import org.jfree.report.expressions.Expression;
import org.jfree.report.flow.FlowController;
import org.jfree.report.flow.ReportTarget;
import org.jfree.report.flow.layoutprocessor.AbstractLayoutController;
import org.jfree.report.flow.layoutprocessor.LayoutController;
import org.jfree.report.flow.layoutprocessor.LayoutControllerUtil;
import org.jfree.report.flow.layoutprocessor.SectionLayoutController;
import org.jfree.report.structure.Element;
import org.jfree.report.structure.Group;

import org.pentaho.reporting.libraries.formula.lvalues.ContextLookup;
import org.pentaho.reporting.libraries.formula.lvalues.LValue;

/**
* Todo: Document me!
*
* @author Thomas Morgner
* @since 05.03.2007
* @noinspection CloneableClassWithoutClone
*/
public abstract class AbstractReportElementLayoutController
        extends AbstractLayoutController
{

    public static final int NOT_STARTED = 0;
    public static final int FINISHED = 2;
    private int state;

    protected AbstractReportElementLayoutController()
    {
    }

    /**
     * Advances the processing position.
     *
     * @param target the report target that receives generated events.
     * @return the new layout controller instance representing the new state.
     *
     * @throws org.jfree.report.DataSourceException        if there was a problem reading data from
     *                                    the datasource.
     * @throws org.jfree.report.ReportProcessingException  if there was a general problem during
     *                                    the report processing.
     * @throws org.jfree.report.ReportDataFactoryException if a query failed.
     */
    public LayoutController advance(final ReportTarget target)
            throws DataSourceException, ReportDataFactoryException,
            ReportProcessingException
    {
        if (state != AbstractReportElementLayoutController.NOT_STARTED)
        {
            throw new IllegalStateException();
        }

        boolean isPrintableContent = true;
        final ReportElement text = (ReportElement) getNode();
        // Tests we have to perform:
        // 1. Print when group changes. We can know whether a group changed by
        //    looking at the newly introduced iteration counter.
        //
        //    Whether we use the next one or the one after that depends on whether
        //    this element is a child of a group-header or group-footer.

        // 2. Print repeated values. This never applies to static text or static
        //    elements.
        if ((text.isPrintWhenGroupChanges() && !isGroupChanged()) || (!text.isPrintRepeatedValues() && !isValueChanged()))
        {
            // if this is set to true, then we print the element only if this is the
            // first occurrence in this group.
            // or
            // If this is set to true, we evaluate the formula of the element and
            // try to derive whether there was a change.
            isPrintableContent = false;
        }

        // 3. Evaluate the Display Condition
        final Expression dc = text.getDisplayCondition();
        if (dc != null)
        {
            final Object o = LayoutControllerUtil.evaluateExpression(getFlowController(), text, dc);
            if (Boolean.FALSE.equals(o))
            {
//        LOGGER.debug ("DISPLAY Condition forbids printing");
                isPrintableContent = false;
            }
        }

        if (!isPrintableContent)
        {
            // There is no printable content at all. Set the state to FINISHED
            return join(getFlowController());
        }
        else
        {
            // delegate to the handler ..
            return delegateContentGeneration(target);
        }

    }

    protected abstract boolean isValueChanged();

    protected boolean isGroupChanged()
    {
        // search the group.
        final SectionLayoutController slc = findGroup();
        if (slc == null)
        {
            // Always print the content of the report header and footer and
            // the page header and footer.
            return true;
        }

        // we are in the first iteration, so yes, the group has changed recently.
        return slc.getIterationCount() == 0;
    }

    private SectionLayoutController findGroup()
    {
        LayoutController parent = getParent();
        boolean skipNext = false;
        while (parent != null)
        {
            if (!(parent instanceof SectionLayoutController))
            {
                parent = parent.getParent();
            }
            else
            {
                final SectionLayoutController slc = (SectionLayoutController) parent;
                final Element element = slc.getElement();
                if (element instanceof OfficeGroupSection)
                {
                    // This is a header or footer. So we take the next group instead.
                    skipNext = true;
                    parent = parent.getParent();
                }
                else if (!(element instanceof Group))
                {
                    parent = parent.getParent();
                }
                else if (skipNext)
                {
                    skipNext = false;
                    parent = parent.getParent();
                }
                else
                {
                    return (SectionLayoutController) parent;
                }
            }
        }
        return null;
    }

    /**
     * Joins with a delegated process flow. This is generally called from a child
     * flow and should *not* (I mean it!) be called from outside. If you do,
     * you'll suffer.
     *
     * @param flowController the flow controller of the parent.
     * @return the joined layout controller that incorperates all changes from the
     *         delegate.
     */
    public LayoutController join(final FlowController flowController)
            throws DataSourceException, ReportDataFactoryException,
            ReportProcessingException
    {
        final AbstractReportElementLayoutController alc =
                (AbstractReportElementLayoutController) clone();
        alc.state = AbstractReportElementLayoutController.FINISHED;
        return alc;
    }

    protected abstract LayoutController delegateContentGeneration(final ReportTarget target)
            throws ReportProcessingException, ReportDataFactoryException,
            DataSourceException;

    /**
     * Checks, whether the layout controller would be advanceable. If this method
     * returns true, it is generally safe to call the 'advance()' method.
     *
     * @return true, if the layout controller is advanceable, false otherwise.
     */
    public boolean isAdvanceable()
    {
        return state != AbstractReportElementLayoutController.FINISHED;
    }

    protected boolean isReferenceChanged(final LValue lValue)
    {
        if (lValue instanceof ContextLookup)
        {
            final ContextLookup rval = (ContextLookup) lValue;
            final String s = rval.getName();
            final DataRow view = getFlowController().getMasterRow().getGlobalView();
            try
            {
                final DataFlags flags = view.getFlags(s);
                if (flags != null && flags.isChanged())
                {
//            LOGGER.debug ("Reference " + s + " is changed");
                    return true;
                }
//        LOGGER.debug ("Reference " + s + " is unchanged");
            }
            catch (DataSourceException e)
            {
                // ignore .. assume that the reference has not changed.
            }
        }
        final LValue[] childValues = lValue.getChildValues();
        for (int i = 0; i < childValues.length; i++)
        {
            final LValue value = childValues[i];
            if (isReferenceChanged(value))
            {
                return true;
            }
        }
//    LOGGER.debug ("Unchanged.");
        return false;
    }

    public int getState()
    {
        return state;
    }

    protected void setState(final int state)
    {
        this.state = state;
    }
}
TOP

Related Classes of com.sun.star.report.pentaho.layoutprocessor.AbstractReportElementLayoutController

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.