1 package pl.aislib.util.validators;
2
3 import java.lang.reflect.Constructor;
4 import java.lang.reflect.InvocationTargetException;
5 import java.lang.reflect.Method;
6 import java.text.DecimalFormat;
7 import java.text.DecimalFormatSymbols;
8 import java.text.Format;
9 import java.text.NumberFormat;
10 import java.text.ParseException;
11 import java.text.ParsePosition;
12 import java.util.Locale;
13
14 import org.apache.commons.logging.Log;
15 import org.apache.commons.logging.LogFactory;
16
17 /***
18 * @author <a href="mailto:pikus@ais.pl">Tomasz Pik</a>, AIS.PL
19 * @version $Revision: 1.2 $
20 */
21 public class NumberFormatHelper {
22
23 protected static final Log LOG = LogFactory.getLog("pl.aislib.util.validators");
24
25 /***
26 * Calls {@link DecimalFormat#applyLocalizedPattern(String)}.
27 *
28 * @param format
29 * @param value
30 */
31 public static void applyLocalizedPattern(Format format, String value) {
32 try {
33 Method method = format.getClass().getDeclaredMethod("applyLocalizedPattern", new Class[]{String.class});
34 method.invoke(format, new Object[]{value});
35 } catch (Exception e) {
36 if (LOG.isWarnEnabled()) {
37 LOG.warn("exeption caught", e);
38 }
39 }
40 }
41
42 /***
43 * Calls {@link DecimalFormat#toLocalizedPattern()}.
44 *
45 * @param format
46 * @return
47 */
48 public static String toLocalizedPattern(Format format) {
49 try {
50 Method method = format.getClass().getDeclaredMethod("toLocalizedPattern", new Class[]{});
51 return (String) method.invoke(format, new Object[]{});
52 } catch (Exception e) {
53 if (LOG.isWarnEnabled()) {
54 LOG.warn("exeption caught", e);
55 }
56 }
57 return null;
58 }
59
60 /***
61 * Calls {@link DecimalFormatSymbols#getGroupingSeparator()}.
62 *
63 * @param format
64 * @return
65 */
66 public static char getGroupingSeparator(Format format) {
67 try {
68 Method method1 = format.getClass().getDeclaredMethod("getDecimalFormatSymbols", new Class[]{});
69 Object decimalFormatSymbols = method1.invoke(format, new Object[]{});
70 if (decimalFormatSymbols != null) {
71 Method method2 = decimalFormatSymbols.getClass().getDeclaredMethod("getGroupingSeparator", new Class[]{});
72 Character charResult = (Character) method2.invoke(decimalFormatSymbols, new Object[]{});
73 return charResult.charValue();
74 }
75 } catch (Exception e) {
76 if (LOG.isWarnEnabled()) {
77 LOG.warn("exeption caught", e);
78 }
79 }
80 return ' ';
81 }
82
83 /***
84 * Calls {@link DecimalFormatSymbols#setGroupingSeparator(char)}.
85 *
86 * @param format
87 * @param separator
88 * @return previous separator
89 */
90 public static char setGroupingSeparator(Format format, char separator) {
91 try {
92 Method method1 = format.getClass().getDeclaredMethod("getDecimalFormatSymbols", new Class[]{});
93 Object decimalFormatSymbols = method1.invoke(format, new Object[]{});
94
95 Method method2 = decimalFormatSymbols.getClass().getDeclaredMethod("getGroupingSeparator", new Class[]{});
96 Character result = (Character) method2.invoke(decimalFormatSymbols, new Object[]{});
97
98 Method method3 = decimalFormatSymbols.getClass().getDeclaredMethod("setGroupingSeparator", new Class[]{char.class});
99 method3.invoke(decimalFormatSymbols, new Object[]{new Character(separator)});
100
101 Method method4 = format.getClass().getDeclaredMethod("setDecimalFormatSymbols", new Class[]{decimalFormatSymbols.getClass()});
102 method4.invoke(format, new Object[]{decimalFormatSymbols});
103
104 return result.charValue();
105 } catch (Exception e) {
106 if (LOG.isWarnEnabled()) {
107 LOG.warn("exeption caught", e);
108 }
109 }
110 return ' ';
111 }
112
113 /***
114 * Calls {@link NumberFormat#parse(String, ParsePosition)}.
115 *
116 * @param format
117 * @param str
118 * @param pos
119 * @return
120 * @throws ParseException
121 */
122 public static Number parse(Format format, String str, ParsePosition pos) throws ParseException {
123 try {
124 Method m = format.getClass().getDeclaredMethod("parse", new Class[]{String.class, ParsePosition.class});
125 return (Number) m.invoke(format, new Object[]{str, pos});
126 } catch (IllegalAccessException iae) {
127 if (LOG.isWarnEnabled()) {
128 LOG.warn("exeption caught", iae);
129 }
130 } catch (NoSuchMethodException nsme) {
131 if (LOG.isWarnEnabled()) {
132 LOG.warn("exeption caught", nsme);
133 }
134 } catch (InvocationTargetException ite) {
135 if (ite.getTargetException() != null && ite.getTargetException() instanceof ParseException) {
136 throw (ParseException) ite.getTargetException();
137 } else {
138 if (LOG.isWarnEnabled()) {
139 LOG.warn("exeption caught", ite);
140 }
141 }
142 }
143 return null;
144 }
145
146 /***
147 * Calls {@link NumberFormat#setParseIntegerOnly(boolean)}.
148 *
149 * @param format
150 * @param value
151 */
152 public static void setParseIntegerOnly(Format format, boolean value) {
153 try {
154 Method m = format.getClass().getMethod("setParseIntegerOnly", new Class[]{boolean.class});
155 m.invoke(format, new Object[]{new Boolean(value)});
156 } catch (Exception e) {
157 if (LOG.isWarnEnabled()) {
158 LOG.warn("exeption caught", e);
159 }
160 }
161 }
162
163 /***
164 * Calls {@link DecimalFormat#setMaximumFractionDigits(int)}.
165 *
166 * @param format
167 * @param value
168 */
169 public static void setMaximumFractionDigits(Format format, int value) {
170 try {
171 Method m = format.getClass().getDeclaredMethod("setMaximumFractionDigits", new Class[]{int.class});
172 m.invoke(format, new Object[]{new Integer(value)});
173 } catch (Exception e) {
174 if (LOG.isWarnEnabled()) {
175 LOG.warn("exeption caught", e);
176 }
177 }
178 }
179
180 /***
181 * Creates new instance of <code>NumberFormat</code>.
182 * If <code>useICU4J</code> is <code>true</code>, <code>com.ibm.icu.text.DecimalFormat</code>
183 * class is being instantied. Otherwise, standard <code>java.text.DecimalFormat</code>
184 * is used.
185 *
186 * @param useICU4J
187 * @param pattern
188 * @param locale
189 * @return
190 */
191 public static Format createInstance(boolean useICU4J, String pattern, Locale locale) {
192 if (useICU4J) {
193 try {
194 Class dfsclass = Class.forName("com.ibm.icu.text.DecimalFormatSymbols");
195 Constructor cnscnstr = dfsclass.getConstructor(new Class[]{Locale.class});
196 Object dfs = cnscnstr.newInstance(new Object[]{locale});
197
198 Class dfclass = Class.forName("com.ibm.icu.text.DecimalFormat");
199 Constructor dfcsnstr = dfclass.getConstructor(new Class[]{String.class, dfsclass});
200 Object result = dfcsnstr.newInstance(new Object[]{pattern, dfs});
201 return (Format) result;
202 } catch (Exception e) {
203 LOG.error("Cannot instantiate ICU4J classes, use default implementation", e);
204 }
205 }
206 DecimalFormat result = new DecimalFormat(pattern, new DecimalFormatSymbols(locale));
207 return result;
208 }
209 }