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: * FormatFilter.java
027: * ------------
028: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
029: */package org.jfree.report.filter;
030:
031: import java.text.Format;
032:
033: import org.jfree.report.function.ExpressionRuntime;
034: import org.jfree.util.ObjectUtilities;
035:
036: /**
037: * The base class for filters that format data. Data is received from a DataSource and
038: * formatted. The data source might be a field in the TableModel or a report function, or
039: * even another format filter (since filters implement the DataSource interface).
040: * <p/>
041: * Formating is done by a java.text.Format object. This filter will always return a String
042: * object on getValue().
043: * <p/>
044: * If the formater does not understand the object returned by the defined datasource, the
045: * defined null value is returned.
046: * <p/>
047: * The nullValue is set to "-" by default.
048: *
049: * @author Thomas Morgner
050: */
051: public class FormatFilter implements DataFilter, RawDataSource {
052: /**
053: * The format used to create the string representation of the data.
054: */
055: private Format format;
056:
057: /**
058: * The datasource from where the data is obtained.
059: */
060: private DataSource datasource;
061:
062: /**
063: * The string used to represent null.
064: */
065: private String nullvalue;
066:
067: /**
068: * A string holding the formatted result.
069: */
070: private transient String cachedResult;
071: /**
072: * The cached raw-value. This value is used to compare the incomming value with the cached result.
073: */
074: private transient Object cachedValue;
075: /**
076: * The cached Formatter.
077: */
078: private transient Format cachedFormat;
079:
080: /**
081: * Default constructor.
082: */
083: public FormatFilter() {
084: nullvalue = null;
085: }
086:
087: /**
088: * Clears all cached values and forces a complete recomputation of all formattings.
089: */
090: protected void invalidateCache() {
091: cachedFormat = null;
092: cachedValue = null;
093: cachedResult = null;
094: }
095:
096: /**
097: * Sets the format for the filter.
098: *
099: * @param format The format.
100: * @throws NullPointerException if the given format is null
101: */
102: public void setFormatter(final Format format) {
103: if (format == null) {
104: throw new NullPointerException();
105: }
106: this .format = format;
107: }
108:
109: /**
110: * Returns the format for the filter.
111: *
112: * @return The format.
113: */
114: public Format getFormatter() {
115: return this .format;
116: }
117:
118: /**
119: * Returns the formatted string. The value is read using the data source given and
120: * formated using the formatter of this object. The formating is guaranteed to completly
121: * form the object to an string or to return the defined NullValue.
122: * <p/>
123: * If format, datasource or object are null, the NullValue is returned.
124: *
125: * @param runtime the expression runtime that is used to evaluate formulas and expressions when computing the value of
126: * this filter.
127: * @return The formatted value.
128: */
129: public Object getValue(final ExpressionRuntime runtime) {
130: final Format f = getFormatter();
131: if (f == null) {
132: return getNullValue();
133: }
134:
135: final DataSource ds = getDataSource();
136: if (ds == null) {
137: return getNullValue();
138: }
139:
140: final Object o = ds.getValue(runtime);
141: if (o == null) {
142: return getNullValue();
143: }
144:
145: if (cachedResult != null && (cachedFormat != f)
146: && ObjectUtilities.equal(cachedValue, o)) {
147: return cachedResult;
148: }
149:
150: try {
151: cachedResult = f.format(o);
152: } catch (IllegalArgumentException e) {
153: cachedResult = getNullValue();
154: }
155:
156: cachedFormat = f;
157: cachedValue = o;
158: return cachedResult;
159: }
160:
161: /**
162: * Sets the value that will be displayed if the data source supplies a null value.
163: *
164: * @param nullvalue The string.
165: */
166: public void setNullValue(final String nullvalue) {
167: if (nullvalue == null) {
168: throw new NullPointerException();
169: }
170: this .nullvalue = nullvalue;
171: }
172:
173: /**
174: * Returns the string representing a null value from the data source.
175: *
176: * @return The string.
177: */
178: public String getNullValue() {
179: return nullvalue;
180: }
181:
182: /**
183: * Returns the data source for the filter.
184: *
185: * @return The data source.
186: */
187: public DataSource getDataSource() {
188: return datasource;
189: }
190:
191: /**
192: * Sets the data source.
193: *
194: * @param ds The data source.
195: */
196: public void setDataSource(final DataSource ds) {
197: if (ds == null) {
198: throw new NullPointerException();
199: }
200: this .datasource = ds;
201: }
202:
203: /**
204: * Clones the filter.
205: *
206: * @return a clone.
207: *
208: * @throws CloneNotSupportedException this should never happen.
209: */
210: public Object clone() throws CloneNotSupportedException {
211: final FormatFilter f = (FormatFilter) super .clone();
212: if (datasource != null) {
213: f.datasource = (DataSource) datasource.clone();
214: }
215: if (format != null) {
216: f.format = (Format) format.clone();
217: if (cachedFormat == format) {
218: f.cachedFormat = f.format;
219: }
220: }
221: return f;
222: }
223:
224: public Object getRawValue(final ExpressionRuntime runtime) {
225: return datasource.getValue(runtime);
226: }
227:
228: public FormatSpecification getFormatString(
229: final ExpressionRuntime runtime,
230: FormatSpecification formatSpecification) {
231: if (datasource instanceof RawDataSource) {
232: final RawDataSource rds = (RawDataSource) datasource;
233: return rds.getFormatString(runtime, formatSpecification);
234: }
235: if (formatSpecification == null) {
236: formatSpecification = new FormatSpecification();
237: }
238: formatSpecification.redefine(
239: FormatSpecification.TYPE_UNDEFINED, null);
240: return formatSpecification;
241: }
242:
243: }
|