001: /**
002: * ===========================================
003: * JFreeReport : a free Java reporting library
004: * ===========================================
005: *
006: * Project Info: http://reporting.pentaho.org/
007: *
008: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
009: *
010: * This library is free software; you can redistribute it and/or modify it under the terms
011: * of the GNU Lesser General Public License as published by the Free Software Foundation;
012: * either version 2.1 of the License, or (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
015: * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016: * See the GNU Lesser General Public License for more details.
017: *
018: * You should have received a copy of the GNU Lesser General Public License along with this
019: * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020: * Boston, MA 02111-1307, USA.
021: *
022: * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
023: * in the United States and other countries.]
024: *
025: * ------------
026: * JoinEndGroupHandler.java
027: * ------------
028: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
029: */package org.jfree.report.states.process;
030:
031: import org.jfree.report.Group;
032: import org.jfree.report.ReportProcessingException;
033: import org.jfree.report.event.ReportEvent;
034: import org.jfree.report.states.datarow.DefaultFlowController;
035:
036: /**
037: * This delays the actual test on whether the current detail-group should be finished until the subreports have been
038: * processed. The subreports can influence this test by declaring output-parameters.
039: *
040: * @author Thomas Morgner
041: */
042: public class JoinEndGroupHandler implements AdvanceHandler {
043: public static final AdvanceHandler HANDLER = new JoinEndGroupHandler();
044:
045: private JoinEndGroupHandler() {
046: }
047:
048: public int getEventCode() {
049: return ReportEvent.GROUP_FINISHED
050: | ProcessState.ARTIFICIAL_EVENT_CODE;
051: }
052:
053: public ProcessState advance(final ProcessState state)
054: throws ReportProcessingException {
055: return state.deriveForAdvance();
056: }
057:
058: public ProcessState commit(final ProcessState next)
059: throws ReportProcessingException {
060: next.setCurrentGroupIndex(next.getCurrentGroupIndex() - 1);
061: final DefaultFlowController fc = next.getFlowController();
062: final boolean advanceRequested = fc.isAdvanceRequested();
063: final boolean advanceable = fc.getMasterRow().isAdvanceable();
064: if (isRootGroup(next)) {
065: // there is no parent group. So if there is more data, print the next header for this group,
066: // else print the report-footer and finish the report processing.
067: if (advanceRequested && advanceable) {
068: final DefaultFlowController cfc = fc.performCommit();
069: next.setFlowController(cfc);
070: next.setAdvanceHandler(BeginGroupHandler.HANDLER);
071: return next;
072: } else {
073: next.setAdvanceHandler(ReportFooterHandler.HANDLER);
074: return next;
075: }
076: }
077:
078: if (advanceRequested == false || advanceable == false) {
079: // This happens for empty - reports. Empty-Reports are never advanceable, therefore we can
080: // reach an non-advance state where inner group-footers are printed.
081: next.setAdvanceHandler(EndGroupHandler.HANDLER);
082: return next;
083: }
084:
085: // This group is not the outer-most group ..
086: final Group group = next.getReport().getGroup(
087: next.getCurrentGroupIndex());
088: final DefaultFlowController cfc = fc.performCommit();
089: if (ProcessState.isLastItemInGroup(group, fc.getMasterRow(),
090: cfc.getMasterRow())) {
091: // continue with an other EndGroup-State ...
092: next.setAdvanceHandler(EndGroupHandler.HANDLER);
093: return next;
094: } else {
095: // The parent group is not finished, so finalize the createRollbackInformation.
096: // more data in parent group, print the next header
097: next.setFlowController(cfc);
098: next.setAdvanceHandler(BeginGroupHandler.HANDLER);
099: return next;
100: }
101: }
102:
103: public boolean isFinish() {
104: return false;
105: }
106:
107: /**
108: * Checks, whether there are more groups active.
109: *
110: * @return true if this is the last (outer-most) group.
111: */
112: private boolean isRootGroup(final ProcessState state) {
113: return state.getCurrentGroupIndex() == ProcessState.BEFORE_FIRST_GROUP;
114: }
115:
116: }
|