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 **/
019/**
020 * Implements the CFML Function javacast
021 */
022package lucee.runtime.functions.string;
023
024import java.math.BigDecimal;
025import java.math.BigInteger;
026
027import lucee.commons.lang.ClassException;
028import lucee.commons.lang.ClassUtil;
029import lucee.commons.lang.StringUtil;
030import lucee.runtime.PageContext;
031import lucee.runtime.exp.ExpressionException;
032import lucee.runtime.exp.PageException;
033import lucee.runtime.ext.function.Function;
034import lucee.runtime.op.Caster;
035import lucee.runtime.type.Array;
036
037public final class JavaCast implements Function {
038
039        private static final long serialVersionUID = -5053403312467568511L;
040
041        public static Object calls(PageContext pc , String string, Object object) throws PageException {
042                throw new ExpressionException("method javacast not implemented yet"); // MUST ????
043        }
044        public static Object call(PageContext pc , String type, Object obj) throws PageException {
045                type=type.trim();
046                String lcType=StringUtil.toLowerCase(type);
047                
048                if(type.endsWith("[]")){
049                        return toArray(pc,type, lcType, obj);
050                        
051                }
052                Class clazz = toClass(pc, lcType, type);
053                return to(pc,obj,clazz);
054                
055        }
056        
057        public static Object toArray(PageContext pc,String type,String lcType, Object obj) throws PageException {
058                lcType=lcType.substring(0,lcType.length()-2);
059                type=type.substring(0,type.length()-2);
060                
061                
062                
063                Array arr = Caster.toArray(obj);
064                Class clazz = toClass(pc, lcType, type);
065                Object trg= java.lang.reflect.Array.newInstance(clazz, arr.size());
066                
067                
068                for(int i=arr.size()-1;i>=0;i--) {
069                        java.lang.reflect.Array.set(trg, i,to(pc,arr.getE(i+1),clazz));
070                        
071                }
072                return trg;
073        }
074        
075        
076        private static Object to(PageContext pc, Object obj,Class trgClass) throws PageException {
077                if(trgClass==null)return Caster.toNull(obj); 
078                else if(trgClass==BigDecimal.class)return new BigDecimal(Caster.toString(obj)); 
079                else if(trgClass==BigInteger.class)return new BigInteger(Caster.toString(obj)); 
080                return Caster.castTo(pc, trgClass, obj);
081                //throw new ExpressionException("can't cast only to the following data types (bigdecimal,int, long, float ,double ,boolean ,string,null ), "+lcType+" is invalid");
082        }
083        
084        private static Class toClass(PageContext pc,String lcType, String type) throws PageException {
085                 
086                if(lcType.equals("null")){
087                        return null; 
088                }  
089                if(lcType.equals("biginteger")){
090                        return BigInteger.class; 
091                }  
092                if(lcType.equals("bigdecimal")){
093                        return BigDecimal.class; 
094                } 
095                try {
096                        return ClassUtil.toClass(type);
097                } catch (ClassException e) {
098                        throw Caster.toPageException(e);
099                }
100        }
101        
102}