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: * AbstractReportDefinition.java
027: * ------------
028: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
029: */package org.jfree.report;
030:
031: import java.io.Serializable;
032:
033: import org.jfree.report.function.Expression;
034: import org.jfree.report.function.ExpressionCollection;
035: import org.jfree.report.style.StyleSheetCollection;
036: import org.jfree.report.util.ReportProperties;
037:
038: /**
039: * The AbstractReportDefinition serves as base-implementation for both the SubReport and the global JFreeReport
040: * instance. There's no point to subclass this class any further.
041: * <p/>
042: * ReportDefinitions define the query string to "default" by default, change this to reflect the accepted queries
043: * in your data-source.
044: *
045: * @author Thomas Morgner
046: */
047: public abstract class AbstractReportDefinition implements Serializable,
048: ReportDefinition {
049: /**
050: * Storage for arbitrary properties that a user can assign to the report.
051: */
052: private ReportProperties properties;
053: /**
054: * Storage for the expressions in the report.
055: */
056: private ExpressionCollection expressions;
057: /**
058: * An ordered list of report groups (each group defines its own header and footer).
059: */
060: private GroupList groups;
061: /**
062: * The report header band (printed once at the start of the report).
063: */
064: private ReportHeader reportHeader;
065: /**
066: * The report footer band (printed once at the end of the report).
067: */
068: private ReportFooter reportFooter;
069: /**
070: * The page header band (printed at the start of every page).
071: */
072: private PageHeader pageHeader;
073: /**
074: * The page footer band (printed at the end of every page).
075: */
076: private PageFooter pageFooter;
077: /**
078: * The item band - used once for each row of data.
079: */
080: private ItemBand itemBand;
081: /**
082: * The watermark band.
083: */
084: private Watermark watermark;
085: /**
086: * The no-data band is printed, if the tablemodel is empty.
087: */
088: private NoDataBand noDataBand;
089: /**
090: * The name of the query that will be used to retrieve the data from the data-factory.
091: */
092: private String query;
093: /**
094: * The stylesheet collection used for this report.
095: */
096: private StyleSheetCollection styleSheetCollection;
097:
098: /**
099: * Creates a new instance. This initializes all properties to their defaults - especially for subreports you have to
100: * set sensible values before you can use them later.
101: */
102: protected AbstractReportDefinition() {
103: this .query = "default";
104:
105: this .properties = new ReportProperties();
106: this .styleSheetCollection = new StyleSheetCollection();
107:
108: this .groups = new GroupList();
109: this .reportHeader = new ReportHeader();
110: this .reportFooter = new ReportFooter();
111: this .pageHeader = new PageHeader();
112: this .pageFooter = new PageFooter();
113: this .itemBand = new ItemBand();
114: this .watermark = new Watermark();
115: this .noDataBand = new NoDataBand();
116:
117: this .expressions = new ExpressionCollection();
118: this .groups.setReportDefinition(this );
119: this .reportHeader.setReportDefinition(this );
120: this .reportFooter.setReportDefinition(this );
121: this .pageHeader.setReportDefinition(this );
122: this .pageFooter.setReportDefinition(this );
123: this .itemBand.setReportDefinition(this );
124: this .watermark.setReportDefinition(this );
125: }
126:
127: /**
128: * Adds a property to the report.
129: * <p/>
130: * If a property with the given name already exists, the property will be updated with the new value. If the supplied
131: * value is <code>null</code>, the property will be removed.
132: * <p/>
133: * Developers are free to add any properties they want to a report, and then display those properties in the report.
134: * For example, you might add a 'user.name' property, so that you can display the username in the header of a report.
135: *
136: * @param key the key.
137: * @param value the value.
138: */
139: public void setProperty(final String key, final Object value) {
140: this .properties.put(key, value);
141: }
142:
143: /**
144: * Returns the report properties collection for this report.
145: * <p/>
146: * These properties are inherited to all ReportStates generated for this report.
147: *
148: * @return the report properties.
149: */
150: public ReportProperties getProperties() {
151: return properties;
152: }
153:
154: /**
155: * Returns the value of the property with the specified key.
156: *
157: * @param key the key.
158: * @return the property value.
159: */
160: public Object getProperty(final String key) {
161: if (key == null) {
162: throw new NullPointerException();
163: }
164: return this .properties.get(key);
165: }
166:
167: /**
168: * Sets the report header.
169: *
170: * @param header the report header (<code>null</code> not permitted).
171: */
172: public void setReportHeader(final ReportHeader header) {
173: if (header == null) {
174: throw new NullPointerException(
175: "AbstractReportDefinition.setReportHeader(...) : null not permitted.");
176: }
177: this .reportHeader.setReportDefinition(null);
178: this .reportHeader = header;
179: this .reportHeader.setReportDefinition(this );
180: }
181:
182: /**
183: * Returns the report header.
184: *
185: * @return the report header (never <code>null</code>).
186: */
187: public ReportHeader getReportHeader() {
188: return reportHeader;
189: }
190:
191: /**
192: * Sets the report footer.
193: *
194: * @param footer the report footer (<code>null</code> not permitted).
195: */
196: public void setReportFooter(final ReportFooter footer) {
197: if (footer == null) {
198: throw new NullPointerException(
199: "AbstractReportDefinition.setReportFooter(...) : null not permitted.");
200: }
201: this .reportFooter.setReportDefinition(null);
202: this .reportFooter = footer;
203: this .reportFooter.setReportDefinition(this );
204: }
205:
206: /**
207: * Returns the page footer.
208: *
209: * @return the report footer (never <code>null</code>).
210: */
211: public ReportFooter getReportFooter() {
212: return reportFooter;
213: }
214:
215: /**
216: * Sets the page header.
217: *
218: * @param header the page header (<code>null</code> not permitted).
219: */
220: public void setPageHeader(final PageHeader header) {
221: if (header == null) {
222: throw new NullPointerException(
223: "AbstractReportDefinition.setPageHeader(...) : null not permitted.");
224: }
225: this .pageHeader.setReportDefinition(null);
226: this .pageHeader = header;
227: this .pageHeader.setReportDefinition(this );
228: }
229:
230: /**
231: * Returns the page header.
232: *
233: * @return the page header (never <code>null</code>).
234: */
235: public PageHeader getPageHeader() {
236: return pageHeader;
237: }
238:
239: /**
240: * Sets the page footer.
241: *
242: * @param footer the page footer (<code>null</code> not permitted).
243: */
244: public void setPageFooter(final PageFooter footer) {
245: if (footer == null) {
246: throw new NullPointerException(
247: "AbstractReportDefinition.setPageFooter(...) : null not permitted.");
248: }
249: this .pageFooter.setReportDefinition(null);
250: this .pageFooter = footer;
251: this .pageFooter.setReportDefinition(this );
252: }
253:
254: /**
255: * Returns the page footer.
256: *
257: * @return the page footer (never <code>null</code>).
258: */
259: public PageFooter getPageFooter() {
260: return pageFooter;
261: }
262:
263: /**
264: * Sets the watermark band for the report.
265: *
266: * @param band the new watermark band (<code>null</code> not permitted).
267: */
268: public void setWatermark(final Watermark band) {
269: if (band == null) {
270: throw new NullPointerException(
271: "AbstractReportDefinition.setWatermark(...) : null not permitted.");
272: }
273: this .watermark.setReportDefinition(null);
274: this .watermark = band;
275: this .watermark.setReportDefinition(this );
276: }
277:
278: /**
279: * Returns the report's watermark band.
280: *
281: * @return the watermark band (never <code>null</code>).
282: */
283: public NoDataBand getNoDataBand() {
284: return this .noDataBand;
285: }
286:
287: /**
288: * Sets the watermark band for the report.
289: *
290: * @param band the new watermark band (<code>null</code> not permitted).
291: */
292: public void setNoDataBand(final NoDataBand band) {
293: if (band == null) {
294: throw new NullPointerException(
295: "AbstractReportDefinition.setNoDataBand(...) : null not permitted.");
296: }
297: this .noDataBand.setReportDefinition(null);
298: this .noDataBand = band;
299: this .noDataBand.setReportDefinition(this );
300: }
301:
302: /**
303: * Returns the report's watermark band.
304: *
305: * @return the watermark band (never <code>null</code>).
306: */
307: public Watermark getWatermark() {
308: return this .watermark;
309: }
310:
311: /**
312: * Sets the item band for the report.
313: *
314: * @param band the new item band (<code>null</code> not permitted).
315: */
316: public void setItemBand(final ItemBand band) {
317: if (band == null) {
318: throw new NullPointerException(
319: "AbstractReportDefinition.setItemBand(...) : null not permitted.");
320: }
321: this .itemBand.setReportDefinition(null);
322: this .itemBand = band;
323: this .itemBand.setReportDefinition(this );
324: }
325:
326: /**
327: * Returns the report's item band.
328: *
329: * @return the item band (never <code>null</code>).
330: */
331: public ItemBand getItemBand() {
332: return this .itemBand;
333: }
334:
335: /**
336: * Adds a group to the report.
337: *
338: * @param group the group.
339: */
340: public void addGroup(final Group group) {
341: groups.add(group);
342: }
343:
344: /**
345: * Sets the groups for this report. If no list (null) or an empty list is given, an default group is created. This
346: * default group contains no elements and starts at the first record of the data and ends on the last record.
347: *
348: * @param groupList the list of groups.
349: */
350: public void setGroups(final GroupList groupList) {
351: if (groupList == null) {
352: throw new NullPointerException("GroupList must not be null");
353: }
354: this .groups.setReportDefinition(null);
355: this .groups = groupList;
356: this .groups.setReportDefinition(this );
357: }
358:
359: /**
360: * Returns a clone of the list of groups for the report.
361: *
362: * @return the group list.
363: */
364: public GroupList getGroups() {
365: return this .groups;
366: }
367:
368: /**
369: * Returns the number of groups in this report. <P> Every report has at least one group defined.
370: *
371: * @return the group count.
372: */
373: public int getGroupCount() {
374: return groups.size();
375: }
376:
377: /**
378: * Returns the group at the specified index or null, if there is no such group.
379: *
380: * @param count the group index.
381: * @return the requested group.
382: * @throws IllegalArgumentException if the count is negative.
383: * @throws IndexOutOfBoundsException if the count is greater than the number of defined groups.
384: */
385: public Group getGroup(final int count) {
386: if (count < 0) {
387: throw new IllegalArgumentException(
388: "GroupCount must not be negative");
389: }
390:
391: if (count >= groups.size()) {
392: throw new IndexOutOfBoundsException(
393: "No such group defined. " + count + " vs. "
394: + groups.size());
395: }
396:
397: return groups.get(count);
398: }
399:
400: /**
401: * Searches a group by its defined name. This method returns null, if the group was not found.
402: *
403: * @param name the name of the group.
404: * @return the group or null if not found.
405: * @see org.jfree.report.GroupList#getGroupByName
406: */
407: public Group getGroupByName(final String name) {
408: return groups.getGroupByName(name);
409: }
410:
411: /**
412: * Adds a function to the report's collection of expressions.
413: *
414: * @param function the function.
415: */
416: public void addExpression(final Expression function) {
417: expressions.add(function);
418: }
419:
420: /**
421: * Returns a new query or query-name that is used when retrieving the data from the data-factory.
422: *
423: * @return the query-string.
424: */
425: public String getQuery() {
426: return query;
427: }
428:
429: /**
430: * Defines a new query or query-name that is used when retrieving the data from the data-factory.
431: *
432: * @param query the query-string.
433: * @see DataFactory#queryData(String,DataRow)
434: */
435: public void setQuery(final String query) {
436: if (query == null) {
437: throw new NullPointerException("Query cannot be null.");
438: }
439: this .query = query;
440: }
441:
442: /**
443: * Returns the stylesheet collection of this report. The stylesheet collection is fixed for the report and all
444: * elements of the report. When a band or group is added to the report it will get registered with this stylesheet
445: * collection and cannot be used in an different report.
446: *
447: * @return the stylesheet collection of the report, never null.
448: */
449: public StyleSheetCollection getStyleSheetCollection() {
450: return styleSheetCollection;
451: }
452:
453: /**
454: * Returns the current datarow assigned to this report definition. JFreeReport objects do not hold a working DataRow,
455: * as the final contents of the data cannot be known, until the reporting has started.
456: *
457: * @return the default implementation for non-processed reports.
458: */
459: public DataRow getDataRow() {
460: return new ParameterDataRow(properties);
461: }
462:
463: /**
464: * Returns the expressions for the report.
465: *
466: * @return the expressions.
467: */
468: public ExpressionCollection getExpressions() {
469: return expressions;
470: }
471:
472: /**
473: * Sets the expressions for the report.
474: *
475: * @param expressions the expressions (<code>null</code> not permitted).
476: */
477: public void setExpressions(final ExpressionCollection expressions) {
478: if (expressions == null) {
479: throw new NullPointerException(
480: "AbstractReportDefinition.setExpressions(...) : null not permitted.");
481: }
482: this .expressions = expressions;
483: }
484:
485: /**
486: * Clones the report.
487: *
488: * @return the clone.
489: * @throws CloneNotSupportedException this should never happen.
490: */
491: public Object clone() throws CloneNotSupportedException {
492: final AbstractReportDefinition report = (AbstractReportDefinition) super
493: .clone();
494: report.groups = (GroupList) groups.clone();
495: report.watermark = (Watermark) watermark.clone();
496: report.itemBand = (ItemBand) itemBand.clone();
497: report.pageFooter = (PageFooter) pageFooter.clone();
498: report.pageHeader = (PageHeader) pageHeader.clone();
499: report.reportFooter = (ReportFooter) reportFooter.clone();
500: report.reportHeader = (ReportHeader) reportHeader.clone();
501: report.noDataBand = (NoDataBand) noDataBand.clone();
502: report.properties = (ReportProperties) properties.clone();
503: report.expressions = (ExpressionCollection) expressions.clone();
504: report.styleSheetCollection = (StyleSheetCollection) styleSheetCollection
505: .clone();
506: report.noDataBand.setReportDefinition(report);
507: report.groups.setReportDefinition(report);
508: report.reportHeader.setReportDefinition(report);
509: report.reportFooter.setReportDefinition(report);
510: report.pageHeader.setReportDefinition(report);
511: report.pageFooter.setReportDefinition(report);
512: report.itemBand.setReportDefinition(report);
513: report.watermark.setReportDefinition(report);
514: return report;
515: }
516: }
|