/**
*
* Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
**/
/**
* Implements the CFML Function javacast
*/
package lucee.runtime.functions.string;
import java.math.BigDecimal;
import java.math.BigInteger;
import lucee.commons.lang.ClassException;
import lucee.commons.lang.ClassUtil;
import lucee.commons.lang.StringUtil;
import lucee.runtime.PageContext;
import lucee.runtime.exp.ExpressionException;
import lucee.runtime.exp.PageException;
import lucee.runtime.ext.function.Function;
import lucee.runtime.op.Caster;
import lucee.runtime.op.Decision;
public final class JavaCast implements Function {
private static final long serialVersionUID = -5053403312467568511L;
public static Object calls(PageContext pc , String string, Object object) throws PageException {
throw new ExpressionException("method javacast not implemented yet"); // MUST ????
}
public static Object call(PageContext pc , String type, Object obj) throws PageException {
type=type.trim();
String lcType=StringUtil.toLowerCase(type);
if(type.endsWith("[]")) {
return toArray(pc,type, lcType, obj);
}
Class<?> clazz = toClass(pc, lcType, type);
return to(pc,obj,clazz);
}
public static Object toArray(PageContext pc,String type,String lcType, Object obj) throws PageException {
// byte
if("byte[]".equals(lcType)) {
if(obj instanceof byte[]) return (byte[])obj;
if(Decision.isBinary(obj)) return Caster.toBinary(obj);
}
// char
else if("char[]".equals(lcType)) {
if(obj instanceof char[]) return (char[])obj;
if(obj instanceof CharSequence) return obj.toString().toCharArray();
}
return _toArray(pc, type, lcType, obj);
}
public static Object _toArray(PageContext pc,String type,String lcType, Object obj) throws PageException {
lcType=lcType.substring(0,lcType.length()-2);
type=type.substring(0,type.length()-2);
// other
Object[] arr = Caster.toList(obj).toArray();
Class<?> clazz = toClass(pc, lcType, type);
Object trg = java.lang.reflect.Array.newInstance(clazz, arr.length);
for(int i=arr.length-1;i>=0;i--) {
java.lang.reflect.Array.set(trg, i, type.endsWith("[]")?_toArray(pc, type, lcType, arr[i]):to(pc,arr[i],clazz));
}
return trg;
}
private static Object to(PageContext pc, Object obj,Class<?> trgClass) throws PageException {
if(trgClass==null)return Caster.toNull(obj);
else if(trgClass==BigDecimal.class)return Caster.toBigDecimal(obj);
else if(trgClass==BigInteger.class)return Caster.toBigInteger(obj);
return Caster.castTo(pc, trgClass, obj);
//throw new ExpressionException("can't cast only to the following data types (bigdecimal,int, long, float ,double ,boolean ,string,null ), "+lcType+" is invalid");
}
private static Class<?> toClass(PageContext pc,String lcType, String type) throws PageException {
if(lcType.equals("null")){
return null;
}
if(lcType.equals("biginteger")){
return BigInteger.class;
}
if(lcType.equals("bigdecimal")){
return BigDecimal.class;
}
try {
return ClassUtil.toClass(type);
} catch (ClassException e) {
throw Caster.toPageException(e);
}
}
}