Source for org.jfree.report.util.MessageFormatSupport

   1: /**
   2:  * ========================================
   3:  * JFreeReport : a free Java report library
   4:  * ========================================
   5:  *
   6:  * Project Info:  http://reporting.pentaho.org/
   7:  *
   8:  * (C) Copyright 2000-2007, by Object Refinery Limited, Pentaho Corporation and Contributors.
   9:  *
  10:  * This library is free software; you can redistribute it and/or modify it under the terms
  11:  * of the GNU Lesser General Public License as published by the Free Software Foundation;
  12:  * either version 2.1 of the License, or (at your option) any later version.
  13:  *
  14:  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  15:  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  16:  * See the GNU Lesser General Public License for more details.
  17:  *
  18:  * You should have received a copy of the GNU Lesser General Public License along with this
  19:  * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  20:  * Boston, MA 02111-1307, USA.
  21:  *
  22:  * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
  23:  * in the United States and other countries.]
  24:  *
  25:  * ------------
  26:  * $Id: MessageFormatSupport.java 3525 2007-10-16 11:43:48Z tmorgner $
  27:  * ------------
  28:  * (C) Copyright 2000-2005, by Object Refinery Limited.
  29:  * (C) Copyright 2005-2007, by Pentaho Corporation.
  30:  */
  31: package org.jfree.report.util;
  32: 
  33: import java.io.Serializable;
  34: import java.text.DateFormat;
  35: import java.text.Format;
  36: import java.text.MessageFormat;
  37: import java.text.NumberFormat;
  38: import java.util.ArrayList;
  39: import java.util.Date;
  40: import java.util.Locale;
  41: 
  42: import org.jfree.report.DataRow;
  43: import org.jfree.report.DataSourceException;
  44: 
  45: public class MessageFormatSupport implements Serializable, Cloneable
  46: {
  47:   protected static class MessageCompiler extends PropertyLookupParser
  48:   {
  49:     private ArrayList fields;
  50:     //private ArrayList completeFormatString;
  51: 
  52:     protected MessageCompiler()
  53:     {
  54:       this.fields = new ArrayList();
  55:       //this.completeFormatString = new ArrayList();
  56:       setMarkerChar('$');
  57:       setOpeningBraceChar('(');
  58:       setClosingBraceChar(')');
  59:     }
  60: 
  61:     protected String lookupVariable(final String name)
  62:     {
  63:       final CSVTokenizer tokenizer = new CSVTokenizer(name, ",", "\"");
  64:       if (tokenizer.hasMoreTokens() == false)
  65:       {
  66:         return null;
  67:       }
  68:       final String varName = tokenizer.nextToken();
  69: /*    // we have to collect every occurence, even if it is included twice
  70:       // to allow the null-value-processing later ..
  71:       final int index = fields.indexOf(varName);
  72:       if (index != -1)
  73:       {
  74:         return (String) completeFormatString.get(index);
  75:       }
  76: */
  77:       final StringBuffer b = new StringBuffer();
  78:       b.append("{");
  79:       b.append(String.valueOf(fields.size()));
  80:       while (tokenizer.hasMoreTokens())
  81:       {
  82:         b.append(",");
  83:         b.append(tokenizer.nextToken());
  84:       }
  85:       b.append("}");
  86:       final String formatString = b.toString();
  87:       //completeFormatString.add(formatString);
  88:       fields.add(varName);
  89:       return formatString;
  90:     }
  91: 
  92:     public String[] getFields()
  93:     {
  94:       return (String[]) fields.toArray(new String[fields.size()]);
  95:     }
  96:   }
  97: 
  98:   private String[] fields;
  99:   private MessageFormat format;
 100:   private String formatString;
 101:   private String compiledFormat;
 102:   private String nullString;
 103: 
 104:   public MessageFormatSupport()
 105:   {
 106:   }
 107: 
 108:   public String getFormatString()
 109:   {
 110:     return formatString;
 111:   }
 112: 
 113:   public void setFormatString(final String formatString)
 114:   {
 115:     final MessageCompiler compiler = new MessageCompiler();
 116:     if (formatString == null)
 117:     {
 118:       throw new NullPointerException("Format must not be null");
 119:     }
 120:     compiledFormat = compiler.translateAndLookup(formatString);
 121:     fields = compiler.getFields();
 122:     format = new MessageFormat(compiledFormat);
 123:     this.formatString = formatString;
 124:   }
 125: 
 126:   public String performFormat(final DataRow dataRow) throws DataSourceException
 127:   {
 128:     return formatWithReplace(dataRow, format, fields, nullString);
 129:   }
 130: 
 131:   public Locale getLocale()
 132:   {
 133:     return format.getLocale();
 134:   }
 135: 
 136:   public String getCompiledFormat()
 137:   {
 138:     return compiledFormat;
 139:   }
 140: 
 141:   public void setLocale(final Locale locale)
 142:   {
 143:     format.setLocale(locale);
 144:     format.applyPattern(compiledFormat);
 145:   }
 146: 
 147:   public String getNullString()
 148:   {
 149:     return nullString;
 150:   }
 151: 
 152:   public void setNullString(final String nullString)
 153:   {
 154:     this.nullString = nullString;
 155:   }
 156: 
 157:   public Object clone()
 158:           throws CloneNotSupportedException
 159:   {
 160:     final MessageFormatSupport support = (MessageFormatSupport) super.clone();
 161:     if (format != null)
 162:     {
 163:       support.format = (MessageFormat) format.clone();
 164:     }
 165:     return support;
 166:   }
 167: 
 168:   public String[] getFields()
 169:   {
 170:     return (String[]) fields.clone();
 171:   }
 172: 
 173: 
 174:   public static String formatWithReplace(final DataRow dataRow,
 175:                                          final MessageFormat format,
 176:                                          final String[] fields,
 177:                                          final String nullString)
 178:           throws DataSourceException
 179:   {
 180:     if (fields == null || format == null)
 181:     {
 182:       return null;
 183:     }
 184: 
 185:     final boolean fastProcessingPossible = (nullString == null);
 186: 
 187:     final Format[] formats = format.getFormats();
 188:     boolean fastProcessing = true;
 189:     final Object[] parameters = new Object[fields.length];
 190:     final boolean[] replaced = new boolean[fields.length];
 191:     for (int i = 0; i < parameters.length; i++)
 192:     {
 193:       final Object value = dataRow.get(fields[i]);
 194:       final Format currentFormat = formats[i];
 195:       if (value == null)
 196:       {
 197:         parameters[i] = nullString;
 198:         replaced[i] = currentFormat != null;
 199:         fastProcessing = (fastProcessing && fastProcessingPossible && replaced[i] == false);
 200:       }
 201:       else
 202:       {
 203:         if (currentFormat instanceof DateFormat)
 204:         {
 205:           if (value instanceof Date)
 206:           {
 207:             parameters[i] = value;
 208:             replaced[i] = false;
 209:           }
 210:           else
 211:           {
 212:             parameters[i] = nullString;
 213:             replaced[i] = true;
 214:             fastProcessing = (fastProcessing && fastProcessingPossible && replaced[i] == false);
 215:           }
 216:         }
 217:         else if (currentFormat instanceof NumberFormat)
 218:         {
 219:           if (value instanceof Number)
 220:           {
 221:             parameters[i] = value;
 222:             replaced[i] = false;
 223:           }
 224:           else
 225:           {
 226:             parameters[i] = nullString;
 227:             replaced[i] = true;
 228:             fastProcessing = (fastProcessing && fastProcessingPossible && replaced[i] == false);
 229:           }
 230:         }
 231:         else
 232:         {
 233:           parameters[i] = value;
 234:           replaced[i] = false;
 235:         }
 236:       }
 237:     }
 238:     if (fastProcessing)
 239:     {
 240:       return format.format(parameters);
 241:     }
 242: 
 243:     final MessageFormat effectiveFormat = (MessageFormat) format.clone();
 244:     for (int i = 0; i < replaced.length; i++)
 245:     {
 246:       final boolean b = replaced[i];
 247:       if (b)
 248:       {
 249:         effectiveFormat.setFormat(i, null);
 250:       }
 251:     }
 252:     return effectiveFormat.format(parameters);
 253:   }
 254: 
 255: 
 256:   public static String formatWithReplace(final MessageFormat format,
 257:                                          final Object[] inputValues,
 258:                                          final String nullString)
 259:   {
 260:     if (inputValues == null || format == null)
 261:     {
 262:       return null;
 263:     }
 264: 
 265:     final Object[] values = (Object[]) inputValues.clone();
 266: 
 267:     final boolean fastProcessingPossible = (nullString == null);
 268: 
 269:     final Format[] formats = format.getFormats();
 270:     boolean fastProcessing = true;
 271:     final boolean[] replaced = new boolean[values.length];
 272:     for (int i = 0; i < values.length; i++)
 273:     {
 274:       final Object value = values[i];
 275:       final Format currentFormat = formats[i];
 276:       if (value == null)
 277:       {
 278:         values[i] = nullString;
 279:         replaced[i] = currentFormat != null;
 280:         fastProcessing = (fastProcessing && fastProcessingPossible && replaced[i] == false);
 281:       }
 282:       else
 283:       {
 284:         if (currentFormat instanceof DateFormat)
 285:         {
 286:           if (value instanceof Date)
 287:           {
 288:             values[i] = value;
 289:             replaced[i] = false;
 290:           }
 291:           else
 292:           {
 293:             values[i] = nullString;
 294:             replaced[i] = true;
 295:             fastProcessing = (fastProcessing && fastProcessingPossible && replaced[i] == false);
 296:           }
 297:         }
 298:         else if (currentFormat instanceof NumberFormat)
 299:         {
 300:           if (value instanceof Number)
 301:           {
 302:             values[i] = value;
 303:             replaced[i] = false;
 304:           }
 305:           else
 306:           {
 307:             values[i] = nullString;
 308:             replaced[i] = true;
 309:             fastProcessing = (fastProcessing && fastProcessingPossible && replaced[i] == false);
 310:           }
 311:         }
 312:         else
 313:         {
 314:           values[i] = value;
 315:           replaced[i] = false;
 316:         }
 317:       }
 318:     }
 319:     if (fastProcessing)
 320:     {
 321:       return format.format(values);
 322:     }
 323: 
 324:     final MessageFormat effectiveFormat = (MessageFormat) format.clone();
 325:     for (int i = 0; i < replaced.length; i++)
 326:     {
 327:       final boolean b = replaced[i];
 328:       if (b)
 329:       {
 330:         effectiveFormat.setFormat(i, null);
 331:       }
 332:     }
 333:     return effectiveFormat.format(values);
 334:   }
 335: 
 336: }