package railo.transformer.bytecode.util;
import java.io.BufferedReader;
import java.io.Reader;
import java.math.BigDecimal;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.Tag;
import org.objectweb.asm.Type;
import railo.commons.io.IOUtil;
import railo.commons.io.res.Resource;
import railo.commons.lang.ClassException;
import railo.commons.lang.ClassUtil;
import railo.commons.lang.StringUtil;
import railo.runtime.InterfacePage;
import railo.runtime.Page;
import railo.runtime.PageContext;
import railo.runtime.PageContextImpl;
import railo.runtime.PagePlus;
import railo.runtime.PageSource;
import railo.runtime.component.ImportDefintion;
import railo.runtime.component.ImportDefintionImpl;
import railo.runtime.component.Member;
import railo.runtime.config.Config;
import railo.runtime.config.ConfigWeb;
import railo.runtime.exp.Abort;
import railo.runtime.exp.ExceptionHandler;
import railo.runtime.exp.PageException;
import railo.runtime.interpreter.VariableInterpreter;
import railo.runtime.op.Caster;
import railo.runtime.op.Operator;
import railo.runtime.poi.Excel;
import railo.runtime.poi.ExcelUtil;
import railo.runtime.security.SecurityManager;
import railo.runtime.type.Array;
import railo.runtime.type.Closure;
import railo.runtime.type.Collection;
import railo.runtime.type.FunctionValue;
import railo.runtime.type.Iteratorable;
import railo.runtime.type.Query;
import railo.runtime.type.Struct;
import railo.runtime.type.UDF;
import railo.runtime.type.UDFImpl;
import railo.runtime.type.UDFProperties;
import railo.runtime.type.UDFPropertiesImpl;
import railo.runtime.type.ref.Reference;
import railo.runtime.type.ref.VariableReference;
import railo.runtime.type.scope.Scope;
import railo.runtime.type.scope.Undefined;
import railo.runtime.type.scope.Variables;
import railo.runtime.type.util.ArrayUtil;
import railo.runtime.type.util.ListUtil;
import railo.runtime.util.NumberRange;
import railo.runtime.writer.BodyContentUtil;
import railo.transformer.bytecode.BytecodeException;
public final class Types {
// TODO muss wohl alle Prim typen sein plus Object
public static final int _BOOLEAN=1;
public static final int _DOUBLE=2;
private static final int _SHORT=7;
public static final int _OBJECT=0;
public static final int _STRING=3;
private static final int _CHAR= _DOUBLE;
private static final int _FLOAT= _DOUBLE;
private static final int _LONG= _DOUBLE;
private static final int _INT= _DOUBLE;
private static final int _BYTE= _DOUBLE;
//public static final int SIZE_INT_TYPES=10;
public static final Type ABORT=Type.getType(Abort.class);
public static final Type ARRAY=Type.getType(railo.runtime.type.Array.class);
public static final Type BYTE=Type.getType(Byte.class);
public static final Type BYTE_VALUE=Type.getType(byte.class);
public static final Type BYTE_ARRAY=Type.getType(Byte[].class);
public static final Type BYTE_VALUE_ARRAY=Type.getType(byte[].class);
public static final Type BOOLEAN = Type.getType(Boolean.class);
public static final Type BOOLEAN_VALUE = Type.getType(boolean.class);
public static final Type CHAR=Type.getType(char.class);
public static final Type CHARACTER=Type.getType(Character.class);
public static final Type DOUBLE = Type.getType(Double.class);
public static final Type DOUBLE_VALUE = Type.getType(double.class);
public static final Type FLOAT = Type.getType(Float.class);
public static final Type FLOAT_VALUE = Type.getType(float.class);
public static final Type INTEGER = Type.getType(Integer.class);
public static final Type INT_VALUE = Type.getType(int.class);
public static final Type LONG = Type.getType(Long.class);
public static final Type LONG_VALUE = Type.getType(long.class);
public static final Type SHORT = Type.getType(Short.class);
public static final Type SHORT_VALUE = Type.getType(short.class);
public static final Type COMPONENT=Type.getType(railo.runtime.Component.class);
public final static Type PAGE=Type.getType(Page.class);
public final static Type PAGE_PLUS=Type.getType(PagePlus.class);
public final static Type PAGE_SOURCE=Type.getType(PageSource.class);
public static final Type COMPONENT_PAGE=Type.getType(railo.runtime.ComponentPage.class);
public static final Type INTERFACE_PAGE = Type.getType(InterfacePage.class);
public static final Type COMPONENT_IMPL=Type.getType(railo.runtime.ComponentImpl.class);
public static final Type INTERFACE_IMPL=Type.getType(railo.runtime.InterfaceImpl.class);
public static final Type DATE_TIME=Type.getType(railo.runtime.type.dt.DateTime.class);
public static final Type DATE=Type.getType(java.util.Date.class);
public static final Type FILE=Type.getType(java.io.File.class);
public static final Type EXCEL=Type.getType(Excel.class);
public static final Type EXCEL_UTIL=Type.getType(ExcelUtil.class);
public static final Type RESOURCE=Type.getType(Resource.class);
public static final Type FUNCTION_VALUE = Type.getType(FunctionValue.class);
public static final Type ITERATOR=Type.getType(Iterator.class);
public static final Type ITERATORABLE=Type.getType(Iteratorable.class);
public static final Type NODE=Type.getType(org.w3c.dom.Node.class);
public static final Type OBJECT=Type.getType(Object.class);
public static final Type OBJECT_ARRAY=Type.getType(Object[].class);
public static final Type PAGE_CONTEXT=Type.getType(PageContext.class);
public static final Type PAGE_CONTEXT_IMPL=Type.getType(PageContextImpl.class);
public final static Type QUERY=Type.getType(railo.runtime.type.Query.class);
public final static Type QUERY_COLUMN=Type.getType(railo.runtime.type.QueryColumn.class);
public final static Type PAGE_EXCEPTION=Type.getType(PageException.class);
public final static Type REFERENCE=Type.getType(Reference.class);
public static final Type CASTER = Type.getType(Caster.class);
public static final Type COLLECTION = Type.getType(Collection.class);
public static final Type STRING = Type.getType(String.class);
public static final Type STRING_ARRAY = Type.getType(String[].class);
public static final Type STRUCT = Type.getType(railo.runtime.type.Struct.class);
public static final Type OPERATOR = Type.getType(Operator.class);
public static final Type CONFIG = Type.getType(Config.class);
public static final Type CONFIG_WEB = Type.getType(ConfigWeb.class);
public static final Type SCOPE = Type.getType(Scope.class);
public static final Type VARIABLES = Type.getType(Variables.class);
public static final Type TIMESPAN = Type.getType(railo.runtime.type.dt.TimeSpan.class);
public static final Type THROWABLE = Type.getType(Throwable.class);
public static final Type EXCEPTION = Type.getType(Exception.class);
public static final Type VOID = Type.VOID_TYPE;
public static final Type LIST_UTIL = Type.getType(ListUtil.class);
public static final Type VARIABLE_INTERPRETER = Type.getType(VariableInterpreter.class);
public static final Type VARIABLE_REFERENCE = Type.getType(VariableReference.class);
public static final Type JSP_WRITER = Type.getType(JspWriter.class);
public static final Type TAG = Type.getType(Tag.class);
public static final Type NUMBER_RANGE = Type.getType(NumberRange.class);
public static final Type SECURITY_MANAGER = Type.getType(SecurityManager.class);
public static final Type READER = Type.getType(Reader.class);
public static final Type BUFFERED_READER = Type.getType(BufferedReader.class);
public static final Type ARRAY_UTIL = Type.getType(ArrayUtil.class);
public static final Type EXCEPTION_HANDLER = Type.getType(ExceptionHandler.class);
//public static final Type RETURN_ EXCEPTION = Type.getType(ReturnException.class);
public static final Type TIMEZONE = Type.getType(java.util.TimeZone.class);
public static final Type STRING_BUFFER = Type.getType(StringBuffer.class);
public static final Type MEMBER = Type.getType(Member.class);
public static final Type UDF = Type.getType(UDF.class);
public static final Type UDF_PROPERTIES = Type.getType(UDFProperties.class);
public static final Type UDF_PROPERTIES_IMPL = Type.getType(UDFPropertiesImpl.class);
public static final Type UDF_IMPL = Type.getType(UDFImpl.class);
public static final Type CLOSURE = Type.getType(Closure.class);
public static final Type UDF_PROPERTIES_ARRAY = Type.getType(UDFProperties[].class);
//public static final Type UDF_IMPL_ARRAY = Type.getType(UDFImpl[].class);
public static final Type COLLECTION_KEY = Type.getType(Collection.Key.class);
public static final Type COLLECTION_KEY_ARRAY = Type.getType(Collection.Key[].class);
public static final Type UNDEFINED = Type.getType(Undefined.class);
public static final Type MAP = Type.getType(Map.class);
public static final Type MAP_ENTRY = Type.getType(Map.Entry.class);
public static final Type CHAR_ARRAY = Type.getType(char[].class);
public static final Type IOUTIL = Type.getType(IOUtil.class);
public static final Type BODY_CONTENT = Type.getType(BodyContent.class);
public static final Type BODY_CONTENT_UTIL = Type.getType(BodyContentUtil.class);
public static final Type IMPORT_DEFINITIONS = Type.getType(ImportDefintion.class);
public static final Type IMPORT_DEFINITIONS_IMPL = Type.getType(ImportDefintionImpl.class);
public static final Type IMPORT_DEFINITIONS_ARRAY = Type.getType(ImportDefintion[].class);
public static final Type CLASS = Type.getType(Class.class);
public static final Type CLASS_ARRAY = Type.getType(Class[].class);
public static final Type CLASS_LOADER = Type.getType(ClassLoader.class);
public static final Type BIG_DECIMAL = Type.getType(BigDecimal.class);
/**
* translate sString classname to a real type
* @param type
* @return
* @throws railo.runtime.exp.TemplateExceptionption
*/
public static Type toType(String type) throws BytecodeException {
if(type==null) return OBJECT;
type=type.trim();
String lcType=StringUtil.toLowerCase(type);
char first=lcType.charAt(0);
switch(first) {
case 'a':
if("any".equals(lcType)) return OBJECT;
if("array".equals(lcType)) return ARRAY;
break;
case 'b':
if("base64".equals(lcType)) return STRING;
if("binary".equals(lcType)) return BYTE_VALUE_ARRAY;
if("bool".equals(lcType) || "boolean".equals(type)) return BOOLEAN_VALUE;
if("boolean".equals(lcType)) return BOOLEAN;
if("byte".equals(type)) return BYTE_VALUE;
if("byte".equals(lcType)) return BYTE;
break;
case 'c':
if("char".equals(lcType)) return CHAR;
if("character".equals(lcType)) return CHARACTER;
if("collection".equals(lcType)) return BYTE_VALUE_ARRAY;
if("component".equals(lcType)) return COMPONENT;
break;
case 'd':
if("date".equals(lcType) || "datetime".equals(lcType)) return DATE_TIME;
if("decimal".equals(lcType)) return STRING;
if("double".equals(type)) return DOUBLE_VALUE;
if("double".equals(lcType)) return DOUBLE;
break;
case 'e':
if("excel".equals(lcType)) return EXCEL;
break;
case 'f':
if("file".equals(lcType)) return FILE;
if("float".equals(type)) return FLOAT_VALUE;
if("float".equals(lcType)) return FLOAT;
if("function".equals(lcType)) return UDF;
break;
case 'i':
if("int".equals(lcType)) return INT_VALUE;
else if("integer".equals(lcType)) return INTEGER;
break;
case 'j':
if("java.lang.boolean".equals(lcType)) return BOOLEAN;
if("java.lang.byte".equals(lcType)) return BYTE;
if("java.lang.character".equals(lcType)) return CHARACTER;
if("java.lang.short".equals(lcType)) return SHORT;
if("java.lang.integer".equals(lcType)) return INTEGER;
if("java.lang.long".equals(lcType)) return LONG;
if("java.lang.float".equals(lcType)) return FLOAT;
if("java.lang.double".equals(lcType)) return DOUBLE;
if("java.io.file".equals(lcType)) return FILE;
if("java.lang.string".equals(lcType)) return STRING;
if("java.lang.string[]".equals(lcType)) return STRING_ARRAY;
if("java.util.date".equals(lcType)) return DATE;
if("java.lang.object".equals(lcType)) return OBJECT;
break;
case 'l':
if("long".equals(type)) return LONG_VALUE;
if("long".equals(lcType)) return LONG;
if("long".equals(lcType)) return LONG;
break;
case 'n':
if("node".equals(lcType)) return NODE;
if("number".equals(lcType)) return DOUBLE_VALUE;
if("numeric".equals(lcType)) return DOUBLE_VALUE;
break;
case 'o':
if("object".equals(lcType)) return OBJECT;
break;
case 's':
if("string".equals(lcType)) return STRING;
if("struct".equals(lcType)) return STRUCT;
if("short".equals(type)) return SHORT_VALUE;
if("short".equals(lcType)) return SHORT;
break;
case 'u':
if("udf".equals(lcType)) return UDF;
break;
case 'v':
if("void".equals(lcType)) return VOID;
if("variablestring".equals(lcType)) return STRING;
if("variable_string".equals(lcType)) return STRING;
break;
case 'x':
if("xml".equals(lcType)) return NODE;
break;
case '[':
if("[Ljava.lang.String;".equals(lcType)) return STRING_ARRAY;
break;
default:
if("query".equals(lcType)) return QUERY;
if("querycolumn".equals(lcType)) return QUERY_COLUMN;
if("timespan".equals(lcType)) return TIMESPAN;
}
// TODO Array als Lbyte und auch byte[]
try {
return Type.getType(ClassUtil.loadClass(type));
} catch (ClassException e) {
throw new BytecodeException(e,null);
}
}
/**
* returns if given type is a "primitve" type or in other words a value type (no reference type, no object)
* @param type
* @return
*/
public static boolean isPrimitiveType(int type) {
return type!=_OBJECT && type!=_STRING;
}
/**
* returns if given type is a "primitve" type or in other words a value type (no reference type, no object)
* @param type
* @return
*/
public static boolean isPrimitiveType(Type type) {
String className=type.getClassName();
if(className.indexOf('.')!=-1) return false;
if("boolean".equals(className)) return true;
if("short".equals(className)) return true;
if("float".equals(className)) return true;
if("long".equals(className)) return true;
if("double".equals(className)) return true;
if("char".equals(className)) return true;
if("int".equals(className)) return true;
if("byte".equals(className)) return true;
return false;
}
public static int getType(Type type) {
String className=type.getClassName();
if(className.indexOf('.')!=-1) {
if("java.lang.String".equalsIgnoreCase(className)) return _STRING;
return _OBJECT;
}
if("boolean".equals(className)) return _BOOLEAN;
if("short".equals(className)) return _SHORT;
if("float".equals(className)) return _FLOAT;
if("long".equals(className)) return _LONG;
if("double".equals(className)) return _DOUBLE;
if("char".equals(className)) return _CHAR;
if("int".equals(className)) return _INT;
if("byte".equals(className)) return _BYTE;
return _OBJECT;
}
public static Type toRefType(Type type) {
String className=type.getClassName();
if(className.indexOf('.')!=-1) return type;
if("boolean".equals(className)) return BOOLEAN;
if("short".equals(className)) return SHORT;
if("float".equals(className)) return FLOAT;
if("long".equals(className)) return LONG;
if("double".equals(className)) return DOUBLE;
if("char".equals(className)) return CHARACTER;
if("int".equals(className)) return INT_VALUE;
if("byte".equals(className)) return BYTE;
return type;
}
public static Class toClass(Type type) throws ClassException {
if(Types.STRING==type) return String.class;
if(Types.BOOLEAN_VALUE==type) return boolean.class;
if(Types.DOUBLE_VALUE==type) return double.class;
if(Types.PAGE_CONTEXT==type) return PageContext.class;
if(Types.OBJECT==type) return Object.class;
if(Types.STRUCT==type) return Struct.class;
if(Types.ARRAY==type) return Array.class;
if(Types.COLLECTION_KEY==type) return Collection.Key.class;
if(Types.COLLECTION_KEY_ARRAY==type) return Collection.Key[].class;
if(Types.QUERY==type) return Query.class;
if(Types.DATE_TIME==type) return railo.runtime.type.dt.DateTime.class;
return ClassUtil.toClass(type.getClassName());
}
}