1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
36
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
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 }