/* * 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; import org.pentaho.reporting.engine.classic.core.style.ElementStyleSheet; import org.pentaho.reporting.engine.classic.core.style.RootLevelBandDefaultStyleSheet; import java.util.ArrayList; /** * The root-level band is the container that is processed by a report-state. The root-level band processing is atomic - * so either the full band is processed or not processed at all. * * @author Thomas Morgner */ public abstract class AbstractRootLevelBand extends Band implements RootLevelBand { /** * A empty array. (For performance reasons.) */ private static final SubReport[] EMPTY_SUBREPORTS = new SubReport[0]; /** * The list of follow-up root-level sub-reports. */ private ArrayList<SubReport> subReports; /** * Constructs a new band (initially empty). */ protected AbstractRootLevelBand() { } /** * Constructs a new band with the given pagebreak attributes. Pagebreak attributes have no effect on subbands. * * @param pagebreakAfter * defines, whether a pagebreak should be done after that band was printed. * @param pagebreakBefore * defines, whether a pagebreak should be done before that band gets printed. */ protected AbstractRootLevelBand( final boolean pagebreakBefore, final boolean pagebreakAfter ) { super( pagebreakBefore, pagebreakAfter ); } /** * Returns the number of subreports attached to this root level band. * * @return the number of subreports. */ public int getSubReportCount() { if ( subReports == null ) { return 0; } return subReports.size(); } /** * Clones this band and all elements contained in this band. After the cloning the band is no longer connected to a * report definition. * * @return the clone of this band. */ public AbstractRootLevelBand clone() { final AbstractRootLevelBand rootLevelBand = (AbstractRootLevelBand) super.clone(); if ( rootLevelBand.subReports != null ) { rootLevelBand.subReports = (ArrayList<SubReport>) rootLevelBand.subReports.clone(); rootLevelBand.subReports.clear(); for ( int i = 0; i < subReports.size(); i++ ) { final SubReport report = subReports.get( i ); final SubReport clone = (SubReport) report.clone(); clone.setParent( rootLevelBand ); rootLevelBand.subReports.add( clone ); } } return rootLevelBand; } /** * Creates a deep copy of this element and regenerates all instance-ids. * * @return the copy of the element. */ public AbstractRootLevelBand derive( final boolean preserveElementInstanceIds ) { final AbstractRootLevelBand rootLevelBand = (AbstractRootLevelBand) super.derive( preserveElementInstanceIds ); if ( rootLevelBand.subReports != null ) { rootLevelBand.subReports = (ArrayList<SubReport>) rootLevelBand.subReports.clone(); rootLevelBand.subReports.clear(); for ( int i = 0; i < subReports.size(); i++ ) { final SubReport report = subReports.get( i ); final SubReport clone = (SubReport) report.derive( preserveElementInstanceIds ); clone.setParent( rootLevelBand ); rootLevelBand.subReports.add( clone ); } } return rootLevelBand; } /** * Returns the subreport at the given index-position. * * @param index * the index * @return the subreport stored at the given index. * @throws IndexOutOfBoundsException * if there is no such subreport. */ public SubReport getSubReport( final int index ) { if ( subReports == null ) { throw new IndexOutOfBoundsException(); } return subReports.get( index ); } /** * Attaches a new subreport at the end of the list. * * @param index * @param element * the subreport, never null. */ public void addSubReport( final int index, final SubReport element ) { if ( element == null ) { throw new NullPointerException( "Parameter 'report' must not be null" ); } validateLooping( element ); if ( unregisterParent( element ) ) { return; } // add the element, update the childs Parent and the childs stylesheet. if ( subReports == null ) { subReports = new ArrayList<SubReport>(); } subReports.add( index, element ); registerAsChild( element ); notifyNodeChildAdded( element ); } /** * Attaches a new subreport at the end of the list. * * @param element * the subreport, never null. */ public void addSubReport( final SubReport element ) { if ( element == null ) { throw new NullPointerException( "Parameter 'report' must not be null" ); } validateLooping( element ); if ( unregisterParent( element ) ) { return; } // add the element, update the childs Parent and the childs stylesheet. if ( subReports == null ) { subReports = new ArrayList<SubReport>(); } subReports.add( element ); registerAsChild( element ); notifyNodeChildAdded( element ); } /** * Removes the given subreport from the list of attached sub-reports. * * @param e * the subreport to be removed. */ public void removeSubreport( final SubReport e ) { if ( e == null ) { throw new NullPointerException( "Parameter 'report' must not be null" ); } if ( subReports == null ) { return; } if ( e.getParentSection() != this ) { // this is none of my childs, ignore the request ... return; } if ( subReports.contains( e ) == false ) { return; } e.setParent( null ); subReports.remove( e ); notifyNodeChildRemoved( e ); } /** * Returns all sub-reports as array. * * @return the sub-reports as array. */ public SubReport[] getSubReports() { if ( subReports == null ) { return AbstractRootLevelBand.EMPTY_SUBREPORTS; } return subReports.toArray( new SubReport[subReports.size()] ); } public ElementStyleSheet getDefaultStyleSheet() { return RootLevelBandDefaultStyleSheet.getRootLevelBandDefaultStyle(); } }