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

net.sf.jasperreports.engine.xml.JRXmlLoader Maven / Gradle / Ivy

There is a newer version: 7.0.1
Show newest version
/*
 * JasperReports - Free Java Reporting Library.
 * Copyright (C) 2001 - 2023 Cloud Software Group, Inc. 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 .
 */

/*
 * Contributors:
 * Artur Biesiadowski - [email protected] 
 */
package net.sf.jasperreports.engine.xml;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.digester.Digester;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import net.sf.jasperreports.engine.DefaultJasperReportsContext;
import net.sf.jasperreports.engine.JRDataset;
import net.sf.jasperreports.engine.JRDatasetRun;
import net.sf.jasperreports.engine.JRElementDataset;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRGroup;
import net.sf.jasperreports.engine.JRRuntimeException;
import net.sf.jasperreports.engine.JRVariable;
import net.sf.jasperreports.engine.JasperReportsContext;
import net.sf.jasperreports.engine.design.JRDesignChart;
import net.sf.jasperreports.engine.design.JRDesignDataset;
import net.sf.jasperreports.engine.design.JRDesignElement;
import net.sf.jasperreports.engine.design.JRDesignElementDataset;
import net.sf.jasperreports.engine.design.JRDesignImage;
import net.sf.jasperreports.engine.design.JRDesignTextField;
import net.sf.jasperreports.engine.design.JRDesignVariable;
import net.sf.jasperreports.engine.design.JRValidationException;
import net.sf.jasperreports.engine.design.JasperDesign;
import net.sf.jasperreports.engine.type.DatasetResetTypeEnum;
import net.sf.jasperreports.engine.type.IncrementTypeEnum;
import net.sf.jasperreports.engine.type.ResetTypeEnum;


/**
 * Utility class that helps parsing a JRXML file into a 
 * {@link net.sf.jasperreports.engine.design.JasperDesign} object.
 * 

* This can be done using one of the load(...) or loadXml * methods published by this class. Applications might need to do this in cases where report * templates kept in their source form (JRXML) must be modified at runtime based on * some user input and then compiled on the fly for filling with data. *

* @author Teodor Danciu ([email protected]) */ public class JRXmlLoader { public static final String EXCEPTION_MESSAGE_KEY_UNKNOWN_SUBDATASET = "xml.loader.unknown.subdataset"; public static final String EXCEPTION_MESSAGE_KEY_SUBDATASET_NOT_FOUND = "xml.loader.subdataset.not.found"; /** * */ private final JasperReportsContext jasperReportsContext; private JasperDesign jasperDesign; private LinkedList contextStack = new LinkedList<>(); private Map groupReferences = new HashMap<>(); //TODO use XmlGroupReference for datasets private Set groupBoundDatasets = new HashSet<>(); private List errors = new ArrayList<>(); private Digester digester; private boolean ignoreConsistencyProblems; /** * */ public JRXmlLoader(JasperReportsContext jasperReportsContext, Digester digester) { this.jasperReportsContext = jasperReportsContext; this.digester = digester; } /** * */ public JasperReportsContext getJasperReportsContext() { return jasperReportsContext; } /** * */ public void setJasperDesign(JasperDesign jasperDesign) { this.jasperDesign = jasperDesign; } public void addGroupReference(XmlGroupReference reference) { XmlLoaderReportContext reportContext = getReportContext(); groupReferences.put(reference, reportContext); } /** * @deprecated To be removed. */ public void addGroupReprintedElement(JRDesignElement element) { addGroupReference( new ElementReprintGroupReference(element)); } /** * @deprecated To be removed. */ public void addGroupEvaluatedImage(JRDesignImage image) { addGroupReference( new ImageEvaluationGroupReference(image)); } /** * @deprecated To be removed. */ public void addGroupEvaluatedTextField(JRDesignTextField textField) { addGroupReference( new TextFieldEvaluationGroupReference(textField)); } /** * @deprecated To be removed. */ public void addGroupEvaluatedChart(JRDesignChart chart) { addGroupReference( new ChartEvaluationGroupReference(chart)); } /** * */ public Set getGroupBoundDatasets() { return groupBoundDatasets; } /** * @see #load(JasperReportsContext, String) */ public static JasperDesign load(String sourceFileName) throws JRException//FIXMEREPO consider renaming { return load(DefaultJasperReportsContext.getInstance(), sourceFileName); } /** * */ public static JasperDesign load(JasperReportsContext jasperReportsContext, String sourceFileName) throws JRException//FIXMEREPO consider renaming { return load(jasperReportsContext, new File(sourceFileName)); } /** * @see #load(JasperReportsContext, File) */ public static JasperDesign load(File file) throws JRException { return load(DefaultJasperReportsContext.getInstance(), file); } /** * */ public static JasperDesign load(JasperReportsContext jasperReportsContext, File file) throws JRException { JasperDesign jasperDesign = null; try (FileInputStream fis = new FileInputStream(file)) { jasperDesign = JRXmlLoader.load(jasperReportsContext, fis); } catch (IOException e) { throw new JRException(e); } return jasperDesign; } /** * @see #load(JasperReportsContext, InputStream) */ public static JasperDesign load(InputStream is) throws JRException { return load(DefaultJasperReportsContext.getInstance(), is); } /** * */ public static JasperDesign load(JasperReportsContext jasperReportsContext, InputStream is) throws JRException { JasperDesign jasperDesign = null; JRXmlLoader xmlLoader = null; try { xmlLoader = new JRXmlLoader(jasperReportsContext, JRXmlDigesterFactory.createDigester(jasperReportsContext)); } catch (ParserConfigurationException | SAXException e) { throw new JRException(e); } jasperDesign = xmlLoader.loadXML(is); return jasperDesign; } /** * */ public JasperDesign loadXML(InputStream is) throws JRException { return loadXML(new InputSource(is)); } /** * */ public JasperDesign loadXML(InputSource is) throws JRException { try { digester.push(this); /* */ digester.parse(is); } catch (SAXException | IOException e) { throw new JRException(e); } finally { digester.clear(); } if (errors.size() > 0) { Exception e = errors.get(0); if (e instanceof JRException) { throw (JRException)e; } throw new JRException(e); } /* */ assignGroupsToVariables(jasperDesign.getMainDesignDataset()); for (Iterator it = jasperDesign.getDatasetsList().iterator(); it.hasNext();) { JRDesignDataset dataset = (JRDesignDataset) it.next(); assignGroupsToVariables(dataset); } assignGroupReferences(); this.assignGroupsToDatasets(); return jasperDesign; } /** * */ private void assignGroupsToVariables(JRDesignDataset dataset) throws JRException { JRVariable[] variables = dataset.getVariables(); if (variables != null && variables.length > 0) { Map groupsMap = dataset.getGroupsMap(); for(int i = 0; i < variables.length; i++) { JRDesignVariable variable = (JRDesignVariable)variables[i]; if (variable.getResetTypeValue() == ResetTypeEnum.GROUP) { String groupName = null; JRGroup group = variable.getResetGroup(); if (group != null) { groupName = group.getName(); group = groupsMap.get(groupName); } if (!ignoreConsistencyProblems && group == null) { throw new JRValidationException( "Unknown reset group '" + groupName + "' for variable : " + variable.getName(), variable ); } variable.setResetGroup(group); } else { variable.setResetGroup(null); } if (variable.getIncrementTypeValue() == IncrementTypeEnum.GROUP) { String groupName = null; JRGroup group = variable.getIncrementGroup(); if (group != null) { groupName = group.getName(); group = groupsMap.get(groupName); } if (!ignoreConsistencyProblems && group == null) { throw new JRValidationException( "Unknown increment group '" + groupName + "' for variable : " + variable.getName(), variable ); } variable.setIncrementGroup(group); } else { variable.setIncrementGroup(null); } } } } /** * */ private void assignGroupReferences() throws JRException { for (Map.Entry entry : groupReferences.entrySet()) { XmlGroupReference reference = entry.getKey(); XmlLoaderReportContext context = entry.getValue(); String groupName = null; JRGroup group = reference.getGroupReference(); if (group != null) { groupName = group.getName(); group = resolveGroup(groupName, context); } if (!ignoreConsistencyProblems && group == null) { reference.groupNotFound(groupName); } else { reference.assignGroup(group); } } } protected JRGroup resolveGroup(String groupName, XmlLoaderReportContext context) { JRGroup group; if (context == null) { // main dataset groups Map groupsMap = jasperDesign.getGroupsMap(); group = groupsMap.get(groupName); } else { String datasetName = context.getSubdatesetName(); JRDesignDataset dataset = (JRDesignDataset) jasperDesign.getDatasetMap().get(datasetName); if (dataset == null) { throw new JRRuntimeException( EXCEPTION_MESSAGE_KEY_SUBDATASET_NOT_FOUND, new Object[]{datasetName}); } group = dataset.getGroupsMap().get(groupName); } return group; } /** * */ private void assignGroupsToDatasets() throws JRException { for(Iterator it = groupBoundDatasets.iterator(); it.hasNext();) { JRDesignElementDataset dataset = (JRDesignElementDataset) it.next(); JRDatasetRun datasetRun = dataset.getDatasetRun(); Map groupsMap; if (datasetRun == null) { groupsMap = jasperDesign.getGroupsMap(); } else { Map datasetMap = jasperDesign.getDatasetMap(); String datasetName = datasetRun.getDatasetName(); JRDesignDataset subDataset = (JRDesignDataset) datasetMap.get(datasetName); if (subDataset == null) { throw new JRException( EXCEPTION_MESSAGE_KEY_UNKNOWN_SUBDATASET, new Object[]{datasetName}); } groupsMap = subDataset.getGroupsMap(); } if (dataset.getIncrementTypeValue() == IncrementTypeEnum.GROUP) { String groupName = null; JRGroup group = dataset.getIncrementGroup(); if (group != null) { groupName = group.getName(); group = groupsMap.get(group.getName()); } if (!ignoreConsistencyProblems && group == null) { throw new JRValidationException("Unknown increment group '" + groupName + "' for element dataset.", dataset); } dataset.setIncrementGroup(group); } else { dataset.setIncrementGroup(null); } if (dataset.getDatasetResetType() == DatasetResetTypeEnum.GROUP) { String groupName = null; JRGroup group = dataset.getResetGroup(); if (group != null) { groupName = group.getName(); group = groupsMap.get(group.getName()); } if (!ignoreConsistencyProblems && group == null) { throw new JRValidationException("Unknown reset group '" + groupName + "' for element dataset.", dataset); } dataset.setResetGroup(group); } else { dataset.setResetGroup(null); } } } /** * */ public void addError(Exception e) { if(!ignoreConsistencyProblems) { this.errors.add(e); } } /** * Returns true if the loader is set to ignore consistency problems * @return the ignoreConsistencyProblems flag. */ public boolean isIgnoreConsistencyProblems() { return ignoreConsistencyProblems; } /** * Allows to enable or disable the reporting of consistency problems. Consistency * problems are problems in the logical structure of the report such as references * to missing groups and fonts. * * @param ignoreConsistencyProblems The ignoreConsistencyProblems value to set. */ public void setIgnoreConsistencyProblems(boolean ignoreConsistencyProblems) { this.ignoreConsistencyProblems = ignoreConsistencyProblems; } public void pushReportContext(XmlLoaderReportContext context) { contextStack.addFirst(context); } public XmlLoaderReportContext popReportContext() { return contextStack.removeFirst(); } public XmlLoaderReportContext getReportContext() { return contextStack.isEmpty() ? null : contextStack.getFirst(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy