/* * 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.InvalidReportStateException; import org.pentaho.reporting.engine.classic.core.ReportProcessingException; import org.pentaho.reporting.engine.classic.core.event.ReportEvent; import org.pentaho.reporting.engine.classic.core.function.ExpressionRuntime; import org.pentaho.reporting.engine.classic.core.function.OutputFunction; import org.pentaho.reporting.engine.classic.core.function.StructureFunction; import org.pentaho.reporting.engine.classic.core.states.datarow.ExpressionEventHelper; import org.pentaho.reporting.engine.classic.core.states.datarow.InlineDataRowRuntime; import org.pentaho.reporting.engine.classic.core.states.datarow.LevelStorage; import org.pentaho.reporting.engine.classic.core.states.datarow.LevelStorageBackend; import org.pentaho.reporting.engine.classic.core.util.InstanceID; public class SubLayoutProcess extends ExpressionEventHelper implements LayoutProcess { private InlineDataRowRuntime inlineDataRowRuntime; private StructureFunction[] collectionFunctions; private boolean hasPageListener; private LayoutProcess parent; private LevelStorageBackend[] levelData; private InstanceID reportDefinitionId; public SubLayoutProcess( final LayoutProcess parent, final StructureFunction[] structureFunctions, final InstanceID reportDefinitionId ) { if ( structureFunctions == null ) { throw new NullPointerException(); } if ( parent == null ) { throw new NullPointerException(); } this.reportDefinitionId = reportDefinitionId; this.parent = parent; this.collectionFunctions = structureFunctions.clone(); this.reinit(); } public LayoutProcess getParent() { return parent; } private void reinit() { this.levelData = LevelStorageBackend.revalidate( this.collectionFunctions, collectionFunctions.length, false ); this.hasPageListener = parent.isPageListener(); for ( int i = 0; i < levelData.length; i++ ) { final LevelStorageBackend backend = levelData[i]; if ( backend.hasPageEventListeners() ) { this.hasPageListener = true; } } } public boolean isPageListener() { return hasPageListener; } public OutputFunction getOutputFunction() { return parent.getOutputFunction(); } public void restart( final ReportState state ) throws ReportProcessingException { parent.restart( state ); } public StructureFunction[] getCollectionFunctions() { return collectionFunctions.clone(); } protected int getRunLevelCount() { return levelData.length; } protected LevelStorage getRunLevel( final int index ) { final LevelStorageBackend backend = levelData[index]; return LevelStorageBackend.getLevelStorage( backend, collectionFunctions ); } protected ExpressionRuntime getRuntime() { return inlineDataRowRuntime; } public LayoutProcess deriveForStorage() { try { final SubLayoutProcess lp = (SubLayoutProcess) super.clone(); if ( parent != null ) { lp.parent = parent.deriveForStorage(); } lp.inlineDataRowRuntime = null; lp.collectionFunctions = collectionFunctions.clone(); for ( int i = 0; i < collectionFunctions.length; i++ ) { collectionFunctions[i] = (StructureFunction) collectionFunctions[i].clone(); } return lp; } catch ( final CloneNotSupportedException e ) { throw new IllegalStateException(); } } public LayoutProcess deriveForPagebreak() { try { final SubLayoutProcess lp = (SubLayoutProcess) super.clone(); if ( parent != null ) { lp.parent = parent.deriveForPagebreak(); } lp.inlineDataRowRuntime = null; lp.collectionFunctions = collectionFunctions.clone(); lp.inlineDataRowRuntime = null; for ( int i = 0; i < collectionFunctions.length; i++ ) { collectionFunctions[i] = (StructureFunction) collectionFunctions[i].clone(); } return lp; } catch ( final CloneNotSupportedException e ) { throw new IllegalStateException(); } } public Object clone() { try { final SubLayoutProcess lp = (SubLayoutProcess) super.clone(); if ( parent != null ) { lp.parent = (LayoutProcess) parent.clone(); } lp.inlineDataRowRuntime = null; lp.collectionFunctions = collectionFunctions.clone(); lp.inlineDataRowRuntime = null; for ( int i = 0; i < collectionFunctions.length; i++ ) { collectionFunctions[i] = (StructureFunction) collectionFunctions[i].clone(); } return lp; } catch ( final CloneNotSupportedException cne ) { throw new IllegalStateException( cne ); } } public void fireReportEvent( final ReportEvent event ) { final InstanceID objectID = event.getReport().getObjectID(); if ( objectID == reportDefinitionId ) { if ( inlineDataRowRuntime == null ) { inlineDataRowRuntime = new InlineDataRowRuntime(); } final ReportState state = inlineDataRowRuntime.getState(); inlineDataRowRuntime.setState( event.getState() ); try { super.fireReportEvent( event ); } catch ( final InvalidReportStateException exception ) { throw exception; } catch ( final Throwable t ) { throw new InvalidReportStateException( "Failed to fire report event for sub-layout-process", t ); } finally { inlineDataRowRuntime.setState( state ); } } if ( parent != null ) { parent.fireReportEvent( event ); } } }