Source Code Cross Referenced for DefaultOutputFunction.java in  » Report » pentaho-report » org » jfree » report » layout » output » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Report » pentaho report » org.jfree.report.layout.output 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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:         * DefaultOutputFunction.java
027:         * ------------
028:         * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
029:         */package org.jfree.report.layout.output;
030:
031:        import java.util.ArrayList;
032:
033:        import org.jfree.report.Band;
034:        import org.jfree.report.Group;
035:        import org.jfree.report.GroupFooter;
036:        import org.jfree.report.GroupHeader;
037:        import org.jfree.report.PageFooter;
038:        import org.jfree.report.PageHeader;
039:        import org.jfree.report.ReportDefinition;
040:        import org.jfree.report.ReportProcessingException;
041:        import org.jfree.report.Watermark;
042:        import org.jfree.report.event.PageEventListener;
043:        import org.jfree.report.event.ReportEvent;
044:        import org.jfree.report.function.AbstractFunction;
045:        import org.jfree.report.function.Expression;
046:        import org.jfree.report.function.ExpressionRuntime;
047:        import org.jfree.report.function.FunctionProcessingException;
048:        import org.jfree.report.function.OutputFunction;
049:        import org.jfree.report.layout.Renderer;
050:        import org.jfree.report.states.ReportState;
051:        import org.jfree.report.states.datarow.DefaultFlowController;
052:        import org.jfree.report.states.datarow.GlobalMasterRow;
053:        import org.jfree.report.states.datarow.ReportDataRow;
054:        import org.jfree.report.style.BandStyleKeys;
055:        import org.jfree.report.style.ElementStyleSheet;
056:        import org.jfree.util.Log;
057:
058:        /**
059:         * Creation-Date: 08.04.2007, 16:22:18
060:         *
061:         * @author Thomas Morgner
062:         */
063:        public class DefaultOutputFunction extends AbstractFunction implements 
064:                OutputFunction, PageEventListener {
065:            public static final String HANDLE_PENDING_GROUP_FOOTER_KEY = "org.jfree.report.modules.output.support.pagelayout.HandlePendingGroupFooter";
066:
067:            private static final LayouterLevel[] EMPTY_LAYOUTER_LEVEL = new LayouterLevel[0];
068:
069:            private ReportEvent currentEvent;
070:            private Renderer renderer;
071:            private boolean lastPagebreak;
072:            private DefaultLayoutPagebreakHandler pagebreakHandler;
073:            private boolean groupStartPending;
074:
075:            /**
076:             * Creates an unnamed function. Make sure the name of the function is set using {@link #setName} before the function
077:             * is added to the report's function collection.
078:             */
079:            public DefaultOutputFunction() {
080:                pagebreakHandler = new DefaultLayoutPagebreakHandler();
081:            }
082:
083:            /**
084:             * Return the current expression value. <P> The value depends (obviously) on the expression implementation.
085:             *
086:             * @return the value of the function.
087:             */
088:            public Object getValue() {
089:                return null;
090:            }
091:
092:            public void reportInitialized(final ReportEvent event) {
093:                // there can be no pending page-start, we just have started ...
094:
095:                // activating this state after the page has ended is invalid.
096:                setCurrentEvent(event);
097:                try {
098:                    // activating this state after the page has ended is invalid.
099:                    final ReportDefinition report = event.getReport();
100:                    if (event.isDeepTraversing() == false) {
101:                        renderer.startReport(report.getPageDefinition());
102:
103:                        final ReportState reportState = event.getState();
104:                        final ExpressionRuntime runtime = getRuntime();
105:                        reportState.setCurrentPage(1);
106:                        reportState.firePageStartedEvent(reportState
107:                                .getEventCode());
108:                        // restore the current event, as the page-started event will clear it ..
109:                        setRuntime(runtime);
110:                        setCurrentEvent(event);
111:                    }
112:                } catch (FunctionProcessingException fe) {
113:                    throw fe;
114:                } catch (Exception e) {
115:                    throw new FunctionProcessingException(
116:                            "ReportInitialized failed", e);
117:                } finally {
118:                    clearCurrentEvent();
119:                }
120:            }
121:
122:            /**
123:             * Receives notification that the report has started. Also invokes the start of the first page ... <P> Layout and draw
124:             * the report header after the PageStartEvent was fired.
125:             *
126:             * @param event the event.
127:             */
128:            public void reportStarted(final ReportEvent event) {
129:
130:                // activating this state after the page has ended is invalid.
131:                setCurrentEvent(event);
132:                try {
133:                    // activating this state after the page has ended is invalid.
134:                    updateFooterArea(event);
135:
136:                    renderer.startSection(Renderer.TYPE_NORMALFLOW);
137:                    final ReportDefinition report = event.getReport();
138:                    print(getRuntime(), report.getReportHeader());
139:                    renderer.endSection();
140:                } catch (FunctionProcessingException fe) {
141:                    throw fe;
142:                } catch (Exception e) {
143:                    throw new FunctionProcessingException(
144:                            "ReportStarted failed", e);
145:                } finally {
146:                    clearCurrentEvent();
147:                }
148:            }
149:
150:            /**
151:             * Receives notification that a group has started. <P> Prints the GroupHeader
152:             *
153:             * @param event Information about the event.
154:             */
155:            public void groupStarted(final ReportEvent event) {
156:                groupStartPending = true;
157:                clearPendingPageStart(event.getState());
158:                groupStartPending = false;
159:
160:                // activating this state after the page has ended is invalid.
161:                setCurrentEvent(event);
162:                try {
163:                    updateFooterArea(event);
164:
165:                    final int gidx = event.getState().getCurrentGroupIndex();
166:                    final Group g = event.getReport().getGroup(gidx);
167:                    final Band b = g.getHeader();
168:                    renderer.startGroup(false);
169:                    renderer.startSection(Renderer.TYPE_NORMALFLOW);
170:                    print(getRuntime(), b);
171:                    renderer.endSection();
172:                } catch (FunctionProcessingException fe) {
173:                    throw fe;
174:                } catch (Exception e) {
175:                    throw new FunctionProcessingException(
176:                            "GroupStarted failed", e);
177:                } finally {
178:                    clearCurrentEvent();
179:                }
180:            }
181:
182:            /**
183:             * Receives notification that a group of item bands is about to be processed. <P> The next events will be
184:             * itemsAdvanced events until the itemsFinished event is raised.
185:             *
186:             * @param event The event.
187:             */
188:            public void itemsStarted(final ReportEvent event) {
189:                clearPendingPageStart(event.getState());
190:
191:                setCurrentEvent(event);
192:                //    effectiveGroupIndex += 1;
193:                //    Log.debug ("Items-Started: " + effectiveGroupIndex + " SR: " + event.isDeepTraversing() + " GI:" + event.getState().getCurrentGroupIndex());
194:
195:                try {
196:                    // activating this state after the page has ended is invalid.
197:                    final int numberOfRows = event.getState().getNumberOfRows();
198:                    if (numberOfRows == 0) {
199:                        // ups, we have no data. Lets signal that ...
200:                        try {
201:                            updateFooterArea(event);
202:                            renderer.startSection(Renderer.TYPE_NORMALFLOW);
203:                            print(getRuntime(), event.getReport()
204:                                    .getNoDataBand());
205:                            renderer.endSection();
206:                        } catch (FunctionProcessingException fe) {
207:                            throw fe;
208:                        } catch (Exception e) {
209:                            throw new FunctionProcessingException(
210:                                    "ItemsStarted failed", e);
211:                        }
212:                        // there will be no item-band printed.
213:                    }
214:                } finally {
215:                    clearCurrentEvent();
216:                }
217:            }
218:
219:            /**
220:             * Receives notification that a row of data is being processed. <P> prints the ItemBand.
221:             *
222:             * @param event Information about the event.
223:             */
224:            public void itemsAdvanced(final ReportEvent event) {
225:                clearPendingPageStart(event.getState());
226:
227:                setCurrentEvent(event);
228:                try {
229:                    updateFooterArea(event);
230:
231:                    renderer.startSection(Renderer.TYPE_NORMALFLOW);
232:                    print(getRuntime(), event.getReport().getItemBand());
233:                    renderer.endSection();
234:                } catch (FunctionProcessingException fe) {
235:                    throw fe;
236:                } catch (Exception e) {
237:                    throw new FunctionProcessingException(
238:                            "ItemsAdvanced failed", e);
239:                } finally {
240:                    clearCurrentEvent();
241:                }
242:            }
243:
244:            /**
245:             * Receives notification that a group has finished. <P> Prints the GroupFooter.
246:             *
247:             * @param event Information about the event.
248:             */
249:            public void groupFinished(final ReportEvent event) {
250:                clearPendingPageStart(event.getState());
251:
252:                setCurrentEvent(event);
253:                try {
254:                    updateFooterArea(event);
255:
256:                    final int gidx = event.getState().getCurrentGroupIndex();
257:                    final Group g = event.getReport().getGroup(gidx);
258:                    final Band b = g.getFooter();
259:
260:                    renderer.startSection(Renderer.TYPE_NORMALFLOW);
261:                    print(getRuntime(), b);
262:                    renderer.endSection();
263:                    renderer.endGroup();
264:
265:                    //      effectiveGroupIndex -= 1;
266:                    //      Log.debug ("Group-Finished: " + effectiveGroupIndex + " SR: " + event.isDeepTraversing() + " GI:" + event.getState().getCurrentGroupIndex());
267:                } catch (FunctionProcessingException fe) {
268:                    throw fe;
269:                } catch (Exception e) {
270:                    throw new FunctionProcessingException(
271:                            "GroupFinished failed", e);
272:                } finally {
273:                    clearCurrentEvent();
274:                }
275:            }
276:
277:            /**
278:             * Receives notification that the report has finished. <P> Prints the ReportFooter and forces the last pagebreak.
279:             *
280:             * @param event Information about the event.
281:             */
282:            public void reportFinished(final ReportEvent event) {
283:                clearPendingPageStart(event.getState());
284:
285:                setCurrentEvent(event);
286:                try {
287:                    // a deep traversing event means, we are in a subreport ..
288:
289:                    // force that this last pagebreak ... (This is an indicator for the
290:                    // pagefooter's print-on-last-page) This is highly unclean and may or
291:                    // may not work ..
292:                    final Band b = event.getReport().getReportFooter();
293:                    renderer.startSection(Renderer.TYPE_NORMALFLOW);
294:                    print(getRuntime(), b);
295:                    renderer.endSection();
296:
297:                    //      if (effectiveGroupIndex != -1)
298:                    //      {
299:                    //         throw new IllegalStateException("Assertation failed: Group index is invalid");
300:                    //      }
301:                    //      Log.debug ("Report-Finished: " + effectiveGroupIndex + " SR: " + event.isDeepTraversing() + " GI:" + event.getState().getCurrentGroupIndex());
302:                    lastPagebreak = true;
303:                    updateFooterArea(event);
304:                } catch (FunctionProcessingException fe) {
305:                    throw fe;
306:                } catch (Exception e) {
307:                    throw new FunctionProcessingException(
308:                            "ReportFinished failed", e);
309:                } finally {
310:                    clearCurrentEvent();
311:                }
312:            }
313:
314:            /**
315:             * Receives notification that report generation has completed, the report footer was printed, no more output is done.
316:             * This is a helper event to shut down the output service.
317:             *
318:             * @param event The event.
319:             */
320:            public void reportDone(final ReportEvent event) {
321:                if (event.isDeepTraversing() == false) {
322:                    final ReportState state = event.getState();
323:                    state.firePageFinishedEvent();
324:                    renderer.endReport();
325:                }
326:            }
327:
328:            protected static LayouterLevel[] collectSubReportStates(
329:                    final ReportEvent event, final ExpressionRuntime parent) {
330:                final ReportState state = event.getState();
331:                ReportState parentState = state.getParentSubReportState();
332:                if (parentState == null) {
333:                    return EMPTY_LAYOUTER_LEVEL;
334:                }
335:                GlobalMasterRow dataRow = state.getFlowController()
336:                        .getMasterRow();
337:                dataRow = dataRow.getParentDataRow();
338:
339:                final ArrayList stack = new ArrayList();
340:                while (parentState != null) {
341:                    final ReportState realState = parentState;
342:                    final DefaultFlowController flowController = realState
343:                            .getFlowController();
344:                    final GlobalMasterRow masterRow = flowController
345:                            .getMasterRow();
346:                    final ReportDataRow reportDataRow = masterRow
347:                            .getReportDataRow();
348:                    final LayoutExpressionRuntime runtime = new LayoutExpressionRuntime(
349:                            dataRow.getGlobalView(), realState
350:                                    .getCurrentDataItem(), reportDataRow
351:                                    .getReportData(), parent
352:                                    .getProcessingContext());
353:                    stack.add(new LayouterLevel(realState.getReport(),
354:                            realState.getCurrentGroupIndex(), runtime));
355:                    parentState = parentState.getParentSubReportState();
356:                }
357:                return (LayouterLevel[]) stack.toArray(new LayouterLevel[stack
358:                        .size()]);
359:            }
360:
361:            private boolean isPageHeaderPrinting(final Band b,
362:                    final ReportEvent event) {
363:                final boolean displayOnFirstPage = b.getStyle()
364:                        .getBooleanStyleProperty(
365:                                BandStyleKeys.DISPLAY_ON_FIRSTPAGE);
366:                if ((event.getState().getCurrentPage() == 1)
367:                        && (displayOnFirstPage == false)) {
368:                    return false;
369:                }
370:
371:                final boolean displayOnLastPage = b.getStyle()
372:                        .getBooleanStyleProperty(
373:                                BandStyleKeys.DISPLAY_ON_LASTPAGE);
374:                if (isLastPagebreak() && (displayOnLastPage == false)) {
375:                    return false;
376:                }
377:
378:                return true;
379:            }
380:
381:            protected boolean isLastPagebreak() {
382:                return lastPagebreak;
383:            }
384:
385:            /**
386:             * Receives notification that a page has started. <P> This prints the PageHeader. If this is the first page, the
387:             * header is not printed if the pageheader style-flag DISPLAY_ON_FIRSTPAGE is set to false. If this event is known to
388:             * be the last pageStarted event, the DISPLAY_ON_LASTPAGE is evaluated and the header is printed only if this flag is
389:             * set to TRUE.
390:             * <p/>
391:             * If there is an active repeating GroupHeader, print the last one. The GroupHeader is searched for the current group
392:             * and all parent groups, starting at the current group and ascending to the parents. The first goupheader that has
393:             * the StyleFlag REPEAT_HEADER set to TRUE is printed.
394:             * <p/>
395:             * The PageHeader and the repeating GroupHeader are spooled until the first real content is printed. This way, the
396:             * LogicalPage remains empty until an other band is printed.
397:             *
398:             * @param event Information about the event.
399:             */
400:            public void pageStarted(final ReportEvent event) {
401:                // activating this state after the page has ended is invalid.
402:                setCurrentEvent(event);
403:                try {
404:                    updateHeaderArea(event);
405:                } catch (FunctionProcessingException fe) {
406:                    throw fe;
407:                } catch (Exception e) {
408:                    throw new FunctionProcessingException("PageStarted failed",
409:                            e);
410:                } finally {
411:                    clearCurrentEvent();
412:                }
413:            }
414:
415:            protected void updateHeaderArea(final ReportEvent event)
416:                    throws ReportProcessingException {
417:                final ReportDefinition report = event.getReport();
418:                LayouterLevel[] levels = null;
419:                final OutputProcessorMetaData metaData = renderer
420:                        .getOutputProcessor().getMetaData();
421:                if (metaData
422:                        .isFeatureSupported(OutputProcessorFeature.WATERMARK_SECTION)) {
423:                    renderer.startSection(Renderer.TYPE_WATERMARK);
424:                    // a new page has started, so reset the cursor ...
425:                    // Check the subreport for sticky watermarks ...
426:                    levels = collectSubReportStates(event, getRuntime());
427:
428:                    for (int i = levels.length - 1; i >= 0; i -= 1) {
429:                        final LayouterLevel level = levels[i];
430:                        final ReportDefinition def = level
431:                                .getReportDefinition();
432:                        final Watermark watermark = def.getWatermark();
433:                        if (watermark.isSticky()
434:                                && isPageHeaderPrinting(watermark, event)) {
435:                            print(level.getRuntime(), watermark);
436:                        }
437:                    }
438:
439:                    // and finally print the watermark of the subreport itself ..
440:                    final Band watermark = report.getWatermark();
441:                    if (isPageHeaderPrinting(watermark, event)) {
442:                        print(getRuntime(), watermark);
443:                    }
444:                    renderer.endSection();
445:                }
446:
447:                if (metaData
448:                        .isFeatureSupported(OutputProcessorFeature.PAGE_SECTIONS)) {
449:                    renderer.startSection(Renderer.TYPE_HEADER);
450:                    // after printing the watermark, we are still at the top of the page.
451:
452:                    if (levels == null) {
453:                        levels = collectSubReportStates(event, getRuntime());
454:                    }
455:
456:                    for (int i = levels.length - 1; i >= 0; i -= 1) {
457:                        // This is propably wrong (or at least incomplete) in case a subreport uses header or footer which should
458:                        // not be printed with the report-footer or header ..
459:                        final LayouterLevel level = levels[i];
460:                        final ReportDefinition def = level
461:                                .getReportDefinition();
462:                        final PageHeader header = def.getPageHeader();
463:                        if (header.isSticky()
464:                                && isPageHeaderPrinting(header, event)) {
465:                            print(level.getRuntime(), header);
466:                        }
467:                    }
468:
469:                    // and print the ordinary page header ..
470:                    final Band b = report.getPageHeader();
471:                    if (isPageHeaderPrinting(b, event)) {
472:                        print(getRuntime(), b);
473:                    }
474:
475:                    /**
476:                     * Repeating group header are only printed while ItemElements are
477:                     * processed.
478:                     *
479:                     * Dive into the pending group to print the group header ...
480:                     */
481:
482:                    for (int i = levels.length - 1; i >= 0; i -= 1) {
483:                        final LayouterLevel level = levels[i];
484:                        final ReportDefinition def = level
485:                                .getReportDefinition();
486:
487:                        for (int gidx = 0; gidx < level.getGroupIndex(); gidx++) {
488:                            final Group g = def.getGroup(gidx);
489:                            final GroupHeader header = g.getHeader();
490:                            if (header.isSticky()
491:                                    && header
492:                                            .getStyle()
493:                                            .getBooleanStyleProperty(
494:                                                    BandStyleKeys.REPEAT_HEADER)) {
495:                                print(level.getRuntime(), header);
496:                            }
497:                        }
498:                    }
499:
500:                    final int groupsPrinted;
501:                    if (groupStartPending) {
502:                        groupsPrinted = event.getState().getCurrentGroupIndex() - 1;
503:                    } else {
504:                        groupsPrinted = event.getState().getCurrentGroupIndex();
505:                    }
506:
507:                    for (int gidx = 0; gidx <= groupsPrinted; gidx++) {
508:                        final Group g = report.getGroup(gidx);
509:                        final GroupHeader header = g.getHeader();
510:                        if (header.getStyle().getBooleanStyleProperty(
511:                                BandStyleKeys.REPEAT_HEADER)) {
512:                            print(getRuntime(), header);
513:                        }
514:                    }
515:
516:                    renderer.endSection();
517:                }
518:                // mark the current position to calculate the maxBand-Height
519:            }
520:
521:            /**
522:             * Receives notification that a page has ended.
523:             * <p/>
524:             * This prints the PageFooter. If this is the first page, the footer is not printed if the pagefooter style-flag
525:             * DISPLAY_ON_FIRSTPAGE is set to false. If this event is known to be the last pageFinished event, the
526:             * DISPLAY_ON_LASTPAGE is evaluated and the footer is printed only if this flag is set to TRUE.
527:             * <p/>
528:             *
529:             * @param event the report event.
530:             */
531:            public void pageFinished(final ReportEvent event) {
532:                setCurrentEvent(event);
533:                try {
534:                    updateFooterArea(event);
535:                } catch (FunctionProcessingException fe) {
536:                    throw fe;
537:                } catch (Exception e) {
538:                    throw new FunctionProcessingException(
539:                            "PageFinished failed", e);
540:                } finally {
541:                    clearCurrentEvent();
542:                }
543:            }
544:
545:            protected void updateFooterArea(final ReportEvent event)
546:                    throws ReportProcessingException {
547:                final OutputProcessorMetaData metaData = renderer
548:                        .getOutputProcessor().getMetaData();
549:                if (metaData
550:                        .isFeatureSupported(OutputProcessorFeature.PAGE_SECTIONS) == false) {
551:                    return;
552:                }
553:
554:                renderer.startSection(Renderer.TYPE_FOOTER);
555:
556:                final ReportDefinition report = event.getReport();
557:                /**
558:                 * Repeating group header are only printed while ItemElements are
559:                 * processed.
560:                 */
561:                final int groupsPrinted = event.getState()
562:                        .getCurrentGroupIndex();
563:                for (int gidx = groupsPrinted; gidx >= 0; gidx -= 1) {
564:                    final Group g = report.getGroup(gidx);
565:                    final GroupFooter footer = g.getFooter();
566:                    if (footer.getStyle().getBooleanStyleProperty(
567:                            BandStyleKeys.REPEAT_HEADER)) {
568:                        print(getRuntime(), footer);
569:                    }
570:                }
571:
572:                final LayouterLevel[] levels = collectSubReportStates(event,
573:                        getRuntime());
574:                final int levelCount = levels.length;
575:                for (int i = 0; i < levelCount; i++) {
576:                    final LayouterLevel level = levels[i];
577:                    final ReportDefinition def = level.getReportDefinition();
578:                    for (int gidx = level.getGroupIndex(); gidx >= 0; gidx -= 1) {
579:                        final Group g = def.getGroup(gidx);
580:                        final GroupFooter footer = g.getFooter();
581:                        final ElementStyleSheet groupFooterStyle = footer
582:                                .getStyle();
583:                        if (footer.isSticky()
584:                                && groupFooterStyle.getBooleanStyleProperty(
585:                                        BandStyleKeys.REPEAT_HEADER, false)) {
586:                            print(level.getRuntime(), footer);
587:                        }
588:                    }
589:                }
590:
591:                final Band pageFooter = report.getPageFooter();
592:                final ElementStyleSheet pageFooterStyle = pageFooter.getStyle();
593:                if (event.getState().getCurrentPage() == 1) {
594:                    if (pageFooterStyle
595:                            .getBooleanStyleProperty(BandStyleKeys.DISPLAY_ON_FIRSTPAGE) == true) {
596:                        print(getRuntime(), pageFooter);
597:                    }
598:                } else if (isLastPagebreak()) {
599:                    if (pageFooterStyle.getBooleanStyleProperty(
600:                            BandStyleKeys.DISPLAY_ON_LASTPAGE, false) == true) {
601:                        print(getRuntime(), pageFooter);
602:                    }
603:                } else {
604:                    print(getRuntime(), pageFooter);
605:                }
606:
607:                for (int i = 0; i < levelCount; i++) {
608:                    final LayouterLevel level = levels[i];
609:                    final ReportDefinition def = level.getReportDefinition();
610:                    final PageFooter b = def.getPageFooter();
611:                    if (b.isSticky() == false) {
612:                        continue;
613:                    }
614:
615:                    final ElementStyleSheet style = b.getStyle();
616:                    if (event.getState().getCurrentPage() == 1) {
617:                        if (style
618:                                .getBooleanStyleProperty(BandStyleKeys.DISPLAY_ON_FIRSTPAGE) == true) {
619:                            print(level.getRuntime(), b);
620:                        }
621:                    } else if (isLastPagebreak()) {
622:                        if (style
623:                                .getBooleanStyleProperty(BandStyleKeys.DISPLAY_ON_LASTPAGE) == true) {
624:                            print(level.getRuntime(), b);
625:                        }
626:                    } else {
627:                        print(level.getRuntime(), b);
628:                    }
629:                }
630:                renderer.endSection();
631:            }
632:
633:            /**
634:             * Returns the current report event.
635:             *
636:             * @return the event.
637:             */
638:            protected ReportEvent getCurrentEvent() {
639:                return currentEvent;
640:            }
641:
642:            /**
643:             * Sets the current event (also updates the report reference).
644:             *
645:             * @param currentEvent event.
646:             */
647:            protected void setCurrentEvent(final ReportEvent currentEvent) {
648:                if (currentEvent == null) {
649:                    throw new NullPointerException("Event must not be null.");
650:                }
651:                this .currentEvent = currentEvent;
652:                this .pagebreakHandler.setReportState(currentEvent.getState());
653:                this .renderer.setStateKey(currentEvent.getState()
654:                        .getProcessKey());
655:            }
656:
657:            /**
658:             * Clears the current event.
659:             */
660:            protected void clearCurrentEvent() {
661:                if (currentEvent == null) {
662:                    Log
663:                            .error(
664:                                    "Failed to clear current event; we don't have an event set!",
665:                                    new IllegalStateException(
666:                                            "stacktrace generated:"));
667:                }
668:                this .currentEvent = null;
669:                this .pagebreakHandler.setReportState(null);
670:                this .renderer.setStateKey(null);
671:            }
672:
673:            /**
674:             * Clones the function. <P> Be aware, this does not create a deep copy. If you have complex strucures contained in
675:             * objects, you have to override this function.
676:             *
677:             * @return a clone of this function.
678:             * @throws CloneNotSupportedException this should never happen.
679:             */
680:            public final Object clone() throws CloneNotSupportedException {
681:                final DefaultOutputFunction sl = (DefaultOutputFunction) super 
682:                        .clone();
683:                sl.currentEvent = null;
684:                return sl;
685:            }
686:
687:            public Expression getInstance() {
688:                return deriveForStorage();
689:            }
690:
691:            /**
692:             * Creates a storage-copy of the output function. A storage copy must create a deep clone of all referenced objects so
693:             * that it is guaranteed that changes to either the original or the clone do not affect the other instance.
694:             * <p/>
695:             * Any failure to implement this method correctly will be a great source of very subtle bugs.
696:             *
697:             * @return the deep clone.
698:             */
699:            public OutputFunction deriveForStorage() {
700:                try {
701:                    final DefaultOutputFunction sl = (DefaultOutputFunction) super 
702:                            .clone();
703:                    sl.renderer = renderer.deriveForStorage();
704:                    sl.currentEvent = null;
705:                    sl.pagebreakHandler = (DefaultLayoutPagebreakHandler) pagebreakHandler
706:                            .clone();
707:                    sl.pagebreakHandler.setReportState(null);
708:                    return sl;
709:                } catch (CloneNotSupportedException e) {
710:                    throw new IllegalStateException();
711:                }
712:            }
713:
714:            /**
715:             * Creates a cheaper version of the deep-copy of the output function. A pagebreak-derivate is created on every possible
716:             * pagebreak position and must contain all undo/rollback information to restore the state of any shared object when
717:             * a roll-back is requested.
718:             * <p/>
719:             * Any failure to implement this method correctly will be a great source of very subtle bugs.
720:             *
721:             * @return the deep clone.
722:             */
723:            public OutputFunction deriveForPagebreak() {
724:                try {
725:                    final DefaultOutputFunction sl = (DefaultOutputFunction) super 
726:                            .clone();
727:                    sl.renderer = renderer.deriveForPagebreak();
728:                    sl.currentEvent = null;
729:                    sl.pagebreakHandler = (DefaultLayoutPagebreakHandler) pagebreakHandler
730:                            .clone();
731:                    return sl;
732:                } catch (CloneNotSupportedException e) {
733:                    throw new IllegalStateException();
734:                }
735:            }
736:
737:            public void setRenderer(final Renderer renderer) {
738:                this .renderer = renderer;
739:            }
740:
741:            public Renderer getRenderer() {
742:                return renderer;
743:            }
744:
745:            /**
746:             * Prints the given band at the current cursor position.
747:             *
748:             * @param dataRow the datarow for evaluating the band's value-expressions.
749:             * @param band    the band to be printed.
750:             */
751:            protected void print(final ExpressionRuntime dataRow,
752:                    final Band band) {
753:                renderer.add(band, dataRow, getCurrentEvent().getState()
754:                        .getProcessKey());
755:            }
756:
757:            private void clearPendingPageStart(final ReportState state) {
758:                pagebreakHandler.setReportState(state);
759:                try {
760:                    renderer.clearPendingPageStart(pagebreakHandler);
761:                } finally {
762:                    pagebreakHandler.setReportState(null);
763:                }
764:            }
765:
766:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.