/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2001 - 2013 Object Refinery Ltd, Pentaho Corporation and Contributors.. All rights reserved. */ package org.pentaho.reporting.engine.classic.core.states; import org.pentaho.reporting.engine.classic.core.AbstractReportDefinition; import org.pentaho.reporting.engine.classic.core.InvalidReportStateException; import org.pentaho.reporting.engine.classic.core.MasterReport; import org.pentaho.reporting.engine.classic.core.ParameterMapping; import org.pentaho.reporting.engine.classic.core.ReportEnvironment; import org.pentaho.reporting.engine.classic.core.ReportPreProcessor; import org.pentaho.reporting.engine.classic.core.ReportProcessingException; import org.pentaho.reporting.engine.classic.core.SubReport; import org.pentaho.reporting.engine.classic.core.function.Expression; import org.pentaho.reporting.engine.classic.core.function.StructureFunction; import org.pentaho.reporting.engine.classic.core.metadata.ReportPreProcessorMetaData; import org.pentaho.reporting.engine.classic.core.metadata.ReportPreProcessorRegistry; import org.pentaho.reporting.engine.classic.core.parameters.DefaultParameterContext; import org.pentaho.reporting.engine.classic.core.parameters.ReportParameterDefinition; import org.pentaho.reporting.engine.classic.core.parameters.ReportParameterValidator; import org.pentaho.reporting.engine.classic.core.parameters.ValidationResult; import org.pentaho.reporting.engine.classic.core.states.datarow.DefaultFlowController; import org.pentaho.reporting.engine.classic.core.util.IntegerCache; import org.pentaho.reporting.engine.classic.core.util.ReportParameterValues; import org.pentaho.reporting.libraries.base.config.Configuration; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.Date; import java.util.HashSet; /** * Creation-Date: Dec 14, 2006, 7:59:39 PM * * @author Thomas Morgner */ public class StateUtilities { /** * A comparator for levels in descending order. */ public static final class DescendingComparator<T extends Comparable> implements Comparator<T>, Serializable { /** * Default constructor. */ public DescendingComparator() { } /** * Compares its two arguments for order. Returns a negative integer, zero, or a positive integer as the first * argument is less than, equal to, or greater than the second. * <p> * * @param c1 * the first object to be compared. * @param c2 * the second object to be compared. * @return a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater * than the second. * @throws ClassCastException * if the arguments' types prevent them from being compared by this Comparator. */ public int compare( final T c1, final T c2 ) { // noinspection unchecked return -1 * c1.compareTo( c2 ); } } private StateUtilities() { } public static boolean computeLevels( final DefaultFlowController report, final LayoutProcess lp, final HashSet<Integer> levels ) { if ( report == null ) { throw new NullPointerException(); } if ( lp == null ) { throw new NullPointerException(); } if ( levels == null ) { throw new NullPointerException(); } boolean retval = false; final StructureFunction[] collectionFunctions = lp.getCollectionFunctions(); for ( int i = 0; i < collectionFunctions.length; i++ ) { final StructureFunction function = collectionFunctions[i]; if ( function.getDependencyLevel() == LayoutProcess.LEVEL_STRUCTURAL_PREPROCESSING ) { // this indicates a structural-preprocessor function, like the CrosstabNormalizer. They do not // take part in the ordinary processing. continue; } final Integer level = IntegerCache.getInteger( function.getDependencyLevel() ); levels.add( level ); if ( level != LayoutProcess.LEVEL_PAGINATE ) { retval = true; } } levels.add( IntegerCache.getInteger( LayoutProcess.LEVEL_PAGINATE ) ); final Expression[] expressions = report.getMasterRow().getExpressionDataRow().getExpressions(); for ( int i = 0; i < expressions.length; i++ ) { final Expression expression = expressions[i]; final Integer level = IntegerCache.getInteger( expression.getDependencyLevel() ); levels.add( level ); if ( level != LayoutProcess.LEVEL_PAGINATE ) { retval = true; } } return retval; } public static ValidationResult validate( final MasterReport report, final ValidationResult result ) throws ReportProcessingException { final ReportParameterDefinition parameters = report.getParameterDefinition(); final DefaultParameterContext parameterContext = new DefaultParameterContext( report ); try { final ReportParameterValidator reportParameterValidator = parameters.getValidator(); return reportParameterValidator.validate( result, parameters, parameterContext ); } finally { parameterContext.close(); } } /** * Computes the parameter value set for a given report. Note that this method ignores the validation result, so if the * specified parameter values are wrong you may end up with a bunch of default values. * * @param report * @return * @throws ReportProcessingException */ public static ReportParameterValues computeParameterValueSet( final MasterReport report ) throws ReportProcessingException { final ReportParameterDefinition parameters = report.getParameterDefinition(); final DefaultParameterContext parameterContext = new DefaultParameterContext( report ); final ReportParameterValues parameterValues; try { final ReportParameterValidator reportParameterValidator = parameters.getValidator(); final ValidationResult validationResult = reportParameterValidator.validate( new ValidationResult(), parameters, parameterContext ); parameterValues = validationResult.getParameterValues(); return computeParameterValueSet( report, parameterValues ); } finally { parameterContext.close(); } } public static ReportParameterValues computeParameterValueSet( final MasterReport report, final ReportParameterValues parameterValues ) throws ReportProcessingException { final ReportParameterValues retval = new ReportParameterValues(); retval.putAll( parameterValues ); final Configuration config = report.getConfiguration(); if ( "true".equals( config .getConfigProperty( "org.pentaho.reporting.engine.classic.core.legacy.ReportNameAsProperty" ) ) ) { retval.put( "report.name", report.getName() ); } final ReportEnvironment reportEnvironment = report.getReportEnvironment(); final Object property = reportEnvironment.getEnvironmentProperty( "::internal::report.date" ); if ( property instanceof Date == false ) { retval.put( MasterReport.REPORT_DATE_PROPERTY, new Date() ); } else { retval.put( MasterReport.REPORT_DATE_PROPERTY, property ); } return retval; } public static ReportParameterValues computeParameterValueSet( final SubReport report ) { // todo: Grab parent reports and compute the dataschema for them, so that the parameters here // get a meaning. final ReportParameterValues retval = new ReportParameterValues(); // for the sake of backward compatiblity .. retval.put( MasterReport.REPORT_DATE_PROPERTY, new Date() ); final ParameterMapping[] reportParameterValues = report.getInputMappings(); for ( int i = 0; i < reportParameterValues.length; i++ ) { final ParameterMapping mapping = reportParameterValues[i]; if ( "*".equals( mapping.getName() ) ) { continue; } retval.put( mapping.getName(), null ); } return retval; } public static ReportPreProcessor[] getAllPreProcessors( final AbstractReportDefinition reportDefinition, final boolean designTime ) { final ReportPreProcessorRegistry registry = ReportPreProcessorRegistry.getInstance(); final ReportPreProcessor[] processors = reportDefinition.getPreProcessors(); final ArrayList<ReportPreProcessor> preProcessors = new ArrayList<ReportPreProcessor>(); for ( int i = 0; i < processors.length; i++ ) { final ReportPreProcessor o = processors[i]; if ( o == null ) { continue; } final String identifier = o.getClass().getName(); if ( registry.isReportPreProcessorRegistered( identifier ) ) { final ReportPreProcessorMetaData metaData = registry.getReportPreProcessorMetaData( identifier ); if ( designTime && metaData.isExecuteInDesignMode() == false ) { continue; } } preProcessors.add( o ); } final ReportPreProcessorMetaData[] allProcessors = registry.getAllReportPreProcessorMetaDatas(); Arrays.sort( allProcessors, new PreProcessorComparator() ); for ( int i = 0; i < allProcessors.length; i++ ) { final ReportPreProcessorMetaData processor = allProcessors[i]; if ( designTime && processor.isExecuteInDesignMode() == false ) { continue; } if ( processor.isAutoProcessor() ) { try { preProcessors.add( processor.create() ); } catch ( InstantiationException e ) { throw new InvalidReportStateException( "Failed to instantiate automatic-report-pre-processor", e ); } } } return preProcessors.toArray( new ReportPreProcessor[preProcessors.size()] ); } private static class PreProcessorComparator implements Comparator<ReportPreProcessorMetaData> { public int compare( final ReportPreProcessorMetaData o1, final ReportPreProcessorMetaData o2 ) { return Integer.valueOf( o1.getExecutionPriority() ).compareTo( o2.getExecutionPriority() ); } } }