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