001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019package lucee.runtime.functions.international;
020
021import java.text.NumberFormat;
022import java.text.ParsePosition;
023import java.util.Locale;
024import java.util.WeakHashMap;
025
026import lucee.runtime.PageContext;
027import lucee.runtime.exp.ExpressionException;
028import lucee.runtime.exp.PageException;
029import lucee.runtime.ext.function.Function;
030import lucee.runtime.i18n.LocaleFactory;
031
032/**
033 * Implements the CFML Function lsparsecurrency
034 */
035public final class LSParseNumber implements Function {
036        
037        private static final long serialVersionUID = 2219030609677513651L;
038        
039        private static WeakHashMap<Locale,NumberFormat> whm=new WeakHashMap<Locale,NumberFormat>();
040
041        public static double call(PageContext pc , String string) throws PageException {
042                return toDoubleValue(pc.getLocale(),string);
043        }
044        
045        public static double call(PageContext pc , String string,String strLocale) throws PageException {
046                return toDoubleValue(strLocale==null?pc.getLocale():LocaleFactory.getLocale(strLocale),string);
047        }
048        
049        
050        public synchronized static double toDoubleValue(Locale locale,String str) throws PageException {
051                Object o=whm.get(locale);
052                NumberFormat nf=null;
053                if(o==null) {
054                        nf=NumberFormat.getInstance(locale);
055                        whm.put(locale,nf);
056                }
057                else {
058                        nf=(NumberFormat) o;
059                }
060                str=optimze(str.toCharArray());
061                
062                ParsePosition pp = new ParsePosition(0);
063        Number result = nf.parse(str, pp);
064                
065        if (pp.getIndex() < str.length()) {
066            throw new ExpressionException("can't parse String [" + str + "] against locale ["+LocaleFactory.toString(locale)+"] to a number");
067        }
068        if(result==null)
069                throw new ExpressionException("can't parse String [" + str + "] against locale ["+LocaleFactory.toString(locale)+"] to a number");
070        return result.doubleValue();
071                
072        }
073        
074        
075        private static String optimze(char[] carr) {
076                StringBuilder sb=new StringBuilder();
077                char c;
078                for(int i=0;i<carr.length;i++){
079                        c=carr[i];
080                        if(!Character.isWhitespace(c) && c!='+')sb.append(carr[i]);
081                }
082                
083                return sb.toString();
084        }
085
086        
087        
088}