View Javadoc

1   /*
2    * This software was designed and created by Jason Carroll.
3    * Copyright (c) 2002, 2003, 2004 Jason Carroll.
4    * The author can be reached at jcarroll@cowsultants.com
5    * ITracker website: http://www.cowsultants.com
6    * ITracker forums: http://www.cowsultants.com/phpBB/index.php
7    *
8    * This program is free software; you can redistribute it and/or modify
9    * it only under the terms of the GNU General Public License as published by
10   * the Free Software Foundation; either version 2 of the License, or
11   * (at your option) any later version.
12   *
13   * This program is distributed in the hope that it will be useful,
14   * but WITHOUT ANY WARRANTY; without even the implied warranty of
15   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   * GNU General Public License for more details.
17   */
18  
19  package org.itracker.core.resources;
20  
21  import java.text.DecimalFormat;
22  import java.text.NumberFormat;
23  import java.util.Locale;
24  
25  import org.apache.log4j.Logger;
26  import org.apache.oro.text.regex.MalformedPatternException;
27  import org.apache.oro.text.regex.MatchResult;
28  import org.apache.oro.text.regex.Pattern;
29  import org.apache.oro.text.regex.PatternCompiler;
30  import org.apache.oro.text.regex.PatternMatcherInput;
31  import org.apache.oro.text.regex.Perl5Compiler;
32  import org.apache.oro.text.regex.Perl5Matcher;
33  
34  /**
35    * This class provides support for message replacement when there is a need for more than
36    * 10 arguements.  Currently the only additional formatting it accepts are number patterns.
37    */
38  public class MessageFormat {
39      
40      private static final Logger logger = Logger.getLogger(MessageFormat.class); 
41      private static final Perl5Matcher matcher = new Perl5Matcher();
42      private static final PatternCompiler compiler = new Perl5Compiler();
43      private static Pattern pattern;
44  
45      static {
46          try {
47              pattern = compiler.compile("{(\\d+),?([\\w]*),?(.*?)}", Perl5Compiler.CASE_INSENSITIVE_MASK|Perl5Compiler.SINGLELINE_MASK);
48          } catch(MalformedPatternException mpe) {
49              logger.error("Invalid pattern specified.  No formatting will be performed.", mpe);
50              pattern = null;
51          }
52      }
53  
54      public static String format(String message, Object[] options) {
55          return format(message, options, ITrackerResources.getLocale());
56      }
57  
58      public static String format(String message, Object[] options, Locale locale) {
59          String output = message;
60  
61          if(pattern != null) {
62              int currentOffset = 0;
63              StringBuffer buffer = new StringBuffer();
64              PatternMatcherInput input = new PatternMatcherInput(message);
65  
66              while(matcher.contains(input, pattern)) {
67                  MatchResult result = null;
68                  try {
69                      result = matcher.getMatch();
70                      int numGroups = result.groups();
71                      int optionNumber = Integer.parseInt(result.group(1));
72  
73                      buffer.append(message.substring(currentOffset, result.beginOffset(0)));
74                      currentOffset = result.endOffset(0);
75  
76                      if(options != null && optionNumber < options.length && options[optionNumber] != null) {
77                          if(numGroups > 2 && "number".equalsIgnoreCase(result.group(2))) {
78                              // Format the option value as a number
79                              try {
80                                  NumberFormat formatter = NumberFormat.getInstance(locale);
81                                  if(numGroups > 3) {
82                                      formatter = new DecimalFormat(result.group(3));
83                                  }
84                                  buffer.append(formatter.format(Double.parseDouble(options[optionNumber].toString())));
85                              } catch(Exception e) {
86                                  logger.debug("Unable to format " + options[optionNumber] + " as number.", e);
87                                  buffer.append(options[optionNumber].toString());
88                              }
89                          } else {
90                              buffer.append(options[optionNumber].toString());
91                          }
92                      }
93                  } catch(Exception e) {
94                      logger.error("Unable to perform option replacement for option " + (result == null ? "NULL" : result.group(1)));
95                      logger.debug("Invalid option has current offest of " + currentOffset + " in message '" + message + "'", e);
96                  }
97              }
98  
99              if(buffer.length() > 0) {
100                 buffer.append(message.substring(currentOffset));
101                 output = buffer.toString();
102             }
103         }
104 
105         return output;
106     }
107 
108 }