001    /**
002     * Implements the CFML Function lsparsecurrency
003     */
004    package railo.runtime.functions.international;
005    
006    import java.text.NumberFormat;
007    import java.text.ParseException;
008    import java.text.ParsePosition;
009    import java.util.Locale;
010    import java.util.WeakHashMap;
011    
012    import railo.runtime.PageContext;
013    import railo.runtime.exp.ExpressionException;
014    import railo.runtime.exp.PageException;
015    import railo.runtime.ext.function.Function;
016    import railo.runtime.i18n.LocaleFactory;
017    import railo.runtime.op.Caster;
018    
019    
020    public final class LSParseCurrency implements Function {
021    
022            private static final long serialVersionUID = -7023441119083818436L;
023            private static WeakHashMap currFormatter=new WeakHashMap();
024            private static WeakHashMap numbFormatter=new WeakHashMap();
025    
026            public static String call(PageContext pc , String string) throws PageException {
027                    return Caster.toString(toDoubleValue(pc.getLocale(),string,false));
028            }
029            public static String call(PageContext pc , String string,String strLocale) throws PageException {
030                    return Caster.toString(toDoubleValue(strLocale==null?pc.getLocale():LocaleFactory.getLocale(strLocale),string,false));
031            }
032    
033            public static synchronized double toDoubleValue(Locale locale,String str) throws PageException {
034                    return toDoubleValue(locale, str, false);
035            }
036            
037            public static synchronized double toDoubleValue(Locale locale,String str, boolean strict) throws PageException {
038                    str=str.trim();
039                    NumberFormat cnf=getCurrencyInstance(locale);
040                    cnf.setParseIntegerOnly(false);
041                    try {
042                            return cnf.parse(str).doubleValue();
043                    } 
044                    catch (ParseException e) {
045                            String stripped=str.replaceFirst(cnf.getCurrency().getCurrencyCode(),"").trim();
046                            NumberFormat nf=getInstance(locale);
047                            
048                            ParsePosition pp = new ParsePosition(0);
049                            double d = nf.parse(stripped,pp).doubleValue();
050                            if (pp.getIndex() == 0 || (strict && stripped.length()!=pp.getIndex())) 
051                        throw new ExpressionException("Unparseable number [" + str + "]");
052                            
053                            return d;
054                    }
055            }
056            
057            private static NumberFormat getInstance(Locale locale) {
058                    Object o=numbFormatter.get(locale);
059                    if(o!=null) return (NumberFormat) o;
060                    
061                    NumberFormat nf=NumberFormat.getInstance(locale);
062                    numbFormatter.put(locale,nf);
063                    return nf;
064            }
065    
066            private static NumberFormat getCurrencyInstance(Locale locale) {
067                    Object o = currFormatter.get(locale);
068                    if(o!=null) return (NumberFormat) o;
069                    
070                    NumberFormat nf=NumberFormat.getCurrencyInstance(locale);
071                    currFormatter.put(locale,nf);
072                    return nf;
073            }
074    }