org.oss.pdfreporter.engine.fill.JRFillObjectFactory.java Source code

Java tutorial

Introduction

Here is the source code for org.oss.pdfreporter.engine.fill.JRFillObjectFactory.java

Source

/*
 * JasperReports - Free Java Reporting Library.
 * Copyright (C) 2001 - 2011 Jaspersoft Corporation. All rights reserved.
 * http://www.jaspersoft.com
 *
 * Unless you have purchased a commercial license agreement from Jaspersoft,
 * the following license terms apply:
 *
 * This program is part of JasperReports.
 *
 * JasperReports is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * JasperReports is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with JasperReports. If not, see <http://www.gnu.org/licenses/>.
 */
package org.oss.pdfreporter.engine.fill;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;

import org.oss.pdfreporter.crosstabs.JRCrosstab;
import org.oss.pdfreporter.crosstabs.JRCrosstabDataset;
import org.oss.pdfreporter.crosstabs.JRCrosstabParameter;
import org.oss.pdfreporter.crosstabs.fill.JRFillCrosstabParameter;
import org.oss.pdfreporter.engine.JRBand;
import org.oss.pdfreporter.engine.JRBreak;
import org.oss.pdfreporter.engine.JRComponentElement;
import org.oss.pdfreporter.engine.JRConditionalStyle;
import org.oss.pdfreporter.engine.JRDataset;
import org.oss.pdfreporter.engine.JRDatasetRun;
import org.oss.pdfreporter.engine.JRDefaultStyleProvider;
import org.oss.pdfreporter.engine.JRElementGroup;
import org.oss.pdfreporter.engine.JREllipse;
import org.oss.pdfreporter.engine.JRExpression;
import org.oss.pdfreporter.engine.JRField;
import org.oss.pdfreporter.engine.JRFrame;
import org.oss.pdfreporter.engine.JRGenericElement;
import org.oss.pdfreporter.engine.JRGroup;
import org.oss.pdfreporter.engine.JRImage;
import org.oss.pdfreporter.engine.JRLine;
import org.oss.pdfreporter.engine.JRParameter;
import org.oss.pdfreporter.engine.JRRectangle;
import org.oss.pdfreporter.engine.JRReportTemplate;
import org.oss.pdfreporter.engine.JRRuntimeException;
import org.oss.pdfreporter.engine.JRSection;
import org.oss.pdfreporter.engine.JRStaticText;
import org.oss.pdfreporter.engine.JRStyle;
import org.oss.pdfreporter.engine.JRStyleContainer;
import org.oss.pdfreporter.engine.JRStyleSetter;
import org.oss.pdfreporter.engine.JRSubreport;
import org.oss.pdfreporter.engine.JRSubreportReturnValue;
import org.oss.pdfreporter.engine.JRTextField;
import org.oss.pdfreporter.engine.JRVariable;
import org.oss.pdfreporter.engine.base.JRBaseConditionalStyle;
import org.oss.pdfreporter.engine.base.JRBaseStyle;
import org.oss.pdfreporter.uses.org.apache.commons.collections.SequencedHashMap;

/**
 * A factory used to instantiate fill objects based on compiled report objects.
 * 
 * @author Teodor Danciu (teodord@users.sourceforge.net)
 * @version $Id: JRFillObjectFactory.java 5498 2012-07-20 11:20:34Z lucianc $
 */
public class JRFillObjectFactory extends JRAbstractFillObjectFactory {
    private final static Logger logger = Logger.getLogger(JRFillObjectFactory.class.getName());

    /**
     *
     */
    protected JRBaseFiller filler;
    private JRFillExpressionEvaluator evaluator;

    private JRFillObjectFactory parentFiller;

    //   private JRFont defaultFont;

    private List<JRFillElementDataset> elementDatasets = new ArrayList<JRFillElementDataset>();
    private Map<String, List<JRFillElementDataset>> elementDatasetMap = new HashMap<String, List<JRFillElementDataset>>();

    private Map<String, List<JRStyleSetter>> delayedStyleSettersByName = new HashMap<String, List<JRStyleSetter>>();

    protected static class StylesList {
        private final List<JRStyle> styles = new ArrayList<JRStyle>();
        private final Map<String, Integer> stylesIdx = new HashMap<String, Integer>();

        public boolean containsStyle(String name) {
            return stylesIdx.containsKey(name);
        }

        public JRStyle getStyle(String name) {
            Integer idx = stylesIdx.get(name);
            return idx == null ? null : styles.get(idx.intValue());
        }

        public void addStyle(JRStyle style) {
            styles.add(style);
            stylesIdx.put(style.getName(), Integer.valueOf(styles.size() - 1));
        }

        public void renamed(String oldName, String newName) {
            Integer idx = stylesIdx.remove(oldName);
            stylesIdx.put(newName, idx);
        }
    }

    private Set<JRStyle> originalStyleList;
    private StylesList stylesMap = new StylesList();

    /**
     *
     */
    protected JRFillObjectFactory(JRBaseFiller filler) {
        this(filler, filler.calculator);
    }

    /**
     *
     */
    public JRFillObjectFactory(JRBaseFiller filler, JRFillExpressionEvaluator expressionEvaluator) {
        this.filler = filler;
        this.evaluator = expressionEvaluator;
    }

    public JRFillObjectFactory(JRFillObjectFactory parent, JRFillExpressionEvaluator expressionEvaluator) {
        this.parentFiller = parent;
        this.filler = parent.filler;
        this.evaluator = expressionEvaluator;
    }

    /**
     * Returns the expression evaluator which is to be used by objects
     * created by this factory.
     * 
     * @return the expression evaluator associated with this factory
     */
    public JRFillExpressionEvaluator getExpressionEvaluator() {
        return evaluator;
    }

    /**
     *
     */
    protected JRFillChartDataset[] getDatasets() {
        return elementDatasets.toArray(new JRFillChartDataset[elementDatasets.size()]);
    }

    protected JRFillElementDataset[] getElementDatasets(JRDataset dataset) {
        JRFillElementDataset[] elementDatasetsArray;
        List<JRFillElementDataset> elementDatasetsList;
        if (dataset.isMainDataset()) {
            elementDatasetsList = elementDatasets;
        } else {
            elementDatasetsList = elementDatasetMap.get(dataset.getName());
        }

        if (elementDatasetsList == null || elementDatasetsList.size() == 0) {
            elementDatasetsArray = new JRFillElementDataset[0];
        } else {
            elementDatasetsArray = new JRFillElementDataset[elementDatasetsList.size()];
            elementDatasetsList.toArray(elementDatasetsArray);
        }

        return elementDatasetsArray;
    }

    protected void registerDelayedStyleSetter(JRStyleSetter delayedSetter, String styleName) {
        if (parentFiller == null) {
            List<JRStyleSetter> setters = delayedStyleSettersByName.get(styleName);
            if (setters == null) {
                setters = new ArrayList<JRStyleSetter>();
                delayedStyleSettersByName.put(styleName, setters);
            }

            setters.add(delayedSetter);
        } else {
            parentFiller.registerDelayedStyleSetter(delayedSetter, styleName);
        }
    }

    public void registerDelayedStyleSetter(JRStyleSetter delayedSetter, JRStyleContainer styleContainer) {
        JRStyle style = styleContainer.getStyle();
        String nameReference = styleContainer.getStyleNameReference();
        if (style != null) {
            registerDelayedStyleSetter(delayedSetter, style.getName());
        } else if (nameReference != null) {
            registerDelayedStyleSetter(delayedSetter, nameReference);
        }
    }

    public JRBaseStyle getStyle(JRStyle style) {
        JRBaseStyle fillStyle = null;

        if (style != null) {
            fillStyle = (JRBaseStyle) get(style);
            if (fillStyle == null) {
                fillStyle = new JRBaseStyle(style, this);

                // deduplicate to previously created identical instances
                fillStyle = filler.fillContext.deduplicate(fillStyle);

                put(style, fillStyle);

                if (originalStyleList != null && originalStyleList.contains(style)) {
                    renameExistingStyle(style.getName());
                    stylesMap.addStyle(style);
                }
            }
        }

        return fillStyle;
    }

    protected void renameExistingStyle(String name) {
        JRStyle originalStyle = stylesMap.getStyle(name);
        if (originalStyle != null) {
            //found a previous external style with the same name
            //renaming the previous style
            JRBaseStyle style = (JRBaseStyle) get(originalStyle);

            String newName;
            int suf = 1;
            do {
                newName = name + suf;
                ++suf;
            } while (stylesMap.containsStyle(newName));

            style.rename(newName);
            stylesMap.renamed(name, newName);
        }
    }

    public void setStyle(JRStyleSetter setter, JRStyleContainer styleContainer) {
        JRStyle style = styleContainer.getStyle();
        String nameReference = styleContainer.getStyleNameReference();
        if (style != null) {
            JRStyle newStyle = getStyle(style);
            setter.setStyle(newStyle);
        } else if (nameReference != null) {
            JRStyle originalStyle = stylesMap.getStyle(nameReference);
            if (originalStyle == null) {
                throw new JRRuntimeException("Style " + nameReference + " not found");
            }

            JRStyle externalStyle = (JRStyle) get(originalStyle);
            setter.setStyle(externalStyle);
        }
    }

    /**
     *
     */
    protected JRFillParameter getParameter(JRParameter parameter) {
        JRFillParameter fillParameter = null;

        if (parameter != null) {
            fillParameter = (JRFillParameter) get(parameter);
            if (fillParameter == null) {
                fillParameter = new JRFillParameter(parameter, this);
            }
        }

        return fillParameter;
    }

    /**
     *
     */
    protected JRFillField getField(JRField field) {
        JRFillField fillField = null;

        if (field != null) {
            fillField = (JRFillField) get(field);
            if (fillField == null) {
                fillField = new JRFillField(field, this);
            }
        }

        return fillField;
    }

    /**
     *
     */
    public JRFillVariable getVariable(JRVariable variable) {
        JRFillVariable fillVariable = null;

        if (variable != null) {
            fillVariable = (JRFillVariable) get(variable);
            if (fillVariable == null) {
                fillVariable = new JRFillVariable(variable, this);
            }
        }

        return fillVariable;
    }

    /**
     *
     */
    protected JRFillGroup getGroup(JRGroup group) {
        JRFillGroup fillGroup = null;

        if (group != null) {
            fillGroup = (JRFillGroup) get(group);
            if (fillGroup == null) {
                fillGroup = new JRFillGroup(group, this);
            }
        }

        return fillGroup;
    }

    /**
     *
     */
    protected JRFillSection getSection(JRSection section) {
        JRFillSection fillSection = null;

        if (section == null) {
            fillSection = filler.missingFillSection;
        } else {
            fillSection = (JRFillSection) get(section);
            if (fillSection == null) {
                fillSection = new JRFillSection(filler, section, this);
            }
        }

        return fillSection;
    }

    /**
     *
     */
    protected JRFillBand getBand(JRBand band) {
        JRFillBand fillBand = null;

        if (band == null) {
            fillBand = filler.missingFillBand;
        } else {
            fillBand = (JRFillBand) get(band);
            if (fillBand == null) {
                fillBand = new JRFillBand(filler, band, this);
            }
        }

        return fillBand;
    }

    /**
     *
     */
    public void visitElementGroup(JRElementGroup elementGroup) {
        JRFillElementGroup fillElementGroup = null;

        if (elementGroup != null) {
            fillElementGroup = (JRFillElementGroup) get(elementGroup);
            if (fillElementGroup == null) {
                fillElementGroup = new JRFillElementGroup(elementGroup, this);
            }
        }

        setVisitResult(fillElementGroup);
    }

    /**
     *
     */
    public void visitBreak(JRBreak breakElement) {
        JRFillBreak fillBreak = null;

        if (breakElement != null) {
            fillBreak = (JRFillBreak) get(breakElement);
            if (fillBreak == null) {
                fillBreak = new JRFillBreak(filler, breakElement, this);
            }
        }

        setVisitResult(fillBreak);
    }

    /**
     *
     */
    public void visitLine(JRLine line) {
        JRFillLine fillLine = null;

        if (line != null) {
            fillLine = (JRFillLine) get(line);
            if (fillLine == null) {
                fillLine = new JRFillLine(filler, line, this);
            }
        }

        setVisitResult(fillLine);
    }

    /**
     *
     */
    public void visitRectangle(JRRectangle rectangle) {
        JRFillRectangle fillRectangle = null;

        if (rectangle != null) {
            fillRectangle = (JRFillRectangle) get(rectangle);
            if (fillRectangle == null) {
                fillRectangle = new JRFillRectangle(filler, rectangle, this);
            }
        }

        setVisitResult(fillRectangle);
    }

    /**
     *
     */
    public void visitEllipse(JREllipse ellipse) {
        JRFillEllipse fillEllipse = null;

        if (ellipse != null) {
            fillEllipse = (JRFillEllipse) get(ellipse);
            if (fillEllipse == null) {
                fillEllipse = new JRFillEllipse(filler, ellipse, this);
            }
        }

        setVisitResult(fillEllipse);
    }

    /**
     *
     */
    public void visitImage(JRImage image) {
        JRFillImage fillImage = null;

        if (image != null) {
            fillImage = (JRFillImage) get(image);
            if (fillImage == null) {
                fillImage = new JRFillImage(filler, image, this);
            }
        }

        setVisitResult(fillImage);
    }

    /**
     *
     */
    public void visitStaticText(JRStaticText staticText) {
        JRFillStaticText fillStaticText = null;

        if (staticText != null) {
            fillStaticText = (JRFillStaticText) get(staticText);
            if (fillStaticText == null) {
                fillStaticText = new JRFillStaticText(filler, staticText, this);
            }
        }

        setVisitResult(fillStaticText);
    }

    /**
     *
     */
    public void visitTextField(JRTextField textField) {
        JRFillTextField fillTextField = null;

        if (textField != null) {
            fillTextField = (JRFillTextField) get(textField);
            if (fillTextField == null) {
                fillTextField = new JRFillTextField(filler, textField, this);
            }
        }

        setVisitResult(fillTextField);
    }

    /**
     *
     */
    public void visitSubreport(JRSubreport subreport) {
        JRFillSubreport fillSubreport = null;

        if (subreport != null) {
            fillSubreport = (JRFillSubreport) get(subreport);
            if (fillSubreport == null) {
                fillSubreport = new JRFillSubreport(filler, subreport, this);
            }
        }

        setVisitResult(fillSubreport);
    }

    protected JRFillSubreportReturnValue getSubreportReturnValue(JRSubreportReturnValue returnValue) {
        JRFillSubreportReturnValue fillReturnValue = null;

        if (returnValue != null) {
            fillReturnValue = (JRFillSubreportReturnValue) get(returnValue);
            if (fillReturnValue == null) {
                fillReturnValue = new JRFillSubreportReturnValue(returnValue, this, filler);
            }
        }

        return fillReturnValue;
    }

    public void visitCrosstab(JRCrosstab crosstabElement) {
        JRFillCrosstab fillCrosstab = null;
        logger.finest("Visit Crosstab: " + crosstabElement);
        if (crosstabElement != null) {
            fillCrosstab = (JRFillCrosstab) get(crosstabElement);
            if (fillCrosstab == null) {
                fillCrosstab = new JRFillCrosstab(filler, crosstabElement, this);
            }
        }

        setVisitResult(fillCrosstab);
    }

    public JRFillCrosstab.JRFillCrosstabDataset getCrosstabDataset(JRCrosstabDataset dataset,
            JRFillCrosstab fillCrosstab) {
        JRFillCrosstab.JRFillCrosstabDataset fillDataset = null;

        if (dataset != null) {
            fillDataset = (JRFillCrosstab.JRFillCrosstabDataset) get(dataset);
            if (fillDataset == null) {
                fillDataset = fillCrosstab.new JRFillCrosstabDataset(dataset, this);
                registerElementDataset(fillDataset);
            }
        }

        return fillDataset;
    }

    public JRFillDataset getDataset(JRDataset dataset) {
        JRFillDataset fillDataset = null;

        if (dataset != null) {
            fillDataset = (JRFillDataset) get(dataset);
            if (fillDataset == null) {
                fillDataset = new JRFillDataset(filler, dataset, this);
            }
        }

        return fillDataset;
    }

    /**
     * Register an element dataset with the report filler.
     * 
     * <p>
     * Registration of element datasets is required in order for the filler
     * to increment the datasets when iterating through the datasource.
     * 
     * @param elementDataset the dataset to register
     */
    public void registerElementDataset(JRFillElementDataset elementDataset) {
        List<JRFillElementDataset> elementDatasetsList;
        JRDatasetRun datasetRun = elementDataset.getDatasetRun();
        if (datasetRun == null) {
            elementDatasetsList = elementDatasets;
        } else {
            String datasetName = datasetRun.getDatasetName();
            elementDatasetsList = elementDatasetMap.get(datasetName);
            if (elementDatasetsList == null) {
                elementDatasetsList = new ArrayList<JRFillElementDataset>();
                elementDatasetMap.put(datasetName, elementDatasetsList);
            }
        }
        elementDatasetsList.add(elementDataset);
    }

    public JRFillDatasetRun getDatasetRun(JRDatasetRun datasetRun) {
        JRFillDatasetRun fillDatasetRun = null;

        if (datasetRun != null) {
            fillDatasetRun = (JRFillDatasetRun) get(datasetRun);
            if (fillDatasetRun == null) {
                fillDatasetRun = new JRFillDatasetRun(filler, datasetRun, this);
            }
        }

        return fillDatasetRun;
    }

    public JRFillCrosstabParameter getCrosstabParameter(JRCrosstabParameter parameter) {
        JRFillCrosstabParameter fillParameter = null;

        if (parameter != null) {
            fillParameter = (JRFillCrosstabParameter) get(parameter);
            if (fillParameter == null) {
                fillParameter = new JRFillCrosstabParameter(parameter, this);
            }
        }

        return fillParameter;
    }

    public void visitFrame(JRFrame frame) {
        Object fillFrame = null;
        // This is the only place where an object gets replaced in the factory map by something else,
        // and we can no longer make a precise cast when getting it.
        // The JRFillFrame object is replaced in the map by a JRFillFrameElements object.
        //JRFillFrame fillFrame = null;

        if (frame != null) {
            fillFrame = get(frame);
            //fillFrame = (JRFillFrame) get(frame);
            if (fillFrame == null) {
                fillFrame = new JRFillFrame(filler, frame, this);
            }
        }

        setVisitResult(fillFrame);
    }

    /**
     * Returns the current report filler.
     * 
     * @return the current report filler
     */
    public JRBaseFiller getFiller() {
        return filler;
    }

    /**
     *
     */
    public JRConditionalStyle getConditionalStyle(JRConditionalStyle conditionalStyle, JRStyle style) {
        JRBaseConditionalStyle baseConditionalStyle = null;
        if (conditionalStyle != null) {
            baseConditionalStyle = (JRBaseConditionalStyle) get(conditionalStyle);
            if (baseConditionalStyle == null) {
                baseConditionalStyle = new JRBaseConditionalStyle(conditionalStyle, style, this);
                put(conditionalStyle, baseConditionalStyle);
            }
        }
        return baseConditionalStyle;
    }

    public JRExpression getExpression(JRExpression expression, boolean assignNotUsedId) {
        return expression;
    }

    public JRFillReportTemplate getReportTemplate(JRReportTemplate template) {
        JRFillReportTemplate fillTemplate = null;
        if (template != null) {
            fillTemplate = (JRFillReportTemplate) get(template);
            if (fillTemplate == null) {
                fillTemplate = new JRFillReportTemplate(template, filler, this);
            }
        }
        return fillTemplate;
    }

    public List<JRStyle> setStyles(List<JRStyle> styles) {
        originalStyleList = new HashSet<JRStyle>(styles);

        //filtering requested styles
        Set<JRStyle> requestedStyles = collectRequestedStyles(styles);

        //collect used styles
        Map<JRStyle, Object> usedStylesMap = new SequencedHashMap();
        Map<String, JRStyle> allStylesMap = new HashMap<String, JRStyle>();
        for (Iterator<JRStyle> it = styles.iterator(); it.hasNext();) {
            JRStyle style = it.next();
            if (requestedStyles.contains(style)) {
                collectUsedStyles(style, usedStylesMap, allStylesMap);
            }
            allStylesMap.put(style.getName(), style);
        }

        List<JRStyle> includedStyles = new ArrayList<JRStyle>();
        for (Iterator<JRStyle> it = usedStylesMap.keySet().iterator(); it.hasNext();) {
            JRStyle style = it.next();
            JRStyle newStyle = getStyle(style);

            includedStyles.add(newStyle);
            if (requestedStyles.contains(style)) {
                useDelayedStyle(newStyle);
            }
        }

        checkUnresolvedReferences();

        return includedStyles;
    }

    protected Set<JRStyle> collectRequestedStyles(List<JRStyle> externalStyles) {
        Map<String, JRStyle> requestedStylesMap = new HashMap<String, JRStyle>();
        for (Iterator<JRStyle> it = externalStyles.iterator(); it.hasNext();) {
            JRStyle style = it.next();
            String name = style.getName();
            if (delayedStyleSettersByName.containsKey(name)) {
                requestedStylesMap.put(name, style);
            }
        }

        return new HashSet<JRStyle>(requestedStylesMap.values());
    }

    protected void collectUsedStyles(JRStyle style, Map<JRStyle, Object> usedStylesMap,
            Map<String, JRStyle> allStylesMap) {
        if (!usedStylesMap.containsKey(style) && originalStyleList.contains(style)) {
            JRStyle parent = style.getStyle();
            if (parent == null) {
                String parentName = style.getStyleNameReference();
                if (parentName != null) {
                    parent = allStylesMap.get(parentName);
                    if (parent == null) {
                        throw new JRRuntimeException("Style " + parentName + " not found");
                    }
                }
            }

            if (parent != null) {
                collectUsedStyles(parent, usedStylesMap, allStylesMap);
            }

            usedStylesMap.put(style, null);
        }
    }

    protected void useDelayedStyle(JRStyle style) {
        List<JRStyleSetter> delayedSetters = delayedStyleSettersByName.remove(style.getName());
        if (delayedSetters != null) {
            for (Iterator<JRStyleSetter> it = delayedSetters.iterator(); it.hasNext();) {
                JRStyleSetter setter = it.next();
                setter.setStyle(style);
            }
        }
    }

    protected void checkUnresolvedReferences() {
        if (!delayedStyleSettersByName.isEmpty()) {
            StringBuffer errorMsg = new StringBuffer("Could not resolve style(s): ");
            for (Iterator<String> it = delayedStyleSettersByName.keySet().iterator(); it.hasNext();) {
                String name = it.next();
                errorMsg.append(name);
                errorMsg.append(", ");
            }

            throw new JRRuntimeException(errorMsg.substring(0, errorMsg.length() - 2));
        }
    }

    public JRDefaultStyleProvider getDefaultStyleProvider() {
        return filler.getJasperPrint().getDefaultStyleProvider();
    }

    public void visitComponentElement(JRComponentElement componentElement) {
        JRFillComponentElement fill = null;

        if (componentElement != null) {
            fill = (JRFillComponentElement) get(componentElement);
            if (fill == null) {
                fill = new JRFillComponentElement(filler, componentElement, this);
            }
        }

        setVisitResult(fill);
    }

    public void visitGenericElement(JRGenericElement element) {
        JRFillGenericElement fill = null;
        if (element != null) {
            fill = (JRFillGenericElement) get(element);
            if (fill == null) {
                fill = new JRFillGenericElement(filler, element, this);
            }
        }
        setVisitResult(fill);
    }

    // TODO (21.03.2013, Donat, Open Software Solutions): Refactoring JFreeChart reactivate removed chart packages, see original class for the job

}