001    package railo.runtime.java;
002    
003    import java.lang.reflect.Field;
004    import java.lang.reflect.InvocationTargetException;
005    import java.lang.reflect.Modifier;
006    import java.util.Date;
007    
008    import railo.runtime.PageContext;
009    import railo.runtime.dump.DumpData;
010    import railo.runtime.dump.DumpProperties;
011    import railo.runtime.dump.DumpUtil;
012    import railo.runtime.exp.ExpressionException;
013    import railo.runtime.exp.PageException;
014    import railo.runtime.op.Caster;
015    import railo.runtime.op.Operator;
016    import railo.runtime.op.date.DateCaster;
017    import railo.runtime.reflection.Reflector;
018    import railo.runtime.reflection.pairs.MethodInstance;
019    import railo.runtime.type.Collection;
020    import railo.runtime.type.ObjectWrap;
021    import railo.runtime.type.Objects;
022    import railo.runtime.type.Struct;
023    import railo.runtime.type.dt.DateTime;
024    import railo.runtime.type.util.ArrayUtil;
025    import railo.runtime.util.VariableUtil;
026    
027    
028    /**
029     * class to handle initialising and call native object from railo
030     */
031    public class JavaObject implements Objects,ObjectWrap {
032            
033            private Class clazz;
034            private boolean isInit=false;
035            private Object object;
036        private VariableUtil variableUtil;
037        
038            /**
039             * constructor with className to load
040             * @param variableUtil
041             * @param clazz
042             * @throws ExpressionException
043             */
044            public JavaObject(VariableUtil variableUtil,Class clazz) {
045                this.variableUtil=variableUtil;
046                    this.clazz=clazz;
047            }
048    
049    
050            public JavaObject(VariableUtil variableUtil,Object object) {
051                this.variableUtil=variableUtil;
052                    this.clazz=object.getClass();
053                    this.object=object;
054                    isInit=true;
055            }
056    
057            /**
058             * @see railo.runtime.type.Objects#get(railo.runtime.PageContext, java.lang.String)
059             */
060            public Object get(PageContext pc, String propertyName) throws PageException {
061            if(isInit) {
062                return variableUtil.get(pc,object,propertyName);
063            }
064                
065            // Check Field
066                Field[] fields = Reflector.getFieldsIgnoreCase(clazz,propertyName,null);
067                if(!ArrayUtil.isEmpty(fields) && Modifier.isStatic(fields[0].getModifiers())) {
068                            try {
069                        return fields[0].get(null);
070                    } 
071                    catch (Exception e) {
072                        throw Caster.toPageException(e);
073                    }
074                    }
075            // Getter
076                MethodInstance mi = Reflector.getGetterEL(clazz,propertyName);
077                if(mi!=null) {
078                    if(Modifier.isStatic(mi.getMethod().getModifiers())) {
079                        try {
080                            return mi.invoke(null);
081                        } 
082                        catch (IllegalAccessException e) {
083                            throw Caster.toPageException(e);
084                        } 
085                        catch (InvocationTargetException e) {
086                            throw Caster.toPageException(e.getTargetException());
087                        }    
088                    }
089                }
090            // male Instance
091            return variableUtil.get(pc,init(),propertyName);  
092            }
093    
094            /**
095             *
096             * @see railo.runtime.type.Objects#get(railo.runtime.PageContext, railo.runtime.type.Collection.Key)
097             */
098            public Object get(PageContext pc, Collection.Key key) throws PageException {
099                    return get(pc, key.getString());
100            }
101    
102        public Object get(PageContext pc, String propertyName, Object defaultValue) {
103            if(isInit) {
104                return variableUtil.get(pc,object,propertyName,defaultValue);  
105            }
106            // Field
107            Field[] fields = Reflector.getFieldsIgnoreCase(clazz,propertyName,null);
108            if(!ArrayUtil.isEmpty(fields) && Modifier.isStatic(fields[0].getModifiers())) {
109                            try {
110                    return fields[0].get(null);
111                } catch (Exception e) {}
112                    }
113            // Getter
114            MethodInstance mi = Reflector.getGetterEL(clazz,propertyName);
115            if(mi!=null) {
116                if(Modifier.isStatic(mi.getMethod().getModifiers())) {
117                    try {
118                        return mi.invoke(null);
119                    } 
120                    catch (Exception e) {}    
121                }
122            }
123            try {
124                return variableUtil.get(pc,init(),propertyName,defaultValue);  
125            } catch (PageException e1) {
126                return defaultValue;
127            }         
128        }
129    
130            /**
131             *
132             * @see railo.runtime.type.Objects#get(railo.runtime.PageContext, railo.runtime.type.Collection.Key, java.lang.Object)
133             */
134            public Object get(PageContext pc, Collection.Key key, Object defaultValue) {
135                    return get(pc, key.getString(), defaultValue);
136            }
137    
138            /**
139             * @see railo.runtime.type.Objects#set(railo.runtime.PageContext, java.lang.String, java.lang.Object)
140             */
141            public Object set(PageContext pc, String propertyName, Object value) throws PageException  {
142                    if(isInit) {
143                        return variableUtil.set(pc,object,propertyName,value);
144                    }
145                // Field
146                    Field[] fields=Reflector.getFieldsIgnoreCase(clazz,propertyName,null);
147                    if(!ArrayUtil.isEmpty(fields) && Modifier.isStatic(fields[0].getModifiers())) {
148                            try {
149                    fields[0].set(null,value);
150                    return value;
151                } catch (Exception e) {
152                    Caster.toPageException(e);
153                }
154                    }
155            // Getter
156            MethodInstance mi = Reflector.getSetterEL(clazz,propertyName,value);
157            if(mi!=null) {
158                if(Modifier.isStatic(mi.getMethod().getModifiers())) {
159                    try {
160                        return mi.invoke(null);
161                    } 
162                    catch (IllegalAccessException e) {
163                        throw Caster.toPageException(e);
164                    } 
165                    catch (InvocationTargetException e) {
166                        throw Caster.toPageException(e.getTargetException());
167                    }    
168                }
169            }
170            
171    
172                return variableUtil.set(pc,init(),propertyName,value);
173            }
174    
175            /**
176             *
177             * @see railo.runtime.type.Objects#set(railo.runtime.PageContext, railo.runtime.type.Collection.Key, java.lang.Object)
178             */
179            public Object set(PageContext pc, Collection.Key propertyName, Object value) throws PageException {
180                    return set(pc, propertyName.toString(), value);
181            }
182    
183        /**
184         * @see railo.runtime.type.Objects#setEL(railo.runtime.PageContext, java.lang.String, java.lang.Object)
185         */
186        public Object setEL(PageContext pc, String propertyName, Object value) {
187                    if(isInit) {
188                        return variableUtil.setEL(pc,object,propertyName,value);
189                    }
190                // Field
191                    Field[] fields=Reflector.getFieldsIgnoreCase(clazz,propertyName,null);
192                    if(!ArrayUtil.isEmpty(fields) && Modifier.isStatic(fields[0].getModifiers())) {
193                            try {
194                    fields[0].set(null,value);
195                } catch (Exception e) {}
196                            return value;
197                    }
198            // Getter
199            MethodInstance mi = Reflector.getSetterEL(clazz,propertyName,value);
200            if(mi!=null) {
201                if(Modifier.isStatic(mi.getMethod().getModifiers())) {
202                    try {
203                        return mi.invoke(null);
204                    } 
205                    catch (Exception e) {}    
206                }
207            }
208               
209            try {
210                return variableUtil.setEL(pc,init(),propertyName,value);
211            } catch (PageException e1) {
212                return value;
213            }
214        }
215    
216            /**
217             *
218             * @see railo.runtime.type.Objects#setEL(railo.runtime.PageContext, railo.runtime.type.Collection.Key, java.lang.Object)
219             */
220            public Object setEL(PageContext pc, Collection.Key propertyName, Object value) {
221                    return setEL(pc, propertyName.toString(), value);
222            }
223    
224            /**
225             * @see railo.runtime.type.Objects#call(railo.runtime.PageContext, java.lang.String, java.lang.Object[])
226             */
227            public Object call(PageContext pc, String methodName, Object[] arguments) throws PageException {
228            if(arguments==null)arguments=new Object[0];
229            
230            // init
231            if(methodName.equalsIgnoreCase("init")) {
232                return init(arguments);
233            }
234            else if(isInit) {
235                        return Reflector.callMethod(object,methodName,arguments);
236                    }
237            
238            
239                try {
240                        // get method
241                        MethodInstance mi = Reflector.getMethodInstance(clazz,methodName,arguments);
242                            // call static method if exist
243                        if(Modifier.isStatic(mi.getMethod().getModifiers())) {
244                                    return mi.invoke(null);
245                            }
246                        
247                        if(arguments.length==0 && methodName.equalsIgnoreCase("getClass")){
248                            return clazz;
249                        }
250                        
251                        // invoke constructor and call instance method
252                            return mi.invoke(init());
253                    }
254                    catch(InvocationTargetException e) {
255                            Throwable target = e.getTargetException();
256                            if(target instanceof PageException) throw (PageException)target;
257                            throw Caster.toPageException(e.getTargetException());
258                    }
259                    catch(Exception e) {
260                            throw Caster.toPageException(e);
261                    }
262            }
263    
264            /**
265             *
266             * @see railo.runtime.type.Objects#call(railo.runtime.PageContext, railo.runtime.type.Collection.Key, java.lang.Object[])
267             */
268            public Object call(PageContext pc, Collection.Key methodName, Object[] arguments) throws PageException {
269                    return call(pc, methodName.getString(), arguments);
270            }
271    
272        /**
273         * @see railo.runtime.type.Objects#callWithNamedValues(railo.runtime.PageContext, java.lang.String, railo.runtime.type.Struct)
274         */
275        public Object callWithNamedValues(PageContext pc, String methodName, Struct args) throws PageException {
276            Collection.Key[] keys = args.keys();
277            Object[] values=new Object[keys.length];
278            for(int i=0;i<keys.length;i++) {
279                values[i]=args.get(keys[i],null);
280            }   
281            return call(pc,methodName,values);
282        }
283    
284            public Object callWithNamedValues(PageContext pc, Collection.Key methodName, Struct args) throws PageException {
285                    return callWithNamedValues(pc, methodName.getString(), args);
286            }
287    
288            /**
289             * initialize method (default no object)
290             * @return initialize object
291             * @throws PageException
292             */
293            private Object init() throws PageException {
294                    return init(new Object[0]);
295            }
296            
297            private Object init(Object defaultValue) {
298                    return init(new Object[0],defaultValue);
299            }
300            
301            /**
302             * initialize method
303             * @param arguments
304             * @return Initalised Object
305             * @throws PageException
306             */
307            private Object init(Object[] arguments) throws PageException {
308                    object=Reflector.callConstructor(clazz,arguments);
309                    isInit=true;
310                    return object;
311            }
312            private Object init(Object[] arguments, Object defaultValue) {
313                    object=Reflector.callConstructor(clazz,arguments,defaultValue);
314                    isInit=object!=defaultValue;
315                    return object;
316            }
317    
318    
319            /**
320             * @see ObjectWrap#getEmbededObject()
321             */
322            public Object getEmbededObject() throws PageException {
323                    if(object==null)init();
324                    return object;
325            }
326    
327            /**
328             * @see railo.runtime.dump.Dumpable#toDumpData(railo.runtime.PageContext, int)
329             */
330            public DumpData toDumpData(PageContext pageContext, int maxlevel, DumpProperties props) {
331                    try {
332                            return DumpUtil.toDumpData(getEmbededObject(), pageContext,maxlevel,props);
333                    } catch (PageException e) {
334                            return DumpUtil.toDumpData(clazz, pageContext,maxlevel,props);
335                    }
336            }
337            
338            /**
339             * @return the containing Class
340             */
341            public Class getClazz() {return clazz;}
342    
343        /**
344         * @see railo.runtime.type.Objects#isInitalized()
345         */
346        public boolean isInitalized() {
347            return isInit;
348        }
349    
350        /**
351         * @see railo.runtime.op.Castable#castToString()
352         */
353        public String castToString() throws PageException {
354            return Caster.toString(getEmbededObject());
355        }
356        
357    
358    
359        /**
360         * @see railo.runtime.op.Castable#castToString(java.lang.String)
361         */
362        public String castToString(String defaultValue) {
363            try {
364                            return Caster.toString(getEmbededObject(),defaultValue);
365                    } catch (PageException e) {
366                            return defaultValue;
367                    }
368        }
369        
370    
371        /**
372         * @see railo.runtime.op.Castable#castToBooleanValue()
373         */
374        public boolean castToBooleanValue() throws PageException {
375            return Caster.toBooleanValue(getEmbededObject());
376        }
377        
378        /**
379         * @see railo.runtime.op.Castable#castToBoolean(java.lang.Boolean)
380         */
381        public Boolean castToBoolean(Boolean defaultValue) {
382            try {
383                            return Caster.toBoolean(getEmbededObject(),defaultValue);
384                    } catch (PageException e) {
385                            return defaultValue;
386                    }
387        }
388    
389        /**
390         * @see railo.runtime.op.Castable#castToDoubleValue()
391         */
392        public double castToDoubleValue() throws PageException {
393            return Caster.toDoubleValue(getEmbededObject());
394        }
395        
396        /**
397         * @see railo.runtime.op.Castable#castToDoubleValue(double)
398         */
399        public double castToDoubleValue(double defaultValue) {
400            try {
401                            return Caster.toDoubleValue(getEmbededObject(),defaultValue);
402                    } catch (PageException e) {
403                            return defaultValue;
404                    }
405        }
406    
407        /**
408         * @see railo.runtime.op.Castable#castToDateTime()
409         */
410        public DateTime castToDateTime() throws PageException {
411            return Caster.toDatetime(getEmbededObject(),null);
412        }
413        
414        /**
415         * @see railo.runtime.op.Castable#castToDateTime(railo.runtime.type.dt.DateTime)
416         */
417        public DateTime castToDateTime(DateTime defaultValue) {
418            try {
419                            return DateCaster.toDateAdvanced(getEmbededObject(),true,null,defaultValue);
420                    } catch (PageException e) {
421                            return defaultValue;
422                    }
423        }
424    
425        /**
426         * @see railo.runtime.type.ObjectWrap#getEmbededObject(Object)
427         */
428        public Object getEmbededObject(Object def) {
429            if(object==null)init(def);
430                    return object;
431        }
432    
433            /**
434             * @return the object
435             */
436            public Object getObject() {
437                    return object;
438            }
439    
440            /**
441             * @see railo.runtime.op.Castable#compare(boolean)
442             */
443            public int compareTo(boolean b) throws PageException {
444                    return Operator.compare(castToBooleanValue(), b);
445            }
446    
447            /**
448             * @see railo.runtime.op.Castable#compareTo(railo.runtime.type.dt.DateTime)
449             */
450            public int compareTo(DateTime dt) throws PageException {
451                    return Operator.compare((Date)castToDateTime(), (Date)dt);
452            }
453    
454            /**
455             * @see railo.runtime.op.Castable#compareTo(double)
456             */
457            public int compareTo(double d) throws PageException {
458                    return Operator.compare(castToDoubleValue(), d);
459            }
460    
461            /**
462             * @see railo.runtime.op.Castable#compareTo(java.lang.String)
463             */
464            public int compareTo(String str) throws PageException {
465                    return Operator.compare(castToString(), str);
466            }
467    
468    }