View Javadoc

1   /*
2    * $Id: DecimalLocaleConverter.java,v 1.4 2004/04/09 18:44:53 eelco12 Exp $
3    * $Revision: 1.4 $
4    * $Date: 2004/04/09 18:44:53 $
5    *
6    * ====================================================================
7    * Copyright (c) 2003, Open Edge B.V.
8    * All rights reserved.
9    * Redistribution and use in source and binary forms, with or without 
10   * modification, are permitted provided that the following conditions are met:
11   * Redistributions of source code must retain the above copyright notice, 
12   * this list of conditions and the following disclaimer. Redistributions 
13   * in binary form must reproduce the above copyright notice, this list of 
14   * conditions and the following disclaimer in the documentation and/or other 
15   * materials provided with the distribution. Neither the name of OpenEdge B.V. 
16   * nor the names of its contributors may be used to endorse or promote products 
17   * derived from this software without specific prior written permission.
18   * 
19   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
20   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
21   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
22   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
23   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
24   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
25   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
26   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
27   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
28   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
29   * THE POSSIBILITY OF SUCH DAMAGE.
30   */
31  
32  package nl.openedge.baritus.converters;
33  
34  import java.text.DecimalFormat;
35  import java.text.ParseException;
36  import java.util.Locale;
37  import java.util.regex.Matcher;
38  import java.util.regex.Pattern;
39  
40  /***
41   * <p>Modified {@link LocaleConverter} 
42   * implementation for this framework</p>
43   *
44   * @author Yauheny Mikulski
45   * @author Eelco Hillenius
46   */
47  public abstract class DecimalLocaleConverter extends BaseLocaleConverter
48  {
49  
50  	protected Pattern nonDigitPattern = 
51  		Pattern.compile(".*[^0-9&&[^//,]&&[^//.]&&[^//-]].*");
52  
53  	// ----------------------------------------------------------- Constructors
54  
55  	/***
56  	 * Create a {@link LocaleConverter} 
57  	 * that will throw a {@link ConversionException}
58  	 * if a conversion error occurs. The locale is the default locale for
59  	 * this instance of the Java Virtual Machine and an unlocalized pattern is used
60  	 * for the convertion.
61  	 *
62  	 */
63  	public DecimalLocaleConverter()
64  	{
65  		this(Locale.getDefault());
66  	}
67  
68  	/***
69  	 * Create a {@link LocaleConverter} 
70  	 * that will throw a {@link ConversionException}
71  	 * if a conversion error occurs. No pattern is used for the convertion.
72  	 *
73  	 * @param locale        The locale
74  	 */
75  	public DecimalLocaleConverter(Locale locale)
76  	{
77  		this(locale, null);
78  	}
79  
80  	/***
81  	 * Create a {@link LocaleConverter} 
82  	 * that will throw a {@link ConversionException}
83  	 * if a conversion error occurs. An unlocalized pattern is used for the convertion.
84  	 *
85  	 * @param locale        The locale
86  	 * @param pattern       The convertion pattern
87  	 */
88  	public DecimalLocaleConverter(Locale locale, String pattern)
89  	{
90  		this(locale, pattern, false);
91  	}
92  
93  	/***
94  	 * Create a {@link LocaleConverter} 
95  	 * that will throw a {@link ConversionException}
96  	 * if a conversion error occurs.
97  	 *
98  	 * @param locale        The locale
99  	 * @param pattern       The convertion pattern
100 	 * @param locPattern    Indicate whether the pattern is localized or not
101 	 */
102 	public DecimalLocaleConverter(
103 		Locale locale,
104 		String pattern,
105 		boolean locPattern)
106 	{
107 		super(locale, pattern, locPattern);
108 	}
109 
110 
111 	// --------------------------------------------------------- Methods
112 
113 	/***
114 	 * Convert the specified locale-sensitive input object into an output object of the
115 	 * specified type.
116 	 *
117 	 * @param value The input object to be converted
118 	 * @param pattern The pattern is used for the conversion
119 	 *
120 	 * @exception ConversionException if conversion cannot be performed successfully
121 	 */
122 	protected Object parse(Object value, String pattern) throws ParseException
123 	{
124 		if(value == null) return null;
125 		DecimalFormat formatter = getFormat(pattern);
126 		
127 		return formatter.parse((String) value);
128 	}
129 	
130 	/***
131 	 * Convert the specified input object into a locale-sensitive output string
132 	 *
133 	 * @param value The input object to be formatted
134 	 * @param pattern The pattern is used for the conversion
135 	 *
136 	 * @exception IllegalArgumentException if formatting cannot be performed successfully
137 	 */
138 	public String format(Object value, String pattern) throws IllegalArgumentException
139 	{
140 		if(value == null) return null;
141 		
142 		DecimalFormat formatter = getFormat(pattern);
143 		return formatter.format(value);		
144 	}
145 	
146 	/***
147 	 * get format and optionally apply pattern if given
148 	 * @param pattern pattern or null
149 	 * @return DecimalFormat formatter instance
150 	 */
151 	protected DecimalFormat getFormat(String pattern)
152 	{
153 		DecimalFormat formatter = (DecimalFormat)DecimalFormat.getInstance(locale);
154 		if (pattern != null)
155 		{
156 			if (locPattern)
157 			{
158 				formatter.applyLocalizedPattern(pattern);
159 			}
160 			else
161 			{
162 				formatter.applyPattern(pattern);
163 			}
164 		}		
165 		return formatter;
166 	}
167 	
168 	/***
169 	 * translate value to a number optionally using the supplied pattern
170 	 * @param value the value to convert
171 	 * @param pattern the patter to use (optional)
172 	 * @return Number
173 	 * @throws ConversionException
174 	 */
175 	protected Number getNumber(Object value, String pattern) throws ConversionException
176 	{
177 		if(value instanceof Number) return (Number)value;
178 		
179 		Number temp = null;
180 		try
181 		{
182 			if (pattern != null)
183 			{
184 				temp = (Number)parse(value, pattern);
185 			}
186 			else
187 			{
188 				String stringval = null;
189 				if(value instanceof String) stringval = (String)value;
190 				else if(value instanceof String[]) stringval = ((String[])value)[0];
191 				else stringval = String.valueOf(value);
192 
193 				Matcher nonDigitMatcher = nonDigitPattern.matcher(stringval);
194 				if(nonDigitMatcher.matches())
195 				{
196 					throw new ConversionException(stringval + " is not a valid number");
197 				}	
198 				
199 				temp = (Number)parse(value, this.pattern);
200 			}
201 		}
202 		catch (Exception e)
203 		{
204 			String dpat = null;
205 			if(pattern != null)
206 			{
207 				dpat = pattern;
208 			}
209 			else
210 			{
211 				DecimalFormat formatter = getFormat(pattern);
212 				dpat = formatter.toLocalizedPattern();
213 			}
214 			throw new ConversionException(e, dpat);
215 		}
216 		
217 		return temp;
218 	}
219 }