View Javadoc

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 }