001 package railo.transformer.bytecode.util; 002 003 import java.io.BufferedReader; 004 import java.io.Reader; 005 import java.util.Iterator; 006 import java.util.Map; 007 008 import javax.servlet.jsp.JspWriter; 009 import javax.servlet.jsp.tagext.BodyContent; 010 import javax.servlet.jsp.tagext.Tag; 011 012 import org.objectweb.asm.Type; 013 014 import railo.commons.io.IOUtil; 015 import railo.commons.io.res.Resource; 016 import railo.commons.lang.ClassException; 017 import railo.commons.lang.ClassUtil; 018 import railo.commons.lang.StringUtil; 019 import railo.runtime.InterfacePage; 020 import railo.runtime.Page; 021 import railo.runtime.PageContext; 022 import railo.runtime.PageContextImpl; 023 import railo.runtime.PagePlus; 024 import railo.runtime.PageSource; 025 import railo.runtime.component.ImportDefintion; 026 import railo.runtime.component.ImportDefintionImpl; 027 import railo.runtime.component.Member; 028 import railo.runtime.config.Config; 029 import railo.runtime.config.ConfigWeb; 030 import railo.runtime.exp.Abort; 031 import railo.runtime.exp.ExceptionHandler; 032 import railo.runtime.exp.PageException; 033 import railo.runtime.interpreter.VariableInterpreter; 034 import railo.runtime.op.Caster; 035 import railo.runtime.op.Operator; 036 import railo.runtime.poi.Excel; 037 import railo.runtime.poi.ExcelUtil; 038 import railo.runtime.security.SecurityManager; 039 import railo.runtime.type.Closure; 040 import railo.runtime.type.Collection; 041 import railo.runtime.type.FunctionValue; 042 import railo.runtime.type.Iteratorable; 043 import railo.runtime.type.UDF; 044 import railo.runtime.type.UDFImpl; 045 import railo.runtime.type.UDFProperties; 046 import railo.runtime.type.UDFPropertiesImpl; 047 import railo.runtime.type.ref.Reference; 048 import railo.runtime.type.ref.VariableReference; 049 import railo.runtime.type.scope.Scope; 050 import railo.runtime.type.scope.Undefined; 051 import railo.runtime.type.scope.Variables; 052 import railo.runtime.type.util.ArrayUtil; 053 import railo.runtime.type.util.ListUtil; 054 import railo.runtime.util.NumberRange; 055 import railo.runtime.writer.BodyContentUtil; 056 import railo.transformer.bytecode.BytecodeException; 057 058 public final class Types { 059 060 061 // TODO muss wohl alle Prim typen sein plus Object 062 public static final int _BOOLEAN=1; 063 public static final int _DOUBLE=2; 064 private static final int _SHORT=7; 065 066 public static final int _OBJECT=0; 067 public static final int _STRING=3; 068 069 070 private static final int _CHAR= _DOUBLE; 071 private static final int _FLOAT= _DOUBLE; 072 private static final int _LONG= _DOUBLE; 073 private static final int _INT= _DOUBLE; 074 private static final int _BYTE= _DOUBLE; 075 076 //public static final int SIZE_INT_TYPES=10; 077 078 079 080 081 public static final Type ABORT=Type.getType(Abort.class); 082 public static final Type ARRAY=Type.getType(railo.runtime.type.Array.class); 083 084 public static final Type BYTE=Type.getType(Byte.class); 085 public static final Type BYTE_VALUE=Type.getType(byte.class); 086 public static final Type BYTE_ARRAY=Type.getType(Byte[].class); 087 public static final Type BYTE_VALUE_ARRAY=Type.getType(byte[].class); 088 089 public static final Type BOOLEAN = Type.getType(Boolean.class); 090 public static final Type BOOLEAN_VALUE = Type.getType(boolean.class); 091 092 public static final Type CHAR=Type.getType(char.class); 093 public static final Type CHARACTER=Type.getType(Character.class); 094 095 public static final Type DOUBLE = Type.getType(Double.class); 096 public static final Type DOUBLE_VALUE = Type.getType(double.class); 097 098 public static final Type FLOAT = Type.getType(Float.class); 099 public static final Type FLOAT_VALUE = Type.getType(float.class); 100 101 public static final Type INTEGER = Type.getType(Integer.class); 102 public static final Type INT_VALUE = Type.getType(int.class); 103 104 public static final Type LONG = Type.getType(Long.class); 105 public static final Type LONG_VALUE = Type.getType(long.class); 106 107 public static final Type SHORT = Type.getType(Short.class); 108 public static final Type SHORT_VALUE = Type.getType(short.class); 109 110 public static final Type COMPONENT=Type.getType(railo.runtime.Component.class); 111 112 public final static Type PAGE=Type.getType(Page.class); 113 public final static Type PAGE_PLUS=Type.getType(PagePlus.class); 114 public final static Type PAGE_SOURCE=Type.getType(PageSource.class); 115 public static final Type COMPONENT_PAGE=Type.getType(railo.runtime.ComponentPage.class); 116 public static final Type INTERFACE_PAGE = Type.getType(InterfacePage.class); 117 118 public static final Type COMPONENT_IMPL=Type.getType(railo.runtime.ComponentImpl.class); 119 public static final Type INTERFACE_IMPL=Type.getType(railo.runtime.InterfaceImpl.class); 120 121 public static final Type DATE_TIME=Type.getType(railo.runtime.type.dt.DateTime.class); 122 123 public static final Type DATE=Type.getType(java.util.Date.class); 124 125 public static final Type FILE=Type.getType(java.io.File.class); 126 public static final Type EXCEL=Type.getType(Excel.class); 127 public static final Type EXCEL_UTIL=Type.getType(ExcelUtil.class); 128 129 public static final Type RESOURCE=Type.getType(Resource.class); 130 131 public static final Type FUNCTION_VALUE = Type.getType(FunctionValue.class); 132 133 public static final Type ITERATOR=Type.getType(Iterator.class); 134 public static final Type ITERATORABLE=Type.getType(Iteratorable.class); 135 136 public static final Type NODE=Type.getType(org.w3c.dom.Node.class); 137 138 public static final Type OBJECT=Type.getType(Object.class); 139 140 public static final Type OBJECT_ARRAY=Type.getType(Object[].class); 141 142 public static final Type PAGE_CONTEXT=Type.getType(PageContext.class); 143 public static final Type PAGE_CONTEXT_IMPL=Type.getType(PageContextImpl.class); 144 145 146 public final static Type QUERY=Type.getType(railo.runtime.type.Query.class); 147 public final static Type QUERY_COLUMN=Type.getType(railo.runtime.type.QueryColumn.class); 148 149 public final static Type PAGE_EXCEPTION=Type.getType(PageException.class); 150 151 public final static Type REFERENCE=Type.getType(Reference.class); 152 153 public static final Type CASTER = Type.getType(Caster.class); 154 155 public static final Type COLLECTION = Type.getType(Collection.class); 156 157 public static final Type STRING = Type.getType(String.class); 158 public static final Type STRING_ARRAY = Type.getType(String[].class); 159 160 public static final Type STRUCT = Type.getType(railo.runtime.type.Struct.class); 161 162 public static final Type OPERATOR = Type.getType(Operator.class); 163 164 public static final Type CONFIG = Type.getType(Config.class); 165 public static final Type CONFIG_WEB = Type.getType(ConfigWeb.class); 166 167 public static final Type SCOPE = Type.getType(Scope.class); 168 public static final Type VARIABLES = Type.getType(Variables.class); 169 170 public static final Type TIMESPAN = Type.getType(railo.runtime.type.dt.TimeSpan.class); 171 172 public static final Type THROWABLE = Type.getType(Throwable.class); 173 public static final Type EXCEPTION = Type.getType(Exception.class); 174 175 public static final Type VOID = Type.VOID_TYPE; 176 177 public static final Type LIST_UTIL = Type.getType(ListUtil.class); 178 public static final Type VARIABLE_INTERPRETER = Type.getType(VariableInterpreter.class); 179 public static final Type VARIABLE_REFERENCE = Type.getType(VariableReference.class); 180 public static final Type JSP_WRITER = Type.getType(JspWriter.class); 181 public static final Type TAG = Type.getType(Tag.class); 182 public static final Type NUMBER_RANGE = Type.getType(NumberRange.class); 183 public static final Type SECURITY_MANAGER = Type.getType(SecurityManager.class); 184 public static final Type READER = Type.getType(Reader.class); 185 public static final Type BUFFERED_READER = Type.getType(BufferedReader.class); 186 public static final Type ARRAY_UTIL = Type.getType(ArrayUtil.class); 187 public static final Type EXCEPTION_HANDLER = Type.getType(ExceptionHandler.class); 188 //public static final Type RETURN_ EXCEPTION = Type.getType(ReturnException.class); 189 public static final Type TIMEZONE = Type.getType(java.util.TimeZone.class); 190 public static final Type STRING_BUFFER = Type.getType(StringBuffer.class); 191 public static final Type MEMBER = Type.getType(Member.class); 192 public static final Type UDF = Type.getType(UDF.class); 193 public static final Type UDF_PROPERTIES = Type.getType(UDFProperties.class); 194 public static final Type UDF_PROPERTIES_IMPL = Type.getType(UDFPropertiesImpl.class); 195 public static final Type UDF_IMPL = Type.getType(UDFImpl.class); 196 public static final Type CLOSURE = Type.getType(Closure.class); 197 public static final Type UDF_PROPERTIES_ARRAY = Type.getType(UDFProperties[].class); 198 public static final Type UDF_IMPL_ARRAY = Type.getType(UDFImpl[].class); 199 public static final Type COLLECTION_KEY = Type.getType(Collection.Key.class); 200 public static final Type COLLECTION_KEY_ARRAY = Type.getType(Collection.Key[].class); 201 public static final Type UNDEFINED = Type.getType(Undefined.class); 202 public static final Type MAP = Type.getType(Map.class); 203 public static final Type MAP_ENTRY = Type.getType(Map.Entry.class); 204 public static final Type CHAR_ARRAY = Type.getType(char[].class); 205 public static final Type IOUTIL = Type.getType(IOUtil.class); 206 public static final Type BODY_CONTENT = Type.getType(BodyContent.class); 207 public static final Type BODY_CONTENT_UTIL = Type.getType(BodyContentUtil.class); 208 public static final Type IMPORT_DEFINITIONS = Type.getType(ImportDefintion.class); 209 public static final Type IMPORT_DEFINITIONS_IMPL = Type.getType(ImportDefintionImpl.class); 210 public static final Type IMPORT_DEFINITIONS_ARRAY = Type.getType(ImportDefintion[].class); 211 public static final Type CLASS = Type.getType(Class.class); 212 public static final Type CLASS_ARRAY = Type.getType(Class[].class); 213 public static final Type CLASS_LOADER = Type.getType(ClassLoader.class); 214 215 216 /** 217 * translate sString classname to a real type 218 * @param type 219 * @return 220 * @throws railo.runtime.exp.TemplateExceptionption 221 */ 222 public static Type toType(String type) throws BytecodeException { 223 if(type==null) return OBJECT; 224 type=type.trim(); 225 String lcType=StringUtil.toLowerCase(type); 226 char first=lcType.charAt(0); 227 228 switch(first) { 229 case 'a': 230 if("any".equals(lcType)) return OBJECT; 231 if("array".equals(lcType)) return ARRAY; 232 break; 233 case 'b': 234 if("base64".equals(lcType)) return STRING; 235 if("binary".equals(lcType)) return BYTE_VALUE_ARRAY; 236 if("bool".equals(lcType) || "boolean".equals(type)) return BOOLEAN_VALUE; 237 if("boolean".equals(lcType)) return BOOLEAN; 238 if("byte".equals(type)) return BYTE_VALUE; 239 if("byte".equals(lcType)) return BYTE; 240 break; 241 case 'c': 242 if("char".equals(lcType)) return CHAR; 243 if("character".equals(lcType)) return CHARACTER; 244 if("collection".equals(lcType)) return BYTE_VALUE_ARRAY; 245 if("component".equals(lcType)) return COMPONENT; 246 break; 247 case 'd': 248 if("date".equals(lcType) || "datetime".equals(lcType)) return DATE_TIME; 249 if("decimal".equals(lcType)) return STRING; 250 if("double".equals(type)) return DOUBLE_VALUE; 251 if("double".equals(lcType)) return DOUBLE; 252 break; 253 case 'e': 254 if("excel".equals(lcType)) return EXCEL; 255 break; 256 case 'f': 257 if("file".equals(lcType)) return FILE; 258 if("float".equals(type)) return FLOAT_VALUE; 259 if("float".equals(lcType)) return FLOAT; 260 if("function".equals(lcType)) return UDF; 261 break; 262 case 'i': 263 if("int".equals(lcType)) return INT_VALUE; 264 else if("integer".equals(lcType)) return INTEGER; 265 break; 266 case 'j': 267 if("java.lang.boolean".equals(lcType)) return BOOLEAN; 268 if("java.lang.byte".equals(lcType)) return BYTE; 269 if("java.lang.character".equals(lcType)) return CHARACTER; 270 if("java.lang.short".equals(lcType)) return SHORT; 271 if("java.lang.integer".equals(lcType)) return INTEGER; 272 if("java.lang.long".equals(lcType)) return LONG; 273 if("java.lang.float".equals(lcType)) return FLOAT; 274 if("java.lang.double".equals(lcType)) return DOUBLE; 275 if("java.io.file".equals(lcType)) return FILE; 276 if("java.lang.string".equals(lcType)) return STRING; 277 if("java.lang.string[]".equals(lcType)) return STRING_ARRAY; 278 if("java.util.date".equals(lcType)) return DATE; 279 if("java.lang.object".equals(lcType)) return OBJECT; 280 break; 281 case 'l': 282 if("long".equals(type)) return LONG_VALUE; 283 if("long".equals(lcType)) return LONG; 284 if("long".equals(lcType)) return LONG; 285 break; 286 case 'n': 287 if("node".equals(lcType)) return NODE; 288 if("number".equals(lcType)) return DOUBLE_VALUE; 289 if("numeric".equals(lcType)) return DOUBLE_VALUE; 290 break; 291 case 'o': 292 if("object".equals(lcType)) return OBJECT; 293 break; 294 case 's': 295 if("string".equals(lcType)) return STRING; 296 if("struct".equals(lcType)) return STRUCT; 297 if("short".equals(type)) return SHORT_VALUE; 298 if("short".equals(lcType)) return SHORT; 299 break; 300 case 'u': 301 if("udf".equals(lcType)) return UDF; 302 break; 303 case 'v': 304 if("void".equals(lcType)) return VOID; 305 if("variablestring".equals(lcType)) return STRING; 306 if("variable_string".equals(lcType)) return STRING; 307 break; 308 case 'x': 309 if("xml".equals(lcType)) return NODE; 310 break; 311 case '[': 312 if("[Ljava.lang.String;".equals(lcType)) return STRING_ARRAY; 313 break; 314 315 316 317 default: 318 if("query".equals(lcType)) return QUERY; 319 if("querycolumn".equals(lcType)) return QUERY_COLUMN; 320 if("timespan".equals(lcType)) return TIMESPAN; 321 } 322 323 // TODO Array als Lbyte und auch byte[] 324 325 try { 326 return Type.getType(ClassUtil.loadClass(type)); 327 } catch (ClassException e) { 328 throw new BytecodeException(e,null); 329 } 330 } 331 332 /** 333 * returns if given type is a "primitve" type or in other words a value type (no reference type, no object) 334 * @param type 335 * @return 336 */ 337 public static boolean isPrimitiveType(int type) { 338 return type!=_OBJECT && type!=_STRING; 339 } 340 341 /** 342 * returns if given type is a "primitve" type or in other words a value type (no reference type, no object) 343 * @param type 344 * @return 345 */ 346 public static boolean isPrimitiveType(Type type) { 347 String className=type.getClassName(); 348 if(className.indexOf('.')!=-1) return false; 349 350 if("boolean".equals(className)) return true; 351 if("short".equals(className)) return true; 352 if("float".equals(className)) return true; 353 if("long".equals(className)) return true; 354 if("double".equals(className)) return true; 355 if("char".equals(className)) return true; 356 if("int".equals(className)) return true; 357 if("byte".equals(className)) return true; 358 359 return false; 360 } 361 public static int getType(Type type) { 362 String className=type.getClassName(); 363 if(className.indexOf('.')!=-1) { 364 if("java.lang.String".equalsIgnoreCase(className)) return _STRING; 365 return _OBJECT; 366 } 367 368 if("boolean".equals(className)) return _BOOLEAN; 369 if("short".equals(className)) return _SHORT; 370 if("float".equals(className)) return _FLOAT; 371 if("long".equals(className)) return _LONG; 372 if("double".equals(className)) return _DOUBLE; 373 if("char".equals(className)) return _CHAR; 374 if("int".equals(className)) return _INT; 375 if("byte".equals(className)) return _BYTE; 376 377 return _OBJECT; 378 } 379 380 public static Type toRefType(Type type) { 381 String className=type.getClassName(); 382 if(className.indexOf('.')!=-1) return type; 383 384 if("boolean".equals(className)) return BOOLEAN; 385 if("short".equals(className)) return SHORT; 386 if("float".equals(className)) return FLOAT; 387 if("long".equals(className)) return LONG; 388 if("double".equals(className)) return DOUBLE; 389 if("char".equals(className)) return CHARACTER; 390 if("int".equals(className)) return INT_VALUE; 391 if("byte".equals(className)) return BYTE; 392 return type; 393 } 394 395 396 397 }