001    package com.softnetConsult.utils.string;
002    
003    import java.math.RoundingMode;
004    import java.text.DecimalFormat;
005    import java.text.NumberFormat;
006    import java.text.ParseException;
007    
008    /**
009     * Defines static utility methods for string processing.
010     * 
011     * <p style="font-size:smaller;">This product includes software developed by the
012     *    <strong>SoftNet-Consult Java Utility Library</strong> project and its contributors.<br />
013     *    (<a href="http://java-tools.sourceforge.net" target="_blank">http://java-tools.sourceforge.net</a>)<br />
014     *    Copyright (c) 2007-2008 SoftNet-Consult.<br />
015     *    Copyright (c) 2007-2008 G. Paperin.<br />
016     *    All rights reserved.
017     * </p>
018     * <p style="font-size:smaller;">File: StringTools.java<br />
019     *    Library API version: {@value com.softnetConsult.utils.APIProperties#apiVersion}<br />
020     *    Java compliance version: {@value com.softnetConsult.utils.APIProperties#javaComplianceVersion}
021     * </p>
022     * <p style="font-size:smaller;">Redistribution and use in source and binary forms, with or
023     *    without modification, are permitted provided that the following terms and conditions are met:
024     * </p>
025     * <p style="font-size:smaller;">1. Redistributions of source code must retain the above
026     *    acknowledgement of the SoftNet-Consult Java Utility Library project, the above copyright
027     *    notice, this list of conditions and the following disclaimer.<br />
028     *    2. Redistributions in binary form must reproduce the above acknowledgement of the
029     *    SoftNet-Consult Java Utility Library project, the above copyright notice, this list of
030     *    conditions and the following disclaimer in the documentation and/or other materials
031     *    provided with the distribution.<br />
032     *    3. All advertising materials mentioning features or use of this software or any derived
033     *    software must display the following acknowledgement:<br />
034     *    <em>This product includes software developed by the SoftNet-Consult Java Utility Library
035     *    project and its contributors.</em>
036     * </p>
037     * <p style="font-size:smaller;">THIS SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY
038     *    OF ANY KIND, EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
039     *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT SHALL
040     *    THE AUTHORS, CONTRIBUTORS OR COPYRIGHT  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
041     *    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING  FROM, OUT OF OR
042     *    IN CONNECTION WITH THE SOFTWARE OR THE USE OR  OTHER DEALINGS IN THE SOFTWARE.
043     * </p> 
044     * @author Greg Paperin (<a href="http://www.paperin.org" target="_blank">http://www.paperin.org</a>)
045     * @version {@value com.softnetConsult.utils.APIProperties#apiVersion}
046     *
047     */
048    public final class StringTools {
049    
050    
051    /**
052     * An internal singelton instance of a default number formatter.
053     */
054    private static NumberFormat singeltonNumberFormatter = null;
055    
056    
057    /**
058     * Prevents instances of this class from being created
059     * as this class contains only static utility methods.
060     */
061    private StringTools() {}
062    
063    
064    /**
065     * Used internally to access a singelton instance of a default number formatter.
066     * 
067     * @return A singelton instance of a default number formatter.
068     */
069    private static NumberFormat getSingeltonNumberFormatter() {
070            if (null == singeltonNumberFormatter) {
071                    singeltonNumberFormatter = NumberFormat.getNumberInstance();
072                    singeltonNumberFormatter.setGroupingUsed(false);
073                    singeltonNumberFormatter.setMinimumFractionDigits(0);
074                    singeltonNumberFormatter.setMaximumFractionDigits(Integer.MAX_VALUE);
075                    singeltonNumberFormatter.setMinimumIntegerDigits(1);
076                    singeltonNumberFormatter.setMaximumIntegerDigits(Integer.MAX_VALUE);
077                    singeltonNumberFormatter.setParseIntegerOnly(false);
078                    try {
079                            singeltonNumberFormatter.setRoundingMode(RoundingMode.HALF_EVEN);
080                    } catch(NoSuchMethodError e) {}
081                    if (singeltonNumberFormatter instanceof DecimalFormat)
082                            ((DecimalFormat) singeltonNumberFormatter).setDecimalSeparatorAlwaysShown(false);
083            }
084            return singeltonNumberFormatter;
085    }
086    
087    
088    /**
089     * Resets the internal number formatter such that next time it is required (e.g. for one
090     * of this class' methods {@code parseXXXX(String)} and {@code toString(xxxx)})
091     * a new formatter is re-created using the current default locale.
092     * This method may be useful after the system default locale has been changed by the user
093     * in order to update the state of this class' formatter.
094     */
095    public static void enforceNumberFormatterReset() {
096            singeltonNumberFormatter = null;
097    }
098    
099    
100    /**
101     * Ensures that the specified string is not shorter than the specified length by
102     * prefixing it with a white spaces.
103     * This is equivalent to {@code ensureMinLength(str, length, ' ')}.
104     * 
105     * @param str A string ({@code null}-strings are converted to the string {@code "null"}).
106     * @param length The required minimum length for the string.
107     * @return The string elongated by prefixing it with white spaces to ensure
108     * the specified minimum length.
109     */
110    public static String ensureMinLength(String str, int length) {
111            return ensureMinLength(str, length, ' ');
112    }
113    
114    
115    /**
116     * Ensures that the specified string is not shorter than the specified length by
117     * prefixing it with the specified character as necessary.
118     * 
119     * @param str A string ({@code null}-strings are converted to the string {@code "null"}).
120     * @param length The required minimum length for the string.
121     * @param fill The character to use for the prefix.
122     * @return The string elongated by prefixing it with the specified character to ensure
123     * the specified minimum length.
124     */
125    public static String ensureMinLength(String str, int length, char fill) {
126            
127            if (null == str)
128                    str = "null";
129            
130            if (str.length() >= length)
131                    return str;
132    
133            StringBuffer s = new StringBuffer(length);
134            for (int i = 0, fillLen = length - str.length(); i < fillLen; i++) {
135                    s.append(fill);
136            }
137            s.append(str);
138            
139            return s.toString();
140    }
141    
142    
143    /**
144     * Parses a string to a number using the current default locale.<br />
145     * Note that the current locale is determined only once at the time
146     * when any of this class' methods {@code parseXXXX(String)} or
147     * {@code toString(xxxx)} is called for the first time. The same
148     * locale is then always reused, even if the default system locale is
149     * changed. In order to enforce the creation of a new formatter, use
150     * the method {@link #enforceNumberFormatterReset()}.
151     * 
152     * @param str A string.
153     * @return The number represented by the specifed string.
154     * @throws NumberFormatException If the specified string is {@code null} or
155     * if the beginning of the specified string cannot be parsed; in the latter
156     * case the thrown exception encapsulates the {@code ParseException} raised
157     * by the formatter as its cause.
158     * @see java.text.NumberFormat#parse(String)
159     */
160    public static Number parseNumber(String str) throws NumberFormatException {
161            
162            if (null == str)
163                    throw new NumberFormatException("Cannot parse a null string");
164            
165            try {
166                    return getSingeltonNumberFormatter().parse(str);
167            } catch (ParseException pe) {
168                    NumberFormatException nfe = new NumberFormatException(pe.getLocalizedMessage());
169                    nfe.initCause(pe);
170                    throw nfe;
171            }
172    }
173    
174    
175    /**
176     * Parses a string to a {@code byte}-number using the current default locale.<br />
177     * This is equivalent to {@code parseNumber(str).byteValue()}.<br />
178     * Note that the current locale is determined only once at the time
179     * when any of this class' methods {@code parseXXXX(String)} or
180     * {@code toString(xxxx)} is called for the first time. The same
181     * locale is then always reused, even if the default system locale is
182     * changed. In order to enforce the creation of a new formatter, use
183     * the method {@link #enforceNumberFormatterReset()}.
184     * 
185     * @param str A string.
186     * @return The number represented by the specifed string.
187     * @throws NumberFormatException If the specified string is {@code null} or
188     * if the beginning of the specified string cannot be parsed; in the latter
189     * case the thrown exception encapsulates the {@code ParseException} raised
190     * by the formatter as its cause.
191     * @see java.text.NumberFormat#parse(String)
192     */
193    public static byte parseByte(String str) throws NumberFormatException {
194            return parseNumber(str).byteValue();
195    }
196    
197    
198    /**
199     * Parses a string to a {@code short}-number using the current default locale.<br />
200     * This is equivalent to {@code parseNumber(str).shortValue()}.<br />
201     * Note that the current locale is determined only once at the time
202     * when any of this class' methods {@code parseXXXX(String)} or
203     * {@code toString(xxxx)} is called for the first time. The same
204     * locale is then always reused, even if the default system locale is
205     * changed. In order to enforce the creation of a new formatter, use
206     * the method {@link #enforceNumberFormatterReset()}.
207     * 
208     * @param str A string.
209     * @return The number represented by the specifed string.
210     * @throws NumberFormatException If the specified string is {@code null} or
211     * if the beginning of the specified string cannot be parsed; in the latter
212     * case the thrown exception encapsulates the {@code ParseException} raised
213     * by the formatter as its cause.
214     * @see java.text.NumberFormat#parse(String)
215     */
216    public static short parseShort(String str) throws NumberFormatException {
217            return parseNumber(str).shortValue();
218    }
219    
220    
221    /**
222     * Parses a string to a {@code int}-number using the current default locale.<br />
223     * This is equivalent to {@code parseNumber(str).intValue()}.<br />
224     * Note that the current locale is determined only once at the time
225     * when any of this class' methods {@code parseXXXX(String)} or
226     * {@code toString(xxxx)} is called for the first time. The same
227     * locale is then always reused, even if the default system locale is
228     * changed. In order to enforce the creation of a new formatter, use
229     * the method {@link #enforceNumberFormatterReset()}.
230     * 
231     * @param str A string.
232     * @return The number represented by the specifed string.
233     * @throws NumberFormatException If the specified string is {@code null} or
234     * if the beginning of the specified string cannot be parsed; in the latter
235     * case the thrown exception encapsulates the {@code ParseException} raised
236     * by the formatter as its cause.
237     * @see java.text.NumberFormat#parse(String)
238     */
239    public static int parseInt(String str) throws NumberFormatException {
240            return parseNumber(str).intValue();
241    }
242    
243    
244    /**
245     * Parses a string to a {@code long}-number using the current default locale.<br />
246     * This is equivalent to {@code parseNumber(str).longValue()}.<br />
247     * Note that the current locale is determined only once at the time
248     * when any of this class' methods {@code parseXXXX(String)} or
249     * {@code toString(xxxx)} is called for the first time. The same
250     * locale is then always reused, even if the default system locale is
251     * changed. In order to enforce the creation of a new formatter, use
252     * the method {@link #enforceNumberFormatterReset()}.
253     * 
254     * @param str A string.
255     * @return The number represented by the specifed string.
256     * @throws NumberFormatException If the specified string is {@code null} or
257     * if the beginning of the specified string cannot be parsed; in the latter
258     * case the thrown exception encapsulates the {@code ParseException} raised
259     * by the formatter as its cause.
260     * @see java.text.NumberFormat#parse(String)
261     */
262    public static long parseLong(String str) throws NumberFormatException {
263            return parseNumber(str).longValue();
264    }
265    
266    
267    /**
268     * Parses a string to a {@code float}-number using the current default locale.<br />
269     * This is equivalent to {@code parseNumber(str).floatValue()}.<br />
270     * Note that the current locale is determined only once at the time
271     * when any of this class' methods {@code parseXXXX(String)} or
272     * {@code toString(xxxx)} is called for the first time. The same
273     * locale is then always reused, even if the default system locale is
274     * changed. In order to enforce the creation of a new formatter, use
275     * the method {@link #enforceNumberFormatterReset()}.
276     * 
277     * @param str A string.
278     * @return The number represented by the specifed string.
279     * @throws NumberFormatException If the specified string is {@code null} or
280     * if the beginning of the specified string cannot be parsed; in the latter
281     * case the thrown exception encapsulates the {@code ParseException} raised
282     * by the formatter as its cause.
283     * @see java.text.NumberFormat#parse(String)
284     */
285    public static float parseFloat(String str) throws NumberFormatException {
286            return parseNumber(str).floatValue();
287    }
288    
289    
290    /**
291     * Parses a string to a {@code double}-number using the current default locale.<br />
292     * This is equivalent to {@code parseNumber(str).doubleValue()}.<br />
293     * Note that the current locale is determined only once at the time
294     * when any of this class' methods {@code parseXXXX(String)} or
295     * {@code toString(xxxx)} is called for the first time. The same
296     * locale is then always reused, even if the default system locale is
297     * changed. In order to enforce the creation of a new formatter, use
298     * the method {@link #enforceNumberFormatterReset()}.
299     * 
300     * @param str A string.
301     * @return The number represented by the specifed string.
302     * @throws NumberFormatException If the specified string is {@code null} or
303     * if the beginning of the specified string cannot be parsed; in the latter
304     * case the thrown exception encapsulates the {@code ParseException} raised
305     * by the formatter as its cause.
306     * @see java.text.NumberFormat#parse(String)
307     */
308    public static double parseDouble(String str) throws NumberFormatException {
309            return parseNumber(str).doubleValue();
310    }
311    
312    
313    /**
314     * Formats a {@code byte}-value to a {@code String} using the current default locale.<br />
315     * Note that the current locale is determined only once at the time
316     * when any of this class' methods {@code parseXXXX(String)} or
317     * {@code toString(xxxx)} is called for the first time. The same
318     * locale is then always reused, even if the default system locale is
319     * changed. In order to enforce the creation of a new formatter, use
320     * the method {@link #enforceNumberFormatterReset()}.
321     * 
322     * @param val A value to be formatted as a string.
323     * @return A string representing the specifed value according to the current default locale.
324     */
325    public static String toString(byte val) {
326            return toString((long) val); 
327    }
328    
329    
330    /**
331     * Formats a {@code short}-value to a {@code String} using the current default locale.<br />
332     * Note that the current locale is determined only once at the time
333     * when any of this class' methods {@code parseXXXX(String)} or
334     * {@code toString(xxxx)} is called for the first time. The same
335     * locale is then always reused, even if the default system locale is
336     * changed. In order to enforce the creation of a new formatter, use
337     * the method {@link #enforceNumberFormatterReset()}.
338     * 
339     * @param val A value to be formatted as a string.
340     * @return A string representing the specifed value according to the current default locale.
341     */
342    public static String toString(short val) {
343            return toString((long) val); 
344    }
345    
346    
347    /**
348     * Formats a {@code int}-value to a {@code String} using the current default locale.<br />
349     * Note that the current locale is determined only once at the time
350     * when any of this class' methods {@code parseXXXX(String)} or
351     * {@code toString(xxxx)} is called for the first time. The same
352     * locale is then always reused, even if the default system locale is
353     * changed. In order to enforce the creation of a new formatter, use
354     * the method {@link #enforceNumberFormatterReset()}.
355     * 
356     * @param val A value to be formatted as a string.
357     * @return A string representing the specifed value according to the current default locale.
358     */
359    public static String toString(int val) {
360            return toString((long) val); 
361    }
362    
363    
364    /**
365     * Formats a {@code long}-value to a {@code String} using the current default locale.<br />
366     * Note that the current locale is determined only once at the time
367     * when any of this class' methods {@code parseXXXX(String)} or
368     * {@code toString(xxxx)} is called for the first time. The same
369     * locale is then always reused, even if the default system locale is
370     * changed. In order to enforce the creation of a new formatter, use
371     * the method {@link #enforceNumberFormatterReset()}.
372     * 
373     * @param val A value to be formatted as a string.
374     * @return A string representing the specifed value according to the current default locale.
375     */
376    public static String toString(long val) {
377            return getSingeltonNumberFormatter().format(val);
378    }
379    
380    
381    /**
382     * Formats a {@code float}-value to a {@code String} using the current default locale.<br />
383     * Note that the current locale is determined only once at the time
384     * when any of this class' methods {@code parseXXXX(String)} or
385     * {@code toString(xxxx)} is called for the first time. The same
386     * locale is then always reused, even if the default system locale is
387     * changed. In order to enforce the creation of a new formatter, use
388     * the method {@link #enforceNumberFormatterReset()}.
389     * 
390     * @param val A value to be formatted as a string.
391     * @return A string representing the specifed value according to the current default locale.
392     */
393    public static String toString(float val) {
394            return toString((double) val); 
395    }
396    
397    
398    /**
399     * Formats a {@code double}-value to a {@code String} using the current default locale.<br />
400     * Note that the current locale is determined only once at the time
401     * when any of this class' methods {@code parseXXXX(String)} or
402     * {@code toString(xxxx)} is called for the first time. The same
403     * locale is then always reused, even if the default system locale is
404     * changed. In order to enforce the creation of a new formatter, use
405     * the method {@link #enforceNumberFormatterReset()}.
406     * 
407     * @param val A value to be formatted as a string.
408     * @return A string representing the specifed value according to the current default locale.
409     */
410    public static String toString(double val) {
411            return getSingeltonNumberFormatter().format(val);
412    }
413    
414    } // class StringTools