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: * PageOfPagesFunction.java
027: * ------------
028: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
029: */package org.jfree.report.function;
030:
031: import java.text.MessageFormat;
032: import java.util.Locale;
033:
034: import org.jfree.report.event.ReportEvent;
035: import org.jfree.util.ObjectUtilities;
036:
037: /**
038: * A report function that combines {@link PageFunction}and {@link PageTotalFunction}. Restrictions for both classes
039: * apply to this one also.
040: *
041: * @author Jörg Schaible
042: */
043: public class PageOfPagesFunction extends PageFunction {
044: /**
045: * A internal function delegate that computes the total number of pages.
046: */
047: private PageTotalFunction pageTotalFunction;
048: /**
049: * The message format pattern.
050: */
051: private String format;
052:
053: /**
054: * An internal cached value holding the last locale used by the function.
055: */
056: private transient Locale lastLocale;
057: /**
058: * An internal cached value holding the last page seen by the function.
059: */
060: private transient Integer lastPage;
061: /**
062: * An internal cached value holding the last total-pages seen by the function.
063: */
064: private transient Integer lastTotalPage;
065: /**
066: * An internal cached value holding the message format object.
067: */
068: private transient MessageFormat messageFormat;
069: /**
070: * An internal cached value holding the last message that has been computed.
071: */
072: private transient String lastMessage;
073:
074: /**
075: * Default Constructor.
076: */
077: public PageOfPagesFunction() {
078: this .pageTotalFunction = new PageTotalFunction();
079: this .format = "{0} / {1}";
080: }
081:
082: /**
083: * Constructs a named function.
084: *
085: * @param name the function name.
086: */
087: public PageOfPagesFunction(final String name) {
088: this ();
089: setName(name);
090: }
091:
092: /**
093: * Returns the format used to print the value. The default format is "{0} / {1}".
094: *
095: * @return the format string.
096: * @see MessageFormat
097: */
098: public String getFormat() {
099: return format;
100: }
101:
102: /**
103: * Set the format of the value. The format should follow the rules of {@link MessageFormat}. The first parameter is
104: * filled with the current page, the second with the total number of pages.
105: *
106: * @param format the format string.
107: */
108: public void setFormat(final String format) {
109: if (format == null) {
110: throw new NullPointerException("Format must not be null.");
111: }
112: this .format = format;
113: this .messageFormat = null;
114: }
115:
116: /**
117: * Forwards the report event to both the base class and the page-total function delegate.
118: *
119: * @param event the received report event.
120: */
121: public void reportInitialized(final ReportEvent event) {
122: super .reportInitialized(event);
123: pageTotalFunction.reportInitialized(event);
124: }
125:
126: /**
127: * Forwards the report event to both the base class and the page-total function delegate.
128: *
129: * @param event the received report event.
130: */
131: public void pageStarted(final ReportEvent event) {
132: super .pageStarted(event);
133: pageTotalFunction.pageStarted(event);
134: }
135:
136: /**
137: * Forwards the report event to both the base class and the page-total function delegate.
138: *
139: * @param event the received report event.
140: */
141: public void pageFinished(final ReportEvent event) {
142: super .pageFinished(event);
143: pageTotalFunction.pageFinished(event);
144: }
145:
146: /**
147: * Forwards the report event to both the base class and the page-total function delegate.
148: *
149: * @param event the received report event.
150: */
151: public void groupStarted(final ReportEvent event) {
152: super .groupStarted(event);
153: pageTotalFunction.groupStarted(event);
154: }
155:
156: public void groupFinished(final ReportEvent event) {
157: super .groupFinished(event);
158: pageTotalFunction.groupFinished(event);
159: }
160:
161: /**
162: * Return the value of this {@link Function}. The method uses the format definition from the properties and adds the
163: * current page and the total number of pages as parameter.
164: *
165: * @return the formatted value with current page and total number of pages.
166: */
167: public Object getValue() {
168: final Integer page = (Integer) super .getValue();
169: final Integer pages = (Integer) pageTotalFunction.getValue();
170: Locale locale = getResourceBundleFactory().getLocale();
171: if (locale == null) {
172: locale = Locale.getDefault();
173: }
174:
175: if (messageFormat == null
176: || ObjectUtilities.equal(locale, lastLocale) == false) {
177: this .messageFormat = new MessageFormat(getFormat());
178: this .messageFormat.setLocale(locale);
179: this .messageFormat.applyPattern(getFormat());
180: this .lastLocale = locale;
181: }
182:
183: if (lastMessage == null
184: || ObjectUtilities.equal(page, this .lastPage) == false
185: || ObjectUtilities.equal(pages, this .lastTotalPage) == false) {
186: this .lastMessage = messageFormat.format(new Object[] {
187: page, pages });
188: this .lastPage = page;
189: this .lastTotalPage = pages;
190: }
191: return lastMessage;
192: }
193:
194: /**
195: * Sets the name of the group that the function acts upon.
196: *
197: * @param group the group name.
198: */
199: public void setGroup(final String group) {
200: super .setGroup(group);
201: pageTotalFunction.setGroup(group);
202: }
203:
204: /**
205: * Defines the page number where the counting starts.
206: *
207: * @param startPage the page number of the first page.
208: */
209: public void setStartPage(final int startPage) {
210: super .setStartPage(startPage);
211: pageTotalFunction.setStartPage(startPage);
212: }
213:
214: /**
215: * Defines the defined dependency level. For page functions, this level can be as low as the pagination level.
216: *
217: * @param level the dependency level.
218: */
219: public void setDependencyLevel(final int level) {
220: super .setDependencyLevel(level);
221: pageTotalFunction.setDependencyLevel(level);
222: }
223:
224: /**
225: * Returns the defined dependency level. For page functions, this level can be as low as the pagination level.
226: *
227: * @return the dependency level.
228: */
229: public int getDependencyLevel() {
230: return pageTotalFunction.getDependencyLevel();
231: }
232:
233: /**
234: * Return a completly separated copy of this function. The copy does no longer share any changeable objects with the
235: * original function.
236: *
237: * @return a copy of this function.
238: */
239: public Expression getInstance() {
240: final PageOfPagesFunction function = (PageOfPagesFunction) super
241: .getInstance();
242: function.pageTotalFunction = (PageTotalFunction) pageTotalFunction
243: .getInstance();
244: return function;
245: }
246:
247: /**
248: * Defines the ExpressionRune used in this expression. The ExpressionRuntime is set before the expression receives
249: * events or gets evaluated and is unset afterwards. Do not hold references on the runtime or you will create
250: * memory-leaks.
251: *
252: * @param runtime the runtime information for the expression
253: */
254: public void setRuntime(final ExpressionRuntime runtime) {
255: super .setRuntime(runtime);
256: pageTotalFunction.setRuntime(runtime);
257: }
258:
259: /**
260: * Creates a copy of the function.
261: *
262: * @return the clone.
263: * @throws CloneNotSupportedException if an error occurs.
264: */
265: public Object clone() throws CloneNotSupportedException {
266: final PageOfPagesFunction function = (PageOfPagesFunction) super
267: .clone();
268: function.pageTotalFunction = (PageTotalFunction) pageTotalFunction
269: .clone();
270: return function;
271: }
272: }
|