001: /**
002: * ========================================
003: * JFreeReport : a free Java report library
004: * ========================================
005: *
006: * Project Info: http://reporting.pentaho.org/
007: *
008: * (C) Copyright 2000-2007, by Object Refinery Limited, 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: * $Id: MessageFormatSupport.java 3525 2007-10-16 11:43:48Z tmorgner $
027: * ------------
028: * (C) Copyright 2000-2005, by Object Refinery Limited.
029: * (C) Copyright 2005-2007, by Pentaho Corporation.
030: */package org.jfree.report.util;
031:
032: import java.io.Serializable;
033: import java.text.DateFormat;
034: import java.text.Format;
035: import java.text.MessageFormat;
036: import java.text.NumberFormat;
037: import java.util.ArrayList;
038: import java.util.Date;
039: import java.util.Locale;
040:
041: import org.jfree.report.DataRow;
042: import org.jfree.report.DataSourceException;
043:
044: public class MessageFormatSupport implements Serializable, Cloneable {
045: protected static class MessageCompiler extends PropertyLookupParser {
046: private ArrayList fields;
047:
048: //private ArrayList completeFormatString;
049:
050: protected MessageCompiler() {
051: this .fields = new ArrayList();
052: //this.completeFormatString = new ArrayList();
053: setMarkerChar('$');
054: setOpeningBraceChar('(');
055: setClosingBraceChar(')');
056: }
057:
058: protected String lookupVariable(final String name) {
059: final CSVTokenizer tokenizer = new CSVTokenizer(name, ",",
060: "\"");
061: if (tokenizer.hasMoreTokens() == false) {
062: return null;
063: }
064: final String varName = tokenizer.nextToken();
065: /* // we have to collect every occurence, even if it is included twice
066: // to allow the null-value-processing later ..
067: final int index = fields.indexOf(varName);
068: if (index != -1)
069: {
070: return (String) completeFormatString.get(index);
071: }
072: */
073: final StringBuffer b = new StringBuffer();
074: b.append("{");
075: b.append(String.valueOf(fields.size()));
076: while (tokenizer.hasMoreTokens()) {
077: b.append(",");
078: b.append(tokenizer.nextToken());
079: }
080: b.append("}");
081: final String formatString = b.toString();
082: //completeFormatString.add(formatString);
083: fields.add(varName);
084: return formatString;
085: }
086:
087: public String[] getFields() {
088: return (String[]) fields.toArray(new String[fields.size()]);
089: }
090: }
091:
092: private String[] fields;
093: private MessageFormat format;
094: private String formatString;
095: private String compiledFormat;
096: private String nullString;
097:
098: public MessageFormatSupport() {
099: }
100:
101: public String getFormatString() {
102: return formatString;
103: }
104:
105: public void setFormatString(final String formatString) {
106: final MessageCompiler compiler = new MessageCompiler();
107: if (formatString == null) {
108: throw new NullPointerException("Format must not be null");
109: }
110: compiledFormat = compiler.translateAndLookup(formatString);
111: fields = compiler.getFields();
112: format = new MessageFormat(compiledFormat);
113: this .formatString = formatString;
114: }
115:
116: public String performFormat(final DataRow dataRow)
117: throws DataSourceException {
118: return formatWithReplace(dataRow, format, fields, nullString);
119: }
120:
121: public Locale getLocale() {
122: return format.getLocale();
123: }
124:
125: public String getCompiledFormat() {
126: return compiledFormat;
127: }
128:
129: public void setLocale(final Locale locale) {
130: format.setLocale(locale);
131: format.applyPattern(compiledFormat);
132: }
133:
134: public String getNullString() {
135: return nullString;
136: }
137:
138: public void setNullString(final String nullString) {
139: this .nullString = nullString;
140: }
141:
142: public Object clone() throws CloneNotSupportedException {
143: final MessageFormatSupport support = (MessageFormatSupport) super
144: .clone();
145: if (format != null) {
146: support.format = (MessageFormat) format.clone();
147: }
148: return support;
149: }
150:
151: public String[] getFields() {
152: return (String[]) fields.clone();
153: }
154:
155: public static String formatWithReplace(final DataRow dataRow,
156: final MessageFormat format, final String[] fields,
157: final String nullString) throws DataSourceException {
158: if (fields == null || format == null) {
159: return null;
160: }
161:
162: final boolean fastProcessingPossible = (nullString == null);
163:
164: final Format[] formats = format.getFormats();
165: boolean fastProcessing = true;
166: final Object[] parameters = new Object[fields.length];
167: final boolean[] replaced = new boolean[fields.length];
168: for (int i = 0; i < parameters.length; i++) {
169: final Object value = dataRow.get(fields[i]);
170: final Format currentFormat = formats[i];
171: if (value == null) {
172: parameters[i] = nullString;
173: replaced[i] = currentFormat != null;
174: fastProcessing = (fastProcessing
175: && fastProcessingPossible && replaced[i] == false);
176: } else {
177: if (currentFormat instanceof DateFormat) {
178: if (value instanceof Date) {
179: parameters[i] = value;
180: replaced[i] = false;
181: } else {
182: parameters[i] = nullString;
183: replaced[i] = true;
184: fastProcessing = (fastProcessing
185: && fastProcessingPossible && replaced[i] == false);
186: }
187: } else if (currentFormat instanceof NumberFormat) {
188: if (value instanceof Number) {
189: parameters[i] = value;
190: replaced[i] = false;
191: } else {
192: parameters[i] = nullString;
193: replaced[i] = true;
194: fastProcessing = (fastProcessing
195: && fastProcessingPossible && replaced[i] == false);
196: }
197: } else {
198: parameters[i] = value;
199: replaced[i] = false;
200: }
201: }
202: }
203: if (fastProcessing) {
204: return format.format(parameters);
205: }
206:
207: final MessageFormat effectiveFormat = (MessageFormat) format
208: .clone();
209: for (int i = 0; i < replaced.length; i++) {
210: final boolean b = replaced[i];
211: if (b) {
212: effectiveFormat.setFormat(i, null);
213: }
214: }
215: return effectiveFormat.format(parameters);
216: }
217:
218: public static String formatWithReplace(final MessageFormat format,
219: final Object[] inputValues, final String nullString) {
220: if (inputValues == null || format == null) {
221: return null;
222: }
223:
224: final Object[] values = (Object[]) inputValues.clone();
225:
226: final boolean fastProcessingPossible = (nullString == null);
227:
228: final Format[] formats = format.getFormats();
229: boolean fastProcessing = true;
230: final boolean[] replaced = new boolean[values.length];
231: for (int i = 0; i < values.length; i++) {
232: final Object value = values[i];
233: final Format currentFormat = formats[i];
234: if (value == null) {
235: values[i] = nullString;
236: replaced[i] = currentFormat != null;
237: fastProcessing = (fastProcessing
238: && fastProcessingPossible && replaced[i] == false);
239: } else {
240: if (currentFormat instanceof DateFormat) {
241: if (value instanceof Date) {
242: values[i] = value;
243: replaced[i] = false;
244: } else {
245: values[i] = nullString;
246: replaced[i] = true;
247: fastProcessing = (fastProcessing
248: && fastProcessingPossible && replaced[i] == false);
249: }
250: } else if (currentFormat instanceof NumberFormat) {
251: if (value instanceof Number) {
252: values[i] = value;
253: replaced[i] = false;
254: } else {
255: values[i] = nullString;
256: replaced[i] = true;
257: fastProcessing = (fastProcessing
258: && fastProcessingPossible && replaced[i] == false);
259: }
260: } else {
261: values[i] = value;
262: replaced[i] = false;
263: }
264: }
265: }
266: if (fastProcessing) {
267: return format.format(values);
268: }
269:
270: final MessageFormat effectiveFormat = (MessageFormat) format
271: .clone();
272: for (int i = 0; i < replaced.length; i++) {
273: final boolean b = replaced[i];
274: if (b) {
275: effectiveFormat.setFormat(i, null);
276: }
277: }
278: return effectiveFormat.format(values);
279: }
280:
281: }
|