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.runtime.op;
020
021import java.awt.image.BufferedImage;
022import java.io.ByteArrayInputStream;
023import java.io.ByteArrayOutputStream;
024import java.io.File;
025import java.io.FileInputStream;
026import java.io.IOException;
027import java.io.InputStream;
028import java.io.OutputStream;
029import java.io.Reader;
030import java.io.Serializable;
031import java.io.UnsupportedEncodingException;
032import java.lang.reflect.InvocationTargetException;
033import java.math.BigDecimal;
034import java.math.BigInteger;
035import java.net.MalformedURLException;
036import java.nio.charset.Charset;
037import java.sql.Blob;
038import java.sql.Clob;
039import java.sql.ResultSet;
040import java.sql.SQLException;
041import java.text.DecimalFormat;
042import java.util.ArrayList;
043import java.util.Calendar;
044import java.util.Date;
045import java.util.Enumeration;
046import java.util.Hashtable;
047import java.util.Iterator;
048import java.util.List;
049import java.util.Locale;
050import java.util.Map;
051import java.util.Map.Entry;
052import java.util.Set;
053import java.util.TimeZone;
054import java.util.Vector;
055import java.util.concurrent.ExecutionException;
056
057import lucee.commons.date.DateTimeUtil;
058import lucee.commons.date.JREDateTimeUtil;
059import lucee.commons.date.TimeZoneUtil;
060import lucee.commons.digest.Base64Encoder;
061import lucee.commons.io.FileUtil;
062import lucee.commons.io.IOUtil;
063import lucee.commons.io.SystemUtil;
064import lucee.commons.io.res.Resource;
065import lucee.commons.io.res.util.ResourceUtil;
066import lucee.commons.lang.CFTypes;
067import lucee.commons.lang.ClassException;
068import lucee.commons.lang.ClassUtil;
069import lucee.commons.lang.ExceptionUtil;
070import lucee.commons.lang.StringUtil;
071import lucee.commons.net.HTTPUtil;
072import lucee.runtime.Component;
073import lucee.runtime.PageContext;
074import lucee.runtime.PageContextImpl;
075import lucee.runtime.coder.Base64Coder;
076import lucee.runtime.coder.CoderException;
077import lucee.runtime.config.Config;
078import lucee.runtime.converter.ConverterException;
079import lucee.runtime.converter.ScriptConverter;
080import lucee.runtime.engine.ThreadLocalPageContext;
081import lucee.runtime.exp.ApplicationException;
082import lucee.runtime.exp.CasterException;
083import lucee.runtime.exp.ExpressionException;
084import lucee.runtime.exp.NativeException;
085import lucee.runtime.exp.PageException;
086import lucee.runtime.exp.PageExceptionBox;
087import lucee.runtime.ext.function.Function;
088import lucee.runtime.functions.file.FileStreamWrapper;
089import lucee.runtime.i18n.LocaleFactory;
090import lucee.runtime.img.Image;
091import lucee.runtime.interpreter.VariableInterpreter;
092import lucee.runtime.java.JavaObject;
093import lucee.runtime.net.rpc.AxisCaster;
094import lucee.runtime.net.rpc.Pojo;
095import lucee.runtime.op.date.DateCaster;
096import lucee.runtime.op.validators.ValidateCreditCard;
097import lucee.runtime.reflection.Reflector;
098import lucee.runtime.text.xml.XMLCaster;
099import lucee.runtime.text.xml.XMLUtil;
100import lucee.runtime.text.xml.struct.XMLMultiElementArray;
101import lucee.runtime.text.xml.struct.XMLMultiElementStruct;
102import lucee.runtime.text.xml.struct.XMLStruct;
103import lucee.runtime.type.Array;
104import lucee.runtime.type.ArrayImpl;
105import lucee.runtime.type.Collection;
106import lucee.runtime.type.Collection.Key;
107import lucee.runtime.type.CollectionStruct;
108import lucee.runtime.type.FunctionValue;
109import lucee.runtime.type.FunctionValueImpl;
110import lucee.runtime.type.Iteratorable;
111import lucee.runtime.type.KeyImpl;
112import lucee.runtime.type.ObjectWrap;
113import lucee.runtime.type.Objects;
114import lucee.runtime.type.Query;
115import lucee.runtime.type.QueryColumn;
116import lucee.runtime.type.QueryImpl;
117import lucee.runtime.type.Struct;
118import lucee.runtime.type.StructImpl;
119import lucee.runtime.type.UDF;
120import lucee.runtime.type.dt.DateTime;
121import lucee.runtime.type.dt.DateTimeImpl;
122import lucee.runtime.type.dt.TimeSpan;
123import lucee.runtime.type.dt.TimeSpanImpl;
124import lucee.runtime.type.scope.ObjectStruct;
125import lucee.runtime.type.util.ArrayUtil;
126import lucee.runtime.type.util.ComponentUtil;
127import lucee.runtime.type.wrap.ArrayAsList;
128import lucee.runtime.type.wrap.ListAsArray;
129import lucee.runtime.type.wrap.MapAsStruct;
130import lucee.runtime.util.ArrayIterator;
131import lucee.runtime.util.IteratorWrapper;
132
133import org.w3c.dom.Node;
134import org.w3c.dom.NodeList;
135
136
137
138
139/**
140 * This class can cast object of one type to a other by CFML rules
141 */
142public final class Caster { 
143    private Caster(){
144    }
145    //static Map calendarsMap=new ReferenceMap(ReferenceMap.SOFT,ReferenceMap.SOFT);
146    
147    private static final int NUMBERS_MIN=0;
148    private static final int NUMBERS_MAX=999;
149    private static final String[] NUMBERS = {
150            "0","1","2","3","4","5","6","7","8","9",
151            "10","11","12","13","14","15","16","17","18","19",
152            "20","21","22","23","24","25","26","27","28","29",
153            "30","31","32","33","34","35","36","37","38","39",
154            "40","41","42","43","44","45","46","47","48","49",
155            "50","51","52","53","54","55","56","57","58","59",
156            "60","61","62","63","64","65","66","67","68","69",
157            "70","71","72","73","74","75","76","77","78","79",
158            "80","81","82","83","84","85","86","87","88","89",
159            "90","91","92","93","94","95","96","97","98","99",
160            "100","101","102","103","104","105","106","107","108","109",
161            "110","111","112","113","114","115","116","117","118","119",
162            "120","121","122","123","124","125","126","127","128","129",
163            "130","131","132","133","134","135","136","137","138","139",
164            "140","141","142","143","144","145","146","147","148","149",
165            "150","151","152","153","154","155","156","157","158","159",
166            "160","161","162","163","164","165","166","167","168","169",
167            "170","171","172","173","174","175","176","177","178","179",
168            "180","181","182","183","184","185","186","187","188","189",
169            "190","191","192","193","194","195","196","197","198","199",
170            "200","201","202","203","204","205","206","207","208","209",
171            "210","211","212","213","214","215","216","217","218","219",
172            "220","221","222","223","224","225","226","227","228","229",
173            "230","231","232","233","234","235","236","237","238","239",
174            "240","241","242","243","244","245","246","247","248","249",
175            "250","251","252","253","254","255","256","257","258","259",
176            "260","261","262","263","264","265","266","267","268","269",
177            "270","271","272","273","274","275","276","277","278","279",
178            "280","281","282","283","284","285","286","287","288","289",
179            "290","291","292","293","294","295","296","297","298","299",
180            "300","301","302","303","304","305","306","307","308","309",
181            "310","311","312","313","314","315","316","317","318","319",
182            "320","321","322","323","324","325","326","327","328","329",
183            "330","331","332","333","334","335","336","337","338","339",
184            "340","341","342","343","344","345","346","347","348","349",
185            "350","351","352","353","354","355","356","357","358","359",
186            "360","361","362","363","364","365","366","367","368","369",
187            "370","371","372","373","374","375","376","377","378","379",
188            "380","381","382","383","384","385","386","387","388","389",
189            "390","391","392","393","394","395","396","397","398","399",
190            "400","401","402","403","404","405","406","407","408","409",
191            "410","411","412","413","414","415","416","417","418","419",
192            "420","421","422","423","424","425","426","427","428","429",
193            "430","431","432","433","434","435","436","437","438","439",
194            "440","441","442","443","444","445","446","447","448","449",
195            "450","451","452","453","454","455","456","457","458","459",
196            "460","461","462","463","464","465","466","467","468","469",
197            "470","471","472","473","474","475","476","477","478","479",
198            "480","481","482","483","484","485","486","487","488","489",
199            "490","491","492","493","494","495","496","497","498","499",
200            "500","501","502","503","504","505","506","507","508","509",
201            "510","511","512","513","514","515","516","517","518","519",
202            "520","521","522","523","524","525","526","527","528","529",
203            "530","531","532","533","534","535","536","537","538","539",
204            "540","541","542","543","544","545","546","547","548","549",
205            "550","551","552","553","554","555","556","557","558","559",
206            "560","561","562","563","564","565","566","567","568","569",
207            "570","571","572","573","574","575","576","577","578","579",
208            "580","581","582","583","584","585","586","587","588","589",
209            "590","591","592","593","594","595","596","597","598","599",
210            "600","601","602","603","604","605","606","607","608","609",
211            "610","611","612","613","614","615","616","617","618","619",
212            "620","621","622","623","624","625","626","627","628","629",
213            "630","631","632","633","634","635","636","637","638","639",
214            "640","641","642","643","644","645","646","647","648","649",
215            "650","651","652","653","654","655","656","657","658","659",
216            "660","661","662","663","664","665","666","667","668","669",
217            "670","671","672","673","674","675","676","677","678","679",
218            "680","681","682","683","684","685","686","687","688","689",
219            "690","691","692","693","694","695","696","697","698","699",
220            "700","701","702","703","704","705","706","707","708","709",
221            "710","711","712","713","714","715","716","717","718","719",
222            "720","721","722","723","724","725","726","727","728","729",
223            "730","731","732","733","734","735","736","737","738","739",
224            "740","741","742","743","744","745","746","747","748","749",
225            "750","751","752","753","754","755","756","757","758","759",
226            "760","761","762","763","764","765","766","767","768","769",
227            "770","771","772","773","774","775","776","777","778","779",
228            "780","781","782","783","784","785","786","787","788","789",
229            "790","791","792","793","794","795","796","797","798","799",
230            "800","801","802","803","804","805","806","807","808","809",
231            "810","811","812","813","814","815","816","817","818","819",
232            "820","821","822","823","824","825","826","827","828","829",
233            "830","831","832","833","834","835","836","837","838","839",
234            "840","841","842","843","844","845","846","847","848","849",
235            "850","851","852","853","854","855","856","857","858","859",
236            "860","861","862","863","864","865","866","867","868","869",
237            "870","871","872","873","874","875","876","877","878","879",
238            "880","881","882","883","884","885","886","887","888","889",
239            "890","891","892","893","894","895","896","897","898","899",
240            "900","901","902","903","904","905","906","907","908","909",
241            "910","911","912","913","914","915","916","917","918","919",
242            "920","921","922","923","924","925","926","927","928","929",
243            "930","931","932","933","934","935","936","937","938","939",
244            "940","941","942","943","944","945","946","947","948","949",
245            "950","951","952","953","954","955","956","957","958","959",
246            "960","961","962","963","964","965","966","967","968","969",
247            "970","971","972","973","974","975","976","977","978","979",
248            "980","981","982","983","984","985","986","987","988","989",
249            "990","991","992","993","994","995","996","997","998","999"
250           };
251    
252    /**
253     * cast a boolean value to a boolean value (do nothing)
254     * @param b boolean value to cast
255     * @return casted boolean value
256     */
257    public static boolean toBooleanValue(boolean b) {
258        return b;
259    }
260    
261    /**
262     * cast a int value to a boolean value (primitive value type)
263     * @param i int value to cast
264     * @return casted boolean value
265     */
266    public static boolean toBooleanValue(int i) {
267        return i!=0;
268    }   
269    
270    /**
271     * cast a long value to a boolean value (primitive value type)
272     * @param l long value to cast
273     * @return casted boolean value
274     */
275    public static boolean toBooleanValue(long l) {
276        return l!=0;
277    }
278    
279    /**
280     * cast a double value to a boolean value (primitive value type)
281     * @param d double value to cast
282     * @return casted boolean value
283     */
284    public static boolean toBooleanValue(double d) {
285        return d!=0;
286    }
287    
288    /**
289     * cast a double value to a boolean value (primitive value type)
290     * @param c char value to cast
291     * @return casted boolean value
292     */
293    public static boolean toBooleanValue(char c) {
294        return c!=0;
295    }
296    
297    /**
298     * cast a Object to a boolean value (primitive value type)
299     * @param o Object to cast
300     * @return casted boolean value
301     * @throws PageException 
302     */
303    public static boolean toBooleanValue(Object o) throws PageException {
304        if(o instanceof Boolean) return ((Boolean)o).booleanValue();
305        else if(o instanceof Double) return toBooleanValue(((Double)o).doubleValue());
306        else if(o instanceof Number) return toBooleanValue(((Number)o).doubleValue());
307        else if(o instanceof String) return toBooleanValue((String)o);
308        else if(o instanceof Castable) return ((Castable)o).castToBooleanValue();
309        else if(o == null) return toBooleanValue("");
310        else if(o instanceof ObjectWrap) return toBooleanValue(((ObjectWrap)o).getEmbededObject());
311        throw new CasterException(o,"boolean");
312    }
313    
314    /**
315     * tranlate a Boolean object to a boolean value
316     * @param b
317     * @return
318     */
319    public static boolean toBooleanValue(Boolean b) {
320        return b.booleanValue();
321    }
322    
323    /**
324     * cast a Object to a boolean value (primitive value type)
325     * @param str String to cast
326     * @return casted boolean value
327     * @throws PageException 
328     */
329    public static boolean toBooleanValue(String str) throws PageException {
330        Boolean b = toBoolean(str,null);
331        if(b!=null) return b.booleanValue();
332        throw new CasterException("Can't cast String ["+str+"] to a boolean");
333    }
334    
335    public static Boolean toBoolean(String str, Boolean defaultValue) {
336        if(str==null) return defaultValue;
337        int i=stringToBooleanValueEL(str);
338        if(i!=-1) return (i==1)?Boolean.TRUE:Boolean.FALSE;
339        
340        double d=toDoubleValue(str,Double.NaN);
341        if(!Double.isNaN(d)) return toBoolean(d);
342        
343        return defaultValue;
344    }
345    
346
347    /**
348     * cast a Object to a Double Object (reference Type)
349     * @param f Object to cast
350     * @return casted Double Object
351     * @throws PageException
352     */
353    public static Double toDouble(float f) {
354        return new Double(f);
355        
356    }
357    public static Double toDouble(Float f) {
358        return new Double(f.doubleValue());
359    }
360
361    /**
362     * cast a Object to a Double Object (reference Type)
363     * @param o Object to cast
364     * @return casted Double Object
365     * @throws PageException
366     */
367    public static Double toDouble(Object o) throws PageException {
368        if(o instanceof Double) return (Double)o;
369        return new Double(toDoubleValue(o));
370        
371    }
372
373    /**
374     * cast a Object to a Double Object (reference Type)
375     * @param str string to cast
376     * @return casted Double Object
377     * @throws PageException
378     */
379    public static Double toDouble(String str) throws PageException {
380        return new Double(toDoubleValue(str));
381        
382    }
383
384    /**
385     * cast a Object to a Double Object (reference Type)
386     * @param o Object to cast
387     * @param defaultValue 
388     * @return casted Double Object
389     */
390    public static Double toDouble(Object o, Double defaultValue) {
391        if(o instanceof Double) return (Double)o;
392        double dbl = toDoubleValue(o,true,Double.NaN);
393        if(Double.isNaN(dbl)) return defaultValue;
394        return new Double(dbl);
395        
396    }
397    
398    /**
399     * cast a double value to a Double Object (reference Type)
400     * @param d double value to cast
401     * @return casted Double Object
402     */
403    private static final int MAX_SMALL_DOUBLE=10000;
404        private static final Double[] smallDoubles=new Double[MAX_SMALL_DOUBLE];
405        static {
406                for(int i=0;i<MAX_SMALL_DOUBLE;i++) smallDoubles[i]=new Double(i);
407        }
408        
409        public static Double toDouble(double d) {
410                if(d<MAX_SMALL_DOUBLE && d>=0) {
411                        int i;
412                        if((i=((int)d))==d) return smallDoubles[i];
413                }
414                return new Double(d);
415        }
416    
417    
418    /**
419     * cast a boolean value to a Double Object (reference Type)
420     * @param b boolean value to cast
421     * @return casted Double Object
422     */
423    public static Double toDouble(boolean b) {
424        return new Double(b?1:0);
425    }
426    
427
428    /**
429     * cast a Object to a double value (primitive value Type)
430     * @param o Object to cast
431     * @return casted double value
432     * @throws PageException
433     */
434    public static double toDoubleValue(Object o) throws PageException {
435        if(o instanceof Number) {
436                return ((Number)o).doubleValue();
437        }
438        else if(o instanceof Boolean) return ((Boolean)o).booleanValue()?1:0;
439        else if(o instanceof String) return toDoubleValue(o.toString(),true);
440        //else if(o instanceof Clob) return toDoubleValue(toString(o));
441        else if(o instanceof Castable) return ((Castable)o).castToDoubleValue();
442        else if(o == null) return 0;//toDoubleValue("");
443        else if(o instanceof ObjectWrap) return toDoubleValue(((ObjectWrap)o).getEmbededObject());
444        else if(o instanceof Date) return DateTimeUtil.getInstance().toDoubleValue(((Date)o).getTime());
445        else if(o instanceof Calendar) return DateTimeUtil.getInstance().toDoubleValue(((Calendar)o).getTimeInMillis());
446        throw new CasterException(o,"number");
447    }
448
449    public static double toDoubleValue(Double d) {
450        if(d == null) return 0;
451        return d.doubleValue();
452    }
453    
454    /**
455     * cast a Object to a double value (primitive value Type)
456     * @param str String to cast
457     * @return casted double value
458     * @throws CasterException 
459     */
460    public static double toDoubleValue(String str) throws CasterException { 
461        return toDoubleValue(str,true);
462    }
463    
464    public static double toDoubleValue(String str, boolean alsoFromDate) throws CasterException { 
465        if(str==null) return 0;//throw new CasterException("can't cast empty string to a number value");
466        str=str.trim();
467        double rtn_=0;
468        double _rtn=0;
469        int eCount=0;
470        double deep=1;
471        int pos=0; 
472        int len=str.length(); 
473        
474        
475        if(len==0) throw new CasterException("can't cast empty string to a number value"); 
476        char curr=str.charAt(pos); 
477        boolean isMinus=false;
478        
479        if(curr=='+') { 
480            if(len==++pos) throw new CasterException("can't cast [+] string to a number value");          
481        }
482        if(curr=='-') { 
483            if(len==++pos) throw new CasterException("can't cast [-] string to a number value");  
484            isMinus=true;
485        }
486        boolean hasDot=false; 
487        //boolean hasExp=false; 
488        do { 
489            curr=str.charAt(pos); 
490            if(curr<'0') {
491                if(curr=='.') { 
492                    if(hasDot) {
493                        if(!alsoFromDate) throw new CasterException("cannot cast ["+str+"] string to a number value");  
494                        return toDoubleValueViaDate(str);
495                    }
496                    hasDot=true; 
497                } 
498                else {
499                    if(pos==0 && Decision.isBoolean(str)) return toBooleanValue(str,false)?1.0D:0.0D;
500                    if(!alsoFromDate) throw new CasterException("cannot cast ["+str+"] string to a number value");  
501                        return toDoubleValueViaDate(str);
502                    //throw new CasterException("can't cast ["+str+"] string to a number value"); 
503                }
504            }
505            else if(curr>'9') {
506                if(curr == 'e' || curr == 'E') { 
507                        try{
508                                return Double.parseDouble(str);
509                        }
510                        catch( NumberFormatException e){
511                                if(!alsoFromDate) throw new CasterException("cannot cast ["+str+"] string to a number value");  
512                        return toDoubleValueViaDate(str);
513                                //throw new CasterException("can't cast ["+str+"] string to a number value"); 
514                        } 
515                }
516                //else {
517                    if(pos==0 && Decision.isBoolean(str)) return toBooleanValue(str,false)?1.0D:0.0D;
518                    if(!alsoFromDate) throw new CasterException("cannot cast ["+str+"] string to a number value");  
519                        return toDoubleValueViaDate(str);
520                    //throw new CasterException("can't cast ["+str+"] string to a number value"); 
521                //}
522            }
523            else if(!hasDot) {
524                rtn_*=10;
525                rtn_+=toDigit(curr);
526                
527            }
528            /*else if(hasExp) {
529                eCount*=10;
530                eCount+=toDigit(curr);
531            }*/
532            else  {               
533                deep*=10;
534                _rtn*=10;
535                _rtn+=toDigit(curr);
536                
537                //rtn_+=(toDigit(curr)/deep);
538                //deep*=10;
539            }
540        } 
541        while(++pos<len);
542        
543
544        if(deep>1) {
545            rtn_+=(_rtn/=deep);
546        }
547        if(isMinus)rtn_= -rtn_;
548        if(eCount>0)for(int i=0;i<eCount;i++)rtn_*=10;
549        return rtn_;
550    }
551    
552    private static double toDoubleValueViaDate(String str) throws CasterException {
553                DateTime date = DateCaster.toDateSimple(str, DateCaster.CONVERTING_TYPE_NONE,false, null, null);// not advanced here, neo also only support simple
554                if(date==null)throw new CasterException("can't cast ["+str+"] string to a number value");
555        return date.castToDoubleValue(0);
556        }
557    
558    private static double toDoubleValueViaDate(String str,double defaultValue) {
559        DateTime date = DateCaster.toDateSimple(str, DateCaster.CONVERTING_TYPE_NONE,false, null, null);// not advanced here, neo also only support simple
560                if(date==null)return defaultValue;
561        return date.castToDoubleValue(0);
562        }
563    
564    /**
565     * cast a Object to a double value (primitive value Type)
566     * @param o Object to cast
567     * @param defaultValue if can't cast return this value
568     * @return casted double value
569     * /
570    public static double toDoubleValue(Object o,double defaultValue) {
571        return toDoubleValue(o, true, defaultValue);
572    }*/
573
574        /**
575     * cast a Object to a double value (primitive value Type)
576     * @param o Object to cast
577     * @param defaultValue if can't cast return this value
578     * @return casted double value
579     */
580    public static double toDoubleValue(Object o,boolean alsoFromDate,double defaultValue) {
581        if(o instanceof Number) return ((Number)o).doubleValue();
582        else if(o instanceof Boolean) return ((Boolean)o).booleanValue()?1:0;
583        else if(o instanceof String) return toDoubleValue(o.toString(),alsoFromDate,defaultValue);
584        else if(o instanceof Castable) {
585            return ((Castable)o).castToDoubleValue(defaultValue);
586            
587        }
588        //else if(o == null) return defaultValue;
589        else if(o instanceof ObjectWrap) return toDoubleValue(((ObjectWrap)o).getEmbededObject(new Double(defaultValue)),true,defaultValue);
590        else if(o instanceof Date) return DateTimeUtil.getInstance().toDoubleValue(((Date)o).getTime());
591        else if(o instanceof Calendar) return DateTimeUtil.getInstance().toDoubleValue(((Calendar)o).getTimeInMillis());
592        return defaultValue;
593    }
594    
595    /**
596     * cast a Object to a double value (primitive value Type), if can't return Double.NaN
597     * @param str String to cast
598     * @param defaultValue if can't cast return this value
599     * @return casted double value
600     */ 
601    public static double toDoubleValue(String str,double defaultValue) { 
602        return toDoubleValue(str, true,defaultValue);
603    }
604    public static double toDoubleValue(String str,boolean alsoFromDate,double defaultValue) { 
605        if(str==null) return defaultValue; 
606        str=str.trim();
607
608        int len=str.length(); 
609        if(len==0) return defaultValue; 
610
611        double rtn_=0;
612        double _rtn=0;
613        int eCount=0;
614//      double deep=10;
615        double deep=1;
616        int pos=0; 
617        
618        char curr=str.charAt(pos); 
619        boolean isMinus=false;
620        
621        if(curr=='+') { 
622            if(len==++pos) return defaultValue; 
623        }
624        else if(curr=='-') { 
625            if(len==++pos) return defaultValue; 
626            isMinus=true;
627        }
628        
629        boolean hasDot=false; 
630        //boolean hasExp=false; 
631        do { 
632            curr=str.charAt(pos); 
633            
634            
635            if(curr<'0') {
636                if(curr=='.') { 
637                        if(hasDot) {
638                                if(!alsoFromDate) return defaultValue;  
639                        return toDoubleValueViaDate(str,defaultValue);
640                        }
641                    hasDot=true; 
642                } 
643                else {
644                    if(pos==0 && Decision.isBoolean(str)) return toBooleanValue(str,false)?1.0D:0.0D;
645                    if(!alsoFromDate) return defaultValue;  
646                        return toDoubleValueViaDate(str,defaultValue);
647                }
648            }
649            else if(curr>'9') {
650                if(curr=='e' || curr=='E') { 
651                        try{
652                                return Double.parseDouble(str);
653                        }
654                        catch( NumberFormatException e){
655                                if(!alsoFromDate) return defaultValue;  
656                        return toDoubleValueViaDate(str,defaultValue);
657                        } 
658                }
659                //else {
660                    if(pos==0 && Decision.isBoolean(str)) return toBooleanValue(str,false)?1.0D:0.0D;
661                    if(!alsoFromDate) return defaultValue;  
662                        return toDoubleValueViaDate(str,defaultValue);
663                //}
664            }
665            else if(!hasDot) {
666                rtn_*=10;
667                rtn_+=toDigit(curr);
668            }
669            /*else if(hasExp) {
670                eCount*=10;
671                eCount+=toDigit(curr);
672            }*/
673            else  {                
674                deep*=10;
675                _rtn*=10;
676                _rtn+=toDigit(curr);
677            }
678           
679        } 
680        while(++pos<len);
681        
682        
683        if(deep>1) {
684            rtn_+=(_rtn/=deep);
685        }
686        if(isMinus)rtn_= -rtn_;
687        if(eCount>0)for(int i=0;i<eCount;i++)rtn_*=10;
688        return rtn_;
689        
690        
691    }
692    
693    private static int toDigit(char c) {
694        return c-48;
695    } 
696
697    /**
698     * cast a double value to a double value (do nothing)
699     * @param d double value to cast
700     * @return casted double value
701     */
702    public static double toDoubleValue(double d) {
703        return d;
704    }
705
706    public static double toDoubleValue(float f) {
707        return f;
708    }
709
710    public static double toDoubleValue(Float f) {
711        return f.doubleValue();
712    }
713    
714    /**
715     * cast a boolean value to a double value (primitive value type)
716     * @param b boolean value to cast
717     * @return casted double value
718     */
719    public static double toDoubleValue(boolean b) {
720        return b?1:0;
721    }
722    
723    /**
724     * cast a char value to a double value (primitive value type)
725     * @param c char value to cast
726     * @return casted double value
727     */
728    public static double toDoubleValue(char c) {
729        return c;
730    }
731    
732    /**
733     * cast a Object to a int value (primitive value type)
734     * @param o Object to cast
735     * @return casted int value
736     * @throws PageException
737     */
738    public static int toIntValue(Object o) throws PageException {
739        
740        if(o instanceof Number) return ((Number)o).intValue();
741        else if(o instanceof Boolean) return ((Boolean)o).booleanValue()?1:0;
742        else if(o instanceof String) return toIntValue(o.toString().trim());
743        //else if(o instanceof Clob) return toIntValue(toString(o));
744        else if(o instanceof Castable) return (int)((Castable)o).castToDoubleValue();
745        else if(o instanceof Date) return (int)new DateTimeImpl((Date)o).castToDoubleValue();
746        
747        if(o instanceof String)
748            throw new ExpressionException("Can't cast String ["+o.toString()+"] to a number");
749        else if(o instanceof ObjectWrap) return toIntValue(((ObjectWrap)o).getEmbededObject());
750                
751        
752        throw new CasterException(o,"number");
753    }
754    
755    /**
756     * cast a Object to a int value (primitive value type)
757     * @param o Object to cast
758     * @param defaultValue 
759     * @return casted int value
760     */
761    public static int toIntValue(Object o, int defaultValue) {
762        
763        if(o instanceof Number) return ((Number)o).intValue();
764        else if(o instanceof Boolean) return ((Boolean)o).booleanValue()?1:0;
765        else if(o instanceof String) return toIntValue(o.toString().trim(),defaultValue);
766        //else if(o instanceof Clob) return toIntValue(toString(o));
767        else if(o instanceof Castable) {
768            return (int)((Castable)o).castToDoubleValue(defaultValue);
769            
770        }
771        else if(o instanceof Date) return (int)new DateTimeImpl((Date)o).castToDoubleValue();
772        else if(o instanceof ObjectWrap) return toIntValue(((ObjectWrap)o).getEmbededObject(Integer.valueOf(defaultValue)),defaultValue);
773                
774        return defaultValue;
775    }
776    
777
778    /**
779     * cast a String to a int value (primitive value type)
780     * @param str String to cast
781     * @return casted int value
782     * @throws ExpressionException
783     */
784    public static int toIntValue(String str) throws ExpressionException {
785        return (int)toDoubleValue(str,false);
786    }
787
788    /**
789     * cast a Object to a double value (primitive value Type), if can't return Integer.MIN_VALUE
790     * @param str String to cast
791     * @param defaultValue 
792     * @return casted double value
793     */
794    public static int toIntValue(String str, int defaultValue) { 
795        return (int)toDoubleValue(str,false,defaultValue);
796    }
797    
798    /**
799     * cast a double value to a int value (primitive value type)
800     * @param d double value to cast
801     * @return casted int value
802     */
803    public static int toIntValue(double d) {
804        return (int)d;
805    }
806    
807    /**
808     * cast a int value to a int value (do nothing)
809     * @param i int value to cast
810     * @return casted int value
811     */
812    public static int toIntValue(int i) {
813        return i;
814    }
815    
816    /**
817     * cast a boolean value to a int value (primitive value type)
818     * @param b boolean value to cast
819     * @return casted int value
820     */
821    public static int toIntValue(boolean b) {
822        return b?1:0;
823    }
824    
825    /**
826     * cast a char value to a int value (primitive value type)
827     * @param c char value to cast
828     * @return casted int value
829     */
830    public static int toIntValue(char c) {
831        return c;
832    }
833
834    /**
835     * cast a double to a decimal value (String:xx.xx)
836     * @param value Object to cast
837     * @return casted decimal value
838     */
839    public static String toDecimal(boolean value) {
840        if(value) return "1.00";
841        return "0.00";
842    }
843
844    /**
845     * cast a double to a decimal value (String:xx.xx)
846     * @param value Object to cast
847     * @return casted decimal value
848     * @throws PageException
849     */
850    public static String toDecimal(Object value) throws PageException {
851        return toDecimal(Caster.toDoubleValue(value));
852    }
853
854    /**
855     * cast a double to a decimal value (String:xx.xx)
856     * @param value Object to cast
857     * @return casted decimal value
858     * @throws PageException
859     */
860    public static String toDecimal(String value) throws PageException {
861        return toDecimal(Caster.toDoubleValue(value));
862    }
863
864    /**
865     * cast a double to a decimal value (String:xx.xx)
866     * @param value Object to cast
867     * @param defaultValue 
868     * @return casted decimal value
869     */
870    public static String toDecimal(Object value, String defaultValue) {
871        double res=toDoubleValue(value,true,Double.NaN);
872        if(Double.isNaN(res)) return defaultValue;
873        return toDecimal(res);
874    }
875    
876    /**
877     * cast a Oject to a decimal value (String:xx.xx)
878     * @param value Object to cast
879     * @return casted decimal value
880     */
881    public static String toDecimal(double value) {
882        return toDecimal(value,'.',',');
883    }
884    
885    
886    private static String toDecimal(double value,char decDel,char thsDel) {
887        // TODO Caster toDecimal bessere impl.
888        String str=new BigDecimal((StrictMath.round(value*100)/100D)).toString();
889        //str=toDouble(value).toString();
890        String[] arr=str.split("\\.");      
891        
892        //right value
893            String rightValue;
894            if(arr.length==1) {
895                rightValue="00";
896            }
897            else {
898                rightValue=arr[1];
899                rightValue=StrictMath.round(Caster.toDoubleValue("0."+rightValue,0)*100)+"";
900                if(rightValue.length()<2)rightValue=0+rightValue;
901            }
902            
903        // left value
904            String leftValue=arr[0];
905            int leftValueLen=leftValue.length();
906            int ends=(StringUtil.startsWith(str, '-'))?1:0;
907            if(leftValueLen>3) {
908                StringBuffer tmp=new StringBuffer();
909                int i;
910                for(i=leftValueLen-3;i>0;i-=3) {
911                        tmp.insert(0, leftValue.substring(i,i+3));
912                    if(i!=ends)tmp.insert(0,thsDel);
913                }
914                tmp.insert(0, leftValue.substring(0,i+3));
915                leftValue=tmp.toString();
916                
917            }
918        
919        return leftValue+decDel+rightValue;
920    }
921    
922    /*public static void main(String[] args) {
923        print.out(toDecimal(12));
924        print.out(toDecimal(123));
925                print.out(toDecimal(1234));
926                print.out(toDecimal(12345));
927                print.out(toDecimal(123456));
928                print.out(toDecimal(-12));
929                print.out(toDecimal(-123));
930                print.out(toDecimal(-1234));
931                print.out(toDecimal(-12345));
932                print.out(toDecimal(-123456));
933        }*/
934    
935    /**
936     * cast a boolean value to a Boolean Object(reference type)
937     * @param b boolean value to cast
938     * @return casted Boolean Object
939     */
940    public static Boolean toBoolean(boolean b) {
941        return b?Boolean.TRUE:Boolean.FALSE;
942    }
943    
944    /**
945     * cast a char value to a Boolean Object(reference type)
946     * @param c char value to cast
947     * @return casted Boolean Object
948     */
949    public static Boolean toBoolean(char c) {
950        return c!=0?Boolean.TRUE:Boolean.FALSE;
951    }
952    
953    /**
954     * cast a int value to a Boolean Object(reference type)
955     * @param i int value to cast
956     * @return casted Boolean Object
957     */
958    public static Boolean toBoolean(int i) {
959        return i!=0?Boolean.TRUE:Boolean.FALSE;
960    }
961    
962    /**
963     * cast a long value to a Boolean Object(reference type)
964     * @param l long value to cast
965     * @return casted Boolean Object
966     */
967    public static Boolean toBoolean(long l) {
968        return l!=0?Boolean.TRUE:Boolean.FALSE;
969    }
970    
971    /**
972     * cast a double value to a Boolean Object(reference type)
973     * @param d double value to cast
974     * @return casted Boolean Object
975     */
976    public static Boolean toBoolean(double d) {
977        return d!=0?Boolean.TRUE:Boolean.FALSE;
978    }
979
980    /**
981     * cast a Object to a Boolean Object(reference type)
982     * @param o Object to cast
983     * @return casted Boolean Object
984     * @throws PageException
985     */
986    public static Boolean toBoolean(Object o) throws PageException {
987        if(o instanceof Boolean) return (Boolean)o;
988        return toBooleanValue(o)?Boolean.TRUE:Boolean.FALSE;
989        
990    }
991
992    /**
993     * cast a Object to a Boolean Object(reference type)
994     * @param str String to cast
995     * @return casted Boolean Object
996     * @throws PageException
997     */
998    public static Boolean toBoolean(String str) throws PageException {
999        return toBooleanValue(str)?Boolean.TRUE:Boolean.FALSE;
1000        
1001    }
1002    
1003    /**
1004     * cast a Object to a boolean value (primitive value type), Exception Less
1005     * @param o Object to cast
1006     * @param defaultValue 
1007     * @return casted boolean value
1008     */
1009    public static boolean toBooleanValue(Object o, boolean defaultValue) {
1010        if(o instanceof Boolean) return ((Boolean)o).booleanValue();
1011        else if(o instanceof Double) return toBooleanValue(((Double)o).doubleValue());
1012        else if(o instanceof Number) return toBooleanValue(((Number)o).doubleValue());
1013        else if(o instanceof String) {
1014            Boolean b = toBoolean(o.toString(),null);
1015                if(b!=null) return b;
1016        }
1017        //else if(o instanceof Clob) return toBooleanValueEL(toStringEL(o));
1018        else if(o instanceof Castable) {
1019            return ((Castable)o).castToBoolean(Caster.toBoolean(defaultValue)).booleanValue();
1020            
1021        }
1022        else if(o == null) return toBooleanValue("",defaultValue);
1023        else if(o instanceof ObjectWrap) return toBooleanValue(((ObjectWrap)o).getEmbededObject(toBoolean(defaultValue)),defaultValue);
1024                
1025        return defaultValue;
1026    }
1027    
1028    /**
1029     * cast a Object to a boolean value (refrence type), Exception Less
1030     * @param o Object to cast
1031     * @param defaultValue default value
1032     * @return casted boolean reference
1033     */
1034    public static Boolean toBoolean(Object o,Boolean defaultValue) {
1035        if(o instanceof Boolean) return ((Boolean)o);
1036        else if(o instanceof Number) return ((Number)o).intValue()==0?Boolean.FALSE:Boolean.TRUE;
1037        else if(o instanceof String) {
1038            int rtn=stringToBooleanValueEL(o.toString());
1039            if(rtn==1)return Boolean.TRUE;
1040            else if(rtn==0)return Boolean.FALSE;
1041            else {
1042                double dbl = toDoubleValue(o.toString(),Double.NaN);
1043                if(!Double.isNaN(dbl)) return toBooleanValue(dbl)?Boolean.TRUE:Boolean.FALSE;
1044            }
1045            
1046        }
1047        //else if(o instanceof Clob) return toBooleanValueEL(toStringEL(o));
1048        else if(o instanceof Castable) {
1049            return ((Castable)o).castToBoolean(defaultValue);
1050        }
1051        else if(o instanceof ObjectWrap) return toBoolean(((ObjectWrap)o).getEmbededObject(defaultValue),defaultValue);
1052                
1053        else if(o == null) return toBoolean("",defaultValue);
1054        return defaultValue;
1055    }
1056    
1057    
1058    
1059
1060    
1061    /**
1062     * cast a boolean value to a char value
1063     * @param b boolean value to cast
1064     * @return casted char value
1065     */
1066    public static char toCharValue(boolean b) {
1067        return (char)(b?1:0);
1068    }
1069    
1070    /**
1071     * cast a double value to a char value (primitive value type)
1072     * @param d double value to cast
1073     * @return casted char value
1074     */
1075    public static char toCharValue(double d) {
1076        return (char)d;
1077    }
1078    
1079    /**
1080     * cast a char value to a char value (do nothing)
1081     * @param c char value to cast
1082     * @return casted char value
1083     */
1084    public static char toCharValue(char c) {
1085        return c;
1086    }
1087
1088    /**
1089     * cast a Object to a char value (primitive value type)
1090     * @param o Object to cast
1091     * @return casted char value
1092     * @throws PageException
1093     */
1094    public static char toCharValue(Object o) throws PageException {
1095        if(o instanceof Character) return ((Character)o).charValue();
1096        else if(o instanceof Boolean) return (char)((((Boolean)o).booleanValue())?1:0);
1097        else if(o instanceof Double) return (char)(((Double)o).doubleValue());
1098        else if(o instanceof Number) return (char)(((Number)o).doubleValue());
1099        else if(o instanceof String) {
1100            String str = o.toString();
1101            if(str.length()>0)return str.charAt(0);
1102            throw new ExpressionException("can't cast empty string to a char");
1103            
1104        }
1105        else if(o instanceof ObjectWrap) {
1106            return toCharValue(((ObjectWrap)o).getEmbededObject());
1107        }                                                                                                                                                                               
1108        else if(o == null) return toCharValue("");
1109        throw new CasterException(o,"char");
1110    }
1111
1112    /**
1113     * cast a Object to a char value (primitive value type)
1114     * @param str Object to cast
1115     * @return casted char value
1116     * @throws PageException
1117     */
1118    public static char toCharValue(String str) throws PageException {
1119            if(str.length()>0)return str.charAt(0);
1120            throw new ExpressionException("can't cast empty string to a char");
1121    }
1122    
1123    /**
1124     * cast a Object to a char value (primitive value type)
1125     * @param o Object to cast
1126     * @param defaultValue 
1127     * @return casted char value
1128     */
1129    public static char toCharValue(Object o, char defaultValue) {
1130        if(o instanceof Character) return ((Character)o).charValue();
1131        else if(o instanceof Boolean) return (char)((((Boolean)o).booleanValue())?1:0);
1132        else if(o instanceof Double) return (char)(((Double)o).doubleValue());
1133        else if(o instanceof Number) return (char)(((Number)o).doubleValue());
1134        else if(o instanceof String) {
1135            String str = o.toString();
1136            if(str.length()>0)return str.charAt(0);
1137            return defaultValue;
1138            
1139        }
1140        else if(o instanceof ObjectWrap) {
1141            return toCharValue(((ObjectWrap)o).getEmbededObject(toCharacter(defaultValue)),defaultValue);
1142        }                                                                                                                                                                               
1143        else if(o == null) return toCharValue("",defaultValue);
1144        return defaultValue;
1145    }
1146    
1147    /**
1148     * cast a boolean value to a Character Object(reference type)
1149     * @param b boolean value to cast
1150     * @return casted Character Object
1151     */
1152    public static Character toCharacter(boolean b) {
1153        return new Character(toCharValue(b));
1154    }
1155    
1156    /**
1157     * cast a char value to a Character Object(reference type)
1158     * @param c char value to cast
1159     * @return casted Character Object
1160     */
1161    public static Character toCharacter(char c) {
1162        return new Character(toCharValue(c));
1163    }
1164    
1165    /**
1166     * cast a double value to a Character Object(reference type)
1167     * @param d double value to cast
1168     * @return casted Character Object
1169     */
1170    public static Character toCharacter(double d) {
1171        return new Character(toCharValue(d));
1172    }
1173
1174    /**
1175     * cast a Object to a Character Object(reference type)
1176     * @param o Object to cast
1177     * @return casted Character Object
1178     * @throws PageException
1179     */
1180    public static Character toCharacter(Object o) throws PageException {
1181        if(o instanceof Character) return (Character)o;
1182        return new Character(toCharValue(o));
1183        
1184    }
1185
1186    /**
1187     * cast a Object to a Character Object(reference type)
1188     * @param str Object to cast
1189     * @return casted Character Object
1190     * @throws PageException
1191     */
1192    public static Character toCharacter(String str) throws PageException {
1193        return new Character(toCharValue(str));
1194        
1195    }
1196    
1197    /**
1198     * cast a Object to a Character Object(reference type)
1199     * @param o Object to cast
1200     * @param defaultValue 
1201     * @return casted Character Object
1202     */
1203    public static Character toCharacter(Object o, Character defaultValue) {
1204        if(o instanceof Character) return (Character)o;
1205        if(defaultValue!=null)return new Character(toCharValue(o,defaultValue.charValue()));
1206        
1207        char res = toCharValue(o,Character.MIN_VALUE);
1208        if(res==Character.MIN_VALUE) return defaultValue;
1209        return new Character(res);
1210    }
1211    
1212    /**
1213     * cast a boolean value to a byte value
1214     * @param b boolean value to cast
1215     * @return casted byte value
1216     */
1217    public static byte toByteValue(boolean b) {
1218        return (byte)(b?1:0);
1219    }
1220    
1221    /**
1222     * cast a double value to a byte value (primitive value type)
1223     * @param d double value to cast
1224     * @return casted byte value
1225     */
1226    public static byte toByteValue(double d) {
1227        return (byte)d;
1228    }
1229    
1230    /**
1231     * cast a char value to a byte value (do nothing)
1232     * @param c char value to cast
1233     * @return casted byte value
1234     */
1235    public static byte toByteValue(char c) {
1236        return (byte)c;
1237    }
1238    
1239    /**
1240     * cast a Object to a byte value (primitive value type)
1241     * @param o Object to cast
1242     * @return casted byte value
1243     * @throws PageException
1244     * @throws CasterException
1245     */
1246    public static byte toByteValue(Object o) throws PageException {
1247        if(o instanceof Byte) return ((Byte)o).byteValue();
1248        if(o instanceof Character) return (byte)(((Character)o).charValue());
1249        else if(o instanceof Boolean) return (byte)((((Boolean)o).booleanValue())?1:0);
1250        else if(o instanceof Number) return (((Number)o).byteValue());
1251        else if(o instanceof String) return (byte)toDoubleValue(o.toString());      
1252        else if(o instanceof ObjectWrap) {
1253            return toByteValue(((ObjectWrap)o).getEmbededObject());
1254        }
1255        throw new CasterException(o,"byte");
1256    }
1257    
1258    /**
1259     * cast a Object to a byte value (primitive value type)
1260     * @param str Object to cast
1261     * @return casted byte value
1262     * @throws PageException
1263     * @throws CasterException
1264     */
1265    public static byte toByteValue(String str) throws PageException {
1266        return (byte)toDoubleValue(str.toString());
1267    }
1268    
1269    /**
1270     * cast a Object to a byte value (primitive value type)
1271     * @param o Object to cast
1272     * @param defaultValue 
1273     * @return casted byte value
1274     */
1275    public static byte toByteValue(Object o, byte defaultValue) {
1276        if(o instanceof Byte)           return ((Byte)o).byteValue();
1277        if(o instanceof Character)      return (byte)(((Character)o).charValue());
1278        else if(o instanceof Boolean)   return (byte)((((Boolean)o).booleanValue())?1:0);
1279        else if(o instanceof Number)    return (((Number)o).byteValue());
1280        else if(o instanceof String)    return (byte)toDoubleValue(o.toString(),defaultValue);      
1281        else if(o instanceof ObjectWrap) {
1282            return toByteValue(((ObjectWrap)o).getEmbededObject(toByte(defaultValue)),defaultValue);
1283        }
1284        return defaultValue;
1285    }
1286    
1287    /**
1288     * cast a boolean value to a Byte Object(reference type)
1289     * @param b boolean value to cast
1290     * @return casted Byte Object
1291     */
1292    public static Byte toByte(boolean b) {
1293        return new Byte(toByteValue(b));
1294    }
1295    
1296    /**
1297     * cast a char value to a Byte Object(reference type)
1298     * @param c char value to cast
1299     * @return casted Byte Object
1300     */
1301    public static Byte toByte(char c) {
1302        return new Byte(toByteValue(c));
1303    }
1304    
1305    /**
1306     * cast a double value to a Byte Object(reference type)
1307     * @param d double value to cast
1308     * @return casted Byte Object
1309     */
1310    public static Byte toByte(double d) {
1311        return new Byte(toByteValue(d));
1312    }
1313
1314    /**
1315     * cast a Object to a Byte Object(reference type)
1316     * @param o Object to cast
1317     * @return casted Byte Object
1318     * @throws PageException
1319     */
1320    public static Byte toByte(Object o) throws PageException {
1321        if(o instanceof Byte) return (Byte)o;
1322        return new Byte(toByteValue(o));
1323        
1324    }
1325
1326    /**
1327     * cast a Object to a Byte Object(reference type)
1328     * @param str String to cast
1329     * @return casted Byte Object
1330     * @throws PageException
1331     */
1332    public static Byte toByte(String str) throws PageException {
1333        return new Byte(toByteValue(str));
1334        
1335    }
1336
1337    /**
1338     * cast a Object to a Byte Object(reference type)
1339     * @param o Object to cast
1340     * @param defaultValue 
1341     * @return casted Byte Object
1342     */
1343    public static Byte toByte(Object o, Byte defaultValue) {
1344        if(o instanceof Byte) return (Byte)o;
1345        if(defaultValue!=null) return new Byte(toByteValue(o,defaultValue.byteValue()));
1346        byte res=toByteValue(o,Byte.MIN_VALUE);
1347        if(res==Byte.MIN_VALUE) return defaultValue;
1348        return new Byte(res);
1349    }
1350
1351    /**
1352     * cast a boolean value to a long value
1353     * @param b boolean value to cast
1354     * @return casted long value
1355     */
1356    public static long toLongValue(boolean b) {
1357        return (b?1L:0L);
1358    }
1359    
1360    /**
1361     * cast a double value to a long value (primitive value type)
1362     * @param d double value to cast
1363     * @return casted long value
1364     */
1365    public static long toLongValue(double d) {
1366        return (long)d;
1367    }
1368    
1369    /**
1370     * cast a char value to a long value (do nothing)
1371     * @param c char value to cast
1372     * @return casted long value
1373     */
1374    public static long toLongValue(char c) {
1375        return c;
1376    }
1377    
1378    /**
1379     * cast a Object to a long value (primitive value type)
1380     * @param o Object to cast
1381     * @return casted long value
1382     * @throws PageException
1383     */
1384    public static long toLongValue(Object o) throws PageException {
1385        if(o instanceof Character) return (((Character)o).charValue());
1386        else if(o instanceof Boolean) return ((((Boolean)o).booleanValue())?1L:0L);
1387        else if(o instanceof Number) return (((Number)o).longValue());
1388        else if(o instanceof String) {
1389                String str=(String)o;
1390                try{
1391                        return Long.parseLong(str);
1392                }
1393                catch(NumberFormatException nfe){
1394                        return (long)toDoubleValue(str);
1395                }                                                                                                                                                     
1396        }
1397        else if(o instanceof Castable) return (long)((Castable)o).castToDoubleValue();    
1398        else if(o instanceof ObjectWrap) return toLongValue(((ObjectWrap)o).getEmbededObject());
1399                
1400        throw new CasterException(o,"long");
1401    }
1402    
1403    /**
1404     * cast a Object to a long value (primitive value type)
1405     * @param str Object to cast
1406     * @return casted long value
1407     * @throws PageException
1408     */
1409    public static long toLongValue(String str) throws PageException {
1410        BigInteger bi=null;
1411        try {
1412                bi = new BigInteger(str);
1413                
1414        }
1415        catch(Throwable t){
1416                        ExceptionUtil.rethrowIfNecessary(t);
1417                }
1418        if(bi!=null) {
1419                if(bi.bitLength()<64) return bi.longValue();
1420                throw new ApplicationException("number ["+str+"] cannot be casted to a long value, number is to long ("+(bi.bitLength()+1)+" bit)");
1421        }
1422        return (long)toDoubleValue(str); 
1423    }
1424    
1425    /**
1426     * returns a number Object, this can be a BigDecimal,BigInteger,Long, Double, depending on the input.
1427     * @param str
1428     * @return
1429     * @throws PageException
1430     */
1431    public static Number toNumber(String str, Number defaultValue) {
1432        try{
1433                // float
1434                if(str.indexOf('.')!=-1) {
1435                        return new BigDecimal(str);
1436                }
1437                // integer
1438                BigInteger bi = new BigInteger(str);
1439                int l = bi.bitLength();
1440                if(l<32) return new Integer(bi.intValue());
1441                if(l<64) return new Long(bi.longValue());
1442                return bi;
1443        }
1444        catch(Throwable t) {
1445                        ExceptionUtil.rethrowIfNecessary(t);
1446                return defaultValue;
1447        }
1448    }
1449    
1450    /**
1451     * cast a Object to a long value (primitive value type)
1452     * @param o Object to cast
1453     * @param defaultValue 
1454     * @return casted long value
1455     */
1456    public static long toLongValue(Object o, long defaultValue) {
1457        if(o instanceof Character) return (((Character)o).charValue());
1458        else if(o instanceof Boolean) return ((((Boolean)o).booleanValue())?1L:0L);
1459        else if(o instanceof Number) return (((Number)o).longValue());
1460        else if(o instanceof String) return (long)toDoubleValue(o.toString(),defaultValue);                                                                                                                                                      
1461        else if(o instanceof Castable) {
1462            return (long)((Castable)o).castToDoubleValue(defaultValue);                                                                                           
1463        }
1464        else if(o instanceof ObjectWrap) return toLongValue(((ObjectWrap)o).getEmbededObject(toLong(defaultValue)),defaultValue);
1465                
1466        return defaultValue;
1467    }
1468    
1469    /**
1470     * cast a boolean value to a Long Object(reference type)
1471     * @param b boolean value to cast
1472     * @return casted Long Object
1473     */
1474    public static Long toLong(boolean b) {
1475        return Long.valueOf(toLongValue(b));
1476    }
1477    
1478    /**
1479     * cast a char value to a Long Object(reference type)
1480     * @param c char value to cast
1481     * @return casted Long Object
1482     */
1483    public static Long toLong(char c) {
1484        return Long.valueOf(toLongValue(c));
1485    }
1486    
1487    /**
1488     * cast a double value to a Long Object(reference type)
1489     * @param d double value to cast
1490     * @return casted Long Object
1491     */
1492    public static Long toLong(double d) {
1493        return Long.valueOf(toLongValue(d));
1494    }
1495
1496    /**
1497     * cast a Object to a Long Object(reference type)
1498     * @param o Object to cast
1499     * @return casted Long Object
1500     * @throws PageException
1501     */
1502    public static Long toLong(Object o) throws PageException {
1503        if(o instanceof Long) return (Long)o; 
1504        return Long.valueOf(toLongValue(o));
1505        
1506    }
1507
1508    /**
1509     * cast a Object to a Long Object(reference type)
1510     * @param str Object to cast
1511     * @return casted Long Object
1512     * @throws PageException
1513     */
1514    public static Long toLong(String str) throws PageException {
1515        return Long.valueOf(toLongValue(str));
1516        
1517    }
1518
1519    /**
1520     * cast a long to a Long Object(reference type)
1521     * @param l long to cast
1522     * @return casted Long Object
1523     */
1524    public static Long toLong(long l) {
1525        return Long.valueOf(l);
1526        
1527    }
1528
1529    /**
1530     * cast a Object to a Long Object(reference type)
1531     * @param o Object to cast
1532     * @param defaultValue 
1533     * @return casted Long Object
1534     */
1535    public static Long toLong(Object o, Long defaultValue) {
1536        if(o instanceof Long) return (Long)o;
1537        if(defaultValue!=null) return Long.valueOf(toLongValue(o,defaultValue.longValue()));
1538        
1539        long res=toLongValue(o,Long.MIN_VALUE);
1540        if(res==Long.MIN_VALUE) return defaultValue;
1541        return Long.valueOf(res);
1542    }
1543    
1544    /**
1545     * cast a boolean value to a Float Object(reference type)
1546     * @param b boolean value to cast
1547     * @return casted Float Object
1548     */
1549    public static Float toFloat(boolean b) {
1550        return new Float(toFloatValue(b));
1551    }
1552    
1553    /**
1554     * cast a char value to a Float Object(reference type)
1555     * @param c char value to cast
1556     * @return casted Float Object
1557     */
1558    public static Float toFloat(char c) {
1559        return new Float(toFloatValue(c));
1560    }
1561    
1562    /**
1563     * cast a double value to a Float Object(reference type)
1564     * @param d double value to cast
1565     * @return casted Float Object
1566     */
1567    public static Float toFloat(double d) {
1568        return new Float(toFloatValue(d));
1569    }
1570
1571    /**
1572     * cast a Object to a Float Object(reference type)
1573     * @param o Object to cast
1574     * @return casted Float Object
1575     * @throws PageException
1576     */
1577    public static Float toFloat(Object o) throws PageException {
1578        if(o instanceof Float) return (Float)o;
1579        return new Float(toFloatValue(o));
1580    }
1581
1582    /**
1583     * cast a Object to a Float Object(reference type)
1584     * @param str Object to cast
1585     * @return casted Float Object
1586     * @throws PageException
1587     */
1588    public static Float toFloat(String str) throws PageException {
1589        return new Float(toFloatValue(str));
1590    }
1591
1592    /**
1593     * cast a Object to a Float Object(reference type)
1594     * @param o Object to cast
1595     * @param defaultValue 
1596     * @return casted Float Object
1597     */
1598    public static Float toFloat(Object o, Float defaultValue) {
1599        if(o instanceof Float) return (Float)o;
1600        if(defaultValue!=null) return new Float(toFloatValue(o,defaultValue.floatValue()));
1601        
1602        float res=toFloatValue(o,Float.MIN_VALUE);
1603        if(res==Float.MIN_VALUE) return defaultValue;
1604        return new Float(res);
1605    }
1606    
1607    
1608    
1609    
1610    /**
1611     * cast a boolean value to a float value
1612     * @param b boolean value to cast
1613     * @return casted long value
1614     */
1615    public static float toFloatValue(boolean b) {
1616        return (b?1F:0F);
1617    }
1618    
1619    /**
1620     * cast a double value to a long value (primitive value type)
1621     * @param d double value to cast
1622     * @return casted long value
1623     */
1624    public static float toFloatValue(double d) {
1625        return (float)d;
1626    }
1627    
1628    /**
1629     * cast a char value to a long value (do nothing)
1630     * @param c char value to cast
1631     * @return casted long value
1632     */
1633    public static float toFloatValue(char c) {
1634        return c;
1635    }
1636    
1637    /**
1638     * cast a Object to a long value (primitive value type)
1639     * @param o Object to cast
1640     * @return casted long value
1641     * @throws PageException
1642     */
1643    public static float toFloatValue(Object o) throws PageException {
1644        if(o instanceof Character) return (((Character)o).charValue());
1645        else if(o instanceof Boolean) return ((((Boolean)o).booleanValue())?1F:0F);
1646        else if(o instanceof Number) return (((Number)o).floatValue());
1647        else if(o instanceof String) return (float)toDoubleValue(o.toString());                                                                                                                                                      
1648        else if(o instanceof Castable) return (float)((Castable)o).castToDoubleValue();    
1649        else if(o instanceof ObjectWrap) return toFloatValue(((ObjectWrap)o).getEmbededObject());
1650                
1651        throw new CasterException(o,"float");
1652    }
1653    
1654    /**
1655     * cast a Object to a long value (primitive value type)
1656     * @param str Object to cast
1657     * @return casted long value
1658     * @throws PageException
1659     */
1660    public static float toFloatValue(String str) throws PageException {
1661        return (float)toDoubleValue(str);  
1662    }
1663    
1664    /**
1665     * cast a Object to a float value (primitive value type)
1666     * @param o Object to cast
1667     * @param defaultValue 
1668     * @return casted float value
1669     */
1670    public static float toFloatValue(Object o, float defaultValue) {
1671        if(o instanceof Character) return (((Character)o).charValue());
1672        else if(o instanceof Boolean) return ((((Boolean)o).booleanValue())?1F:0F);
1673        else if(o instanceof Number) return (((Number)o).floatValue());
1674        else if(o instanceof String) return (float)toDoubleValue(o.toString(),defaultValue);                                                                                                                                                      
1675        else if(o instanceof Castable) {
1676            return (float)((Castable)o).castToDoubleValue(defaultValue);
1677                                                                                                                                                                  
1678        }
1679        else if(o instanceof ObjectWrap) return toFloatValue(((ObjectWrap)o).getEmbededObject(toFloat(defaultValue)),defaultValue);
1680                
1681        return defaultValue;
1682    }
1683
1684    /**
1685     * cast a boolean value to a short value
1686     * @param b boolean value to cast
1687     * @return casted short value
1688     */
1689    public static short toShortValue(boolean b) {
1690        return (short)(b?1:0);
1691    }
1692    
1693    /**
1694     * cast a double value to a short value (primitive value type)
1695     * @param d double value to cast
1696     * @return casted short value
1697     */
1698    public static short toShortValue(double d) {
1699        return (short)d;
1700    }
1701    
1702    /**
1703     * cast a char value to a short value (do nothing)
1704     * @param c char value to cast
1705     * @return casted short value
1706     */
1707    public static short toShortValue(char c) {
1708        return (short)c;
1709    }
1710    
1711    /**
1712     * cast a Object to a short value (primitive value type)
1713     * @param o Object to cast
1714     * @return casted short value
1715     * @throws PageException
1716     */
1717    public static short toShortValue(Object o) throws PageException {
1718        if(o instanceof Short) return ((Short)o).shortValue();
1719        if(o instanceof Character) return (short)(((Character)o).charValue());
1720        else if(o instanceof Boolean) return (short)((((Boolean)o).booleanValue())?1:0);
1721        else if(o instanceof Number) return (((Number)o).shortValue());
1722        else if(o instanceof String) return (short)toDoubleValue(o.toString());                                                                                                                                                             
1723        else if(o instanceof Castable) return (short)((Castable)o).castToDoubleValue(); 
1724        else if(o instanceof ObjectWrap) return toShortValue(((ObjectWrap)o).getEmbededObject());
1725                
1726        throw new CasterException(o,"short");
1727    }
1728    
1729    /**
1730     * cast a Object to a short value (primitive value type)
1731     * @param str Object to cast
1732     * @return casted short value
1733     * @throws PageException
1734     */
1735    public static short toShortValue(String str) throws PageException {
1736        return (short)toDoubleValue(str);     
1737    }
1738    
1739    /**
1740     * cast a Object to a short value (primitive value type)
1741     * @param o Object to cast
1742     * @param defaultValue 
1743     * @return casted short value
1744     */
1745    public static short toShortValue(Object o, short defaultValue) {
1746        if(o instanceof Short) return ((Short)o).shortValue();
1747        if(o instanceof Character) return (short)(((Character)o).charValue());
1748        else if(o instanceof Boolean) return (short)((((Boolean)o).booleanValue())?1:0);
1749        else if(o instanceof Number) return (((Number)o).shortValue());
1750        else if(o instanceof String) return (short)toDoubleValue(o.toString(),defaultValue);                                                                                                                                                             
1751        else if(o instanceof Castable) {
1752            return (short)((Castable)o).castToDoubleValue(defaultValue);
1753                                                                                                                                            
1754        }
1755        else if(o instanceof ObjectWrap) return toShortValue(((ObjectWrap)o).getEmbededObject(toShort(defaultValue)),defaultValue);
1756                
1757        return defaultValue;
1758    }
1759    
1760    /**
1761     * cast a boolean value to a Short Object(reference type)
1762     * @param b boolean value to cast
1763     * @return casted Short Object
1764     */
1765    public static Short toShort(boolean b) {
1766        return Short.valueOf(toShortValue(b));
1767    }
1768    
1769    /**
1770     * cast a char value to a Short Object(reference type)
1771     * @param c char value to cast
1772     * @return casted Short Object
1773     */
1774    public static Short toShort(char c) {
1775        return Short.valueOf(toShortValue(c));
1776    }
1777    
1778    /**
1779     * cast a double value to a Byte Object(reference type)
1780     * @param d double value to cast
1781     * @return casted Byte Object
1782     */
1783    public static Short toShort(double d) {
1784        return Short.valueOf(toShortValue(d));
1785    }
1786
1787    /**
1788     * cast a Object to a Byte Object(reference type)
1789     * @param o Object to cast
1790     * @return casted Byte Object
1791     * @throws PageException
1792     */
1793    public static Short toShort(Object o) throws PageException {
1794        if(o instanceof Short) return (Short)o;
1795        return Short.valueOf(toShortValue(o));
1796        
1797    }
1798
1799    /**
1800     * cast a Object to a Byte Object(reference type)
1801     * @param str Object to cast
1802     * @return casted Byte Object
1803     * @throws PageException
1804     */
1805    public static Short toShort(String str) throws PageException {
1806        return Short.valueOf(toShortValue(str));
1807        
1808    }
1809
1810    /**
1811     * cast a Object to a Byte Object(reference type)
1812     * @param o Object to cast
1813     * @param defaultValue 
1814     * @return casted Byte Object
1815     */
1816    public static Short toShort(Object o, Short defaultValue) {
1817        if(o instanceof Short) return (Short)o;
1818        if(defaultValue!=null)return Short.valueOf(toShortValue(o,defaultValue.shortValue()));
1819        short res=toShortValue(o,Short.MIN_VALUE);
1820        if(res==Short.MIN_VALUE) return defaultValue;
1821        return Short.valueOf(res);
1822    }
1823    
1824    /**
1825     * cast a String to a boolean value (primitive value type)
1826     * @param str String to cast
1827     * @return casted boolean value
1828     * @throws ExpressionException
1829     */
1830    public static boolean stringToBooleanValue(String str) throws ExpressionException {
1831        str=StringUtil.toLowerCase(str.trim());
1832        if(str.equals("yes") || str.equals("true")) return true;
1833        else if(str.equals("no") || str.equals("false")) return false;
1834        throw new CasterException("Can't cast String ["+str+"] to boolean");
1835    }
1836    
1837    /**
1838     * cast a String to a boolean value (primitive value type), return 1 for true, 0 for false and -1 if can't cast to a boolean type
1839     * @param str String to cast
1840     * @return casted boolean value
1841     */
1842    public static int stringToBooleanValueEL(String str) {
1843        if(str.length()<2) return -1;
1844        switch(str.charAt(0)) {
1845            case 't':
1846            case 'T': return str.equalsIgnoreCase("true")?1:-1;
1847            case 'f':
1848            case 'F': return str.equalsIgnoreCase("false")?0:-1;
1849            case 'y':
1850            case 'Y': return str.equalsIgnoreCase("yes")?1:-1;
1851            case 'n':
1852            case 'N': return str.equalsIgnoreCase("no")?0:-1;
1853        }
1854        return -1;
1855    }
1856
1857    /**
1858     * cast a Object to a String
1859     * @param o Object to cast
1860     * @return casted String
1861     * @throws PageException
1862     */
1863    public static String toString(Object o) throws PageException {
1864        if(o instanceof String) return (String)o;
1865        else if(o instanceof Number) return toString(((Number)o));
1866        else if(o instanceof Boolean) return toString(((Boolean)o).booleanValue());
1867        else if(o instanceof Castable) return ((Castable)o).castToString();
1868        else if(o instanceof Date) {
1869            if(o instanceof DateTime) return ((DateTime)o).castToString();
1870            return new DateTimeImpl((Date)o).castToString();
1871        }
1872        else if(o instanceof Clob) return toString((Clob)o);
1873        else if(o instanceof Node) return XMLCaster.toString((Node)o);
1874        else if(o instanceof Reader) {
1875                Reader r=null;
1876                        try {
1877                                return IOUtil.toString(r=(Reader)o);
1878                        } 
1879                        catch (IOException e) {
1880                                throw Caster.toPageException(e);
1881                        }
1882                        finally {
1883                                IOUtil.closeEL(r);
1884                        }
1885        }
1886        else if(o instanceof InputStream) {
1887                PageContextImpl pc = (PageContextImpl) ThreadLocalPageContext.get();
1888                InputStream r=null;
1889                        try {
1890                                return IOUtil.toString(r=(InputStream)o,pc.getWebCharset());
1891                        } 
1892                        catch (IOException e) {
1893                                throw Caster.toPageException(e);
1894                        }
1895                        finally {
1896                                IOUtil.closeEL(r);
1897                        }
1898        }
1899        else if(o instanceof byte[]) {
1900                PageContextImpl pc = (PageContextImpl) ThreadLocalPageContext.get();
1901                
1902                try {
1903                                return new String((byte[])o,pc.getWebCharset());
1904                        } catch (Throwable t) {
1905                                ExceptionUtil.rethrowIfNecessary(t);
1906                                return new String((byte[])o);
1907                        }
1908        }
1909        else if(o instanceof char[]) return new String((char[])o);
1910        else if(o instanceof ObjectWrap) return toString(((ObjectWrap)o).getEmbededObject());
1911        else if(o instanceof Calendar) return toString(((Calendar)o).getTime());
1912        else if(o == null) return "";
1913        
1914        // INFO Collection is new of type Castable 
1915        if(o instanceof Map || o instanceof List || o instanceof Function)
1916            throw new CasterException(o,"string");
1917        /*if((x instanceof Query) || 
1918                        (x instanceof RowSet) || 
1919                        (x instanceof coldfusion.runtime.Array) || 
1920                        (x instanceof JavaProxy) || 
1921                        (x instanceof FileStreamWrapper))
1922        */
1923        
1924        
1925        return o.toString();
1926    }
1927    
1928    /**
1929     * cast a String to a String (do Nothing)
1930     * @param str
1931     * @return casted String
1932     * @throws PageException
1933     */
1934    public static String toString(String str) {
1935        return str;
1936    }
1937    
1938    public static StringBuffer toStringBuffer(Object obj) throws PageException {
1939        if(obj instanceof StringBuffer) return (StringBuffer) obj;
1940        return new StringBuffer(toString(obj));
1941    }
1942
1943    public static Collection.Key toKey(Object o) throws CasterException { 
1944        return KeyImpl.toKey(o);
1945    }
1946    public static Collection.Key toKey(Object o,Collection.Key defaultValue) {
1947        return KeyImpl.toKey(o, defaultValue);
1948    }
1949    
1950
1951    /**
1952     * cast a Object to a String dont throw a exception, if can't cast to a string return a empty string
1953     * @param o Object to cast
1954     * @param defaultValue 
1955     * @return casted String
1956     */
1957    public static String toString(Object o,String defaultValue) {
1958        return toString(o,true,defaultValue);
1959    }
1960    
1961    public static String toString(Object o, boolean executeDefaultToStringMethod, String defaultValue) {
1962        if(o instanceof String) return (String)o;
1963        else if(o instanceof Boolean) return toString(((Boolean)o).booleanValue());
1964        else if(o instanceof Number) return toString(((Number)o));
1965        else if(o instanceof Castable) return ((Castable)o).castToString(defaultValue);
1966        else if(o instanceof Date) {
1967            if(o instanceof DateTime) {
1968                return ((DateTime)o).castToString(defaultValue);
1969                
1970            }
1971            return new DateTimeImpl((Date)o).castToString(defaultValue);
1972        }
1973        else if(o instanceof Clob) {
1974            try {
1975                return toString((Clob)o);
1976            } catch (ExpressionException e) {
1977                return defaultValue;
1978            }
1979        }
1980        else if(o instanceof Node) {
1981            try {
1982                return XMLCaster.toString((Node)o);
1983            } catch (PageException e) {
1984                return defaultValue;
1985            }
1986        }
1987        else if(o instanceof Map || o instanceof List || o instanceof Function) return defaultValue;
1988        else if(o == null) return "";
1989        else if(o instanceof ObjectWrap) return toString(((ObjectWrap)o).getEmbededObject(defaultValue),defaultValue);
1990                return executeDefaultToStringMethod?o.toString():defaultValue;
1991    }
1992
1993    private static String toString(Clob clob) throws ExpressionException {
1994        try {
1995        Reader in = clob.getCharacterStream();
1996        StringBuffer buf = new StringBuffer();
1997        for(int c=in.read();c != -1;c = in.read()) {
1998            buf.append((char)c);
1999        }
2000        return buf.toString();
2001        }
2002        catch(Exception e) {
2003            throw ExpressionException.newInstance(e);
2004        }
2005    }
2006    
2007    
2008    /**
2009     * cast a double value to a String
2010     * @param d double value to cast
2011     * @return casted String
2012     */
2013    public static String toString3(double d) {
2014        
2015        long l = (long)d;
2016        if(l == d) return toString(l);
2017        String str = Double.toString(d);
2018        int pos;
2019        if((pos=str.indexOf('E'))!=-1 && pos==str.length()-2){
2020            return new StringBuffer(pos+2).
2021            append(str.charAt(0)).
2022            append(str.substring(2,toDigit(str.charAt(pos+1))+2)).
2023            append('.').
2024            append(str.substring(toDigit(str.charAt(pos+1))+2,pos)).
2025            toString();
2026            
2027        }
2028        return str;
2029    }
2030    private static DecimalFormat df=(DecimalFormat) DecimalFormat.getInstance(Locale.US);//("#.###########");
2031        static { df.applyLocalizedPattern("#.############");}
2032
2033    public static String toString(double d) {
2034        long l = (long)d;
2035        if(l == d) return toString(l);
2036        
2037        if(d>l && (d-l)<0.000000000001)  return toString(l);
2038        if(l>d && (l-d)<0.000000000001)  return toString(l);
2039        
2040        return df.format(d);
2041    }
2042    
2043    public static String toString(Number n) {
2044        double d = n.doubleValue();
2045        long l = (long)d;
2046        if(l == d) return toString(l);
2047        
2048        if(d>l && (d-l)<0.000000000001)  return toString(l);
2049        if(l>d && (l-d)<0.000000000001)  return toString(l);
2050        
2051        if(n instanceof Double) return toString(n.doubleValue());
2052        return n.toString();
2053        //return df.format(d);
2054    }
2055    
2056    /**
2057     * cast a long value to a String
2058     * @param l long value to cast
2059     * @return casted String
2060     */
2061    public static String toString(long l) {
2062        if(l<NUMBERS_MIN || l>NUMBERS_MAX) {
2063            return Long.toString(l, 10);
2064        }
2065        return NUMBERS[(int)l];
2066    }
2067    
2068    /**
2069     * cast a int value to a String
2070     * @param i int value to cast
2071     * @return casted String
2072     */
2073    public static String toString(int i) {
2074        if(i<NUMBERS_MIN || i>NUMBERS_MAX) return Integer.toString(i, 10);
2075        return NUMBERS[i];
2076    }
2077
2078    /**
2079     * cast a boolean value to a String
2080     * @param b boolean value to cast
2081     * @return casted String
2082     */
2083    public static String toString(boolean b) {
2084        return b?"true":"false";
2085    }
2086
2087    public static UDF toFunction(Object o) throws PageException {
2088        if(o instanceof UDF) return (UDF)o;
2089        
2090        else if(o instanceof ObjectWrap) {
2091            return toFunction(((ObjectWrap)o).getEmbededObject());
2092        }
2093        throw new CasterException(o,"function");
2094    }
2095
2096    public static UDF toFunction(Object o, UDF defaultValue) {
2097        if(o instanceof UDF) return (UDF)o;
2098        
2099        else if(o instanceof ObjectWrap) {
2100            return toFunction(((ObjectWrap)o).getEmbededObject(defaultValue),defaultValue);
2101        }
2102        return defaultValue;
2103    }
2104    
2105    /**
2106     * cast a Object to a Array Object
2107     * @param o Object to cast
2108     * @return casted Array
2109     * @throws PageException
2110     */
2111    public static List toList(Object o) throws PageException {
2112        return toList(o,false);
2113    }
2114    
2115    /**
2116     * cast a Object to a Array Object
2117     * @param o Object to cast
2118     * @param defaultValue 
2119     * @return casted Array
2120     */
2121    public static List toList(Object o, List defaultValue) {
2122        return toList(o,false,defaultValue);
2123    }
2124    
2125    /**
2126     * cast a Object to a Array Object
2127     * @param o Object to cast
2128     * @param duplicate 
2129     * @param defaultValue 
2130     * @return casted Array
2131     */
2132    public static List toList(Object o, boolean duplicate, List defaultValue) {
2133        try {
2134            return toList(o,duplicate);
2135        } catch (PageException e) {
2136            return defaultValue;
2137        }
2138    }
2139    
2140    /**
2141     * cast a Object to a Array Object
2142     * @param o Object to cast
2143     * @param duplicate 
2144     * @return casted Array
2145     * @throws PageException
2146     */
2147    public static List toList(Object o, boolean duplicate) throws PageException {
2148        if(o instanceof List) {
2149            if(duplicate) {
2150                List src=(List)o;
2151                int size=src.size();
2152                ArrayList trg = new ArrayList();
2153                
2154                for(int i=0;i<size;i++) {
2155                    trg.add(i,src.get(i));
2156                }
2157                return trg;
2158                
2159            }
2160            return (List)o;
2161        }
2162        else if(o instanceof Object[]) {
2163                ArrayList list=new ArrayList();
2164            Object[] arr=(Object[])o;
2165            for(int i=0;i<arr.length;i++)list.add(i,arr[i]);
2166            return list;
2167        }
2168        else if(o instanceof Array) {
2169            if(!duplicate)return ArrayAsList.toList((Array)o);
2170                ArrayList list=new ArrayList();
2171            Array arr=(Array)o;
2172            for(int i=0;i<arr.size();i++)list.add(i,arr.get(i+1,null));
2173            return list;
2174        }
2175        else if(o instanceof Iterator) {
2176                Iterator it=(Iterator) o;
2177            ArrayList list=new ArrayList();
2178            while(it.hasNext()){
2179                list.add(it.next());
2180            }
2181            return list;
2182        }
2183        else if(o instanceof XMLStruct) {
2184            XMLStruct sct=((XMLStruct)o);
2185            if(sct instanceof XMLMultiElementStruct) return toList(new XMLMultiElementArray((XMLMultiElementStruct) o));
2186            ArrayList list=new ArrayList();
2187            list.add(sct);
2188            return list;
2189        }
2190        else if(o instanceof ObjectWrap) {
2191            return toList(((ObjectWrap)o).getEmbededObject());
2192        }
2193        else if(o instanceof Struct) {
2194            Struct sct=(Struct) o;
2195            ArrayList arr=new ArrayList();
2196            
2197            Iterator<Entry<Key, Object>> it = sct.entryIterator();
2198            Entry<Key, Object> e=null;
2199            try {
2200                while(it.hasNext()) {
2201                        e = it.next();
2202                    arr.add(toIntValue(e.getKey().getString()),e.getValue());
2203                }
2204            } 
2205            catch (ExpressionException ee) {
2206                throw new ExpressionException("can't cast struct to a array, key ["+(e!=null?e.getKey():"")+"] is not a number");
2207            }
2208            return arr;
2209        }
2210        else if(o instanceof boolean[])return toList(ArrayUtil.toReferenceType((boolean[])o));
2211        else if(o instanceof byte[])return toList(ArrayUtil.toReferenceType((byte[])o));
2212        else if(o instanceof char[])return toList(ArrayUtil.toReferenceType((char[])o));
2213        else if(o instanceof short[])return toList(ArrayUtil.toReferenceType((short[])o));
2214        else if(o instanceof int[])return toList(ArrayUtil.toReferenceType((int[])o));
2215        else if(o instanceof long[])return toList(ArrayUtil.toReferenceType((long[])o));
2216        else if(o instanceof float[])return toList(ArrayUtil.toReferenceType((float[])o));
2217        else if(o instanceof double[])return toList(ArrayUtil.toReferenceType((double[])o));
2218        
2219        throw new CasterException(o,"List");
2220        
2221
2222    }
2223    
2224    /**
2225     * cast a Object to a Array Object
2226     * @param o Object to cast
2227     * @return casted Array
2228     * @throws PageException
2229     */
2230    public static Array toArray(Object o) throws PageException {
2231        if(o instanceof Array) return (Array)o;
2232        else if(o instanceof Object[]) {
2233            return new ArrayImpl((Object[])o);
2234        }
2235        else if(o instanceof List) {
2236            return ListAsArray.toArray((List)o);//new ArrayImpl(((List) o).toArray());
2237        }
2238        else if(o instanceof Set) {
2239                
2240            return toArray(((Set)o).toArray());//new ArrayImpl(((List) o).toArray());
2241        }
2242        else if(o instanceof XMLStruct) {
2243                XMLMultiElementStruct xmes;
2244                if(o instanceof XMLMultiElementStruct) {
2245                        xmes=(XMLMultiElementStruct)o;
2246                }
2247                else {
2248                        XMLStruct sct=(XMLStruct) o;
2249                    Array a=new ArrayImpl();
2250                    a.append(o);
2251                    xmes=new XMLMultiElementStruct(a, sct.getCaseSensitive());
2252                }
2253                return new XMLMultiElementArray(xmes);
2254        }
2255        else if(o instanceof ObjectWrap) {
2256            return toArray(((ObjectWrap)o).getEmbededObject());
2257        }
2258        else if(o instanceof Struct) {
2259            Struct sct=(Struct) o;
2260            Array arr=new ArrayImpl();
2261            
2262            Iterator<Entry<Key, Object>> it = sct.entryIterator();
2263            Entry<Key, Object> e=null;
2264            try {
2265                while(it.hasNext()) {
2266                        e = it.next();
2267                    arr.setE(toIntValue(e.getKey().getString()),e.getValue());
2268                }
2269            } 
2270            catch (ExpressionException ee) {
2271                throw new ExpressionException("can't cast struct to a array, key ["+e.getKey().getString()+"] is not a number");
2272            }
2273            return arr;
2274        }
2275        else if(o instanceof boolean[])return new ArrayImpl(ArrayUtil.toReferenceType((boolean[])o));
2276        else if(o instanceof byte[])return new ArrayImpl(ArrayUtil.toReferenceType((byte[])o));
2277        else if(o instanceof char[])return new ArrayImpl(ArrayUtil.toReferenceType((char[])o));
2278        else if(o instanceof short[])return new ArrayImpl(ArrayUtil.toReferenceType((short[])o));
2279        else if(o instanceof int[])return new ArrayImpl(ArrayUtil.toReferenceType((int[])o));
2280        else if(o instanceof long[])return new ArrayImpl(ArrayUtil.toReferenceType((long[])o));
2281        else if(o instanceof float[])return new ArrayImpl(ArrayUtil.toReferenceType((float[])o));
2282        else if(o instanceof double[])return new ArrayImpl(ArrayUtil.toReferenceType((double[])o));
2283        
2284        throw new CasterException(o,"Array");
2285    }
2286    
2287    public static Object[] toNativeArray(Object o) throws PageException {
2288        if(o instanceof Object[]) {
2289            return (Object[])o;
2290        }
2291        else if(o instanceof Array) {
2292                Array arr=(Array)o;
2293                Object[] objs=new Object[arr.size()];
2294                for(int i=0;i<objs.length;i++) {
2295                        objs[i]=arr.get(i+1, null);
2296                }
2297                return objs;
2298        }
2299        else if(o instanceof List) {
2300            return ((List) o).toArray();
2301        }
2302        else if(o instanceof XMLStruct) {
2303            XMLStruct sct=((XMLStruct)o);
2304            if(sct instanceof XMLMultiElementStruct) return toNativeArray((sct));
2305            Object[] a=new Object[1];
2306            a[0]=sct;
2307            return a;
2308        }
2309        else if(o instanceof ObjectWrap) {
2310            return toNativeArray(((ObjectWrap)o).getEmbededObject());
2311        }
2312        else if(o instanceof Struct) {
2313            Struct sct=(Struct) o;
2314            Array arr=new ArrayImpl();
2315            
2316            Iterator<Entry<Key, Object>> it = sct.entryIterator();
2317            Entry<Key, Object> e=null;
2318            try {
2319                while(it.hasNext()) {
2320                        e=it.next();
2321                    arr.setE(toIntValue(e.getKey().getString()),e.getValue());
2322                }
2323            } 
2324            catch (ExpressionException ee) {
2325                throw new ExpressionException("can't cast struct to a array, key ["+e.getKey()+"] is not a number");
2326            }
2327            return toNativeArray(arr);
2328        }
2329        else if(o instanceof boolean[])return ArrayUtil.toReferenceType((boolean[])o);
2330        else if(o instanceof byte[])return ArrayUtil.toReferenceType((byte[])o);
2331        else if(o instanceof char[])return ArrayUtil.toReferenceType((char[])o);
2332        else if(o instanceof short[])return ArrayUtil.toReferenceType((short[])o);
2333        else if(o instanceof int[])return ArrayUtil.toReferenceType((int[])o);
2334        else if(o instanceof long[])return ArrayUtil.toReferenceType((long[])o);
2335        else if(o instanceof float[])return ArrayUtil.toReferenceType((float[])o);
2336        else if(o instanceof double[])return ArrayUtil.toReferenceType((double[])o);
2337        
2338        throw new CasterException(o,"Array");
2339    }
2340    
2341    /**
2342     * cast a Object to a Array Object
2343     * @param o Object to cast
2344     * @param defaultValue 
2345     * @return casted Array
2346     */
2347    public static Array toArray(Object o, Array defaultValue) {
2348        if(o instanceof Array) return (Array)o;
2349        else if(o instanceof Object[]) {
2350            return new ArrayImpl((Object[])o);
2351        }
2352        else if(o instanceof List) {
2353            return new ArrayImpl(((List) o).toArray());
2354        }
2355        else if(o instanceof XMLStruct) {
2356            Array arr = new ArrayImpl();
2357            arr.appendEL(o);
2358            return arr;
2359        }
2360        else if(o instanceof ObjectWrap) {
2361            return toArray(((ObjectWrap)o).getEmbededObject(defaultValue),defaultValue);
2362            //if(io!=null)return toArray(io,defaultValue);
2363        }
2364        else if(o instanceof Struct) {
2365            Struct sct=(Struct) o;
2366            Array arr=new ArrayImpl();
2367            
2368            Iterator<Entry<Key, Object>> it = sct.entryIterator();
2369            Entry<Key, Object> e=null;
2370            try {
2371                while(it.hasNext()) {
2372                        e=it.next();
2373                    arr.setEL(toIntValue(e.getKey().getString()),e.getValue());
2374                }
2375            } 
2376            catch (ExpressionException ee) {
2377                return defaultValue;
2378            }
2379            return arr;
2380        }
2381        else if(o instanceof boolean[])return new ArrayImpl(ArrayUtil.toReferenceType((boolean[])o));
2382        else if(o instanceof byte[])return new ArrayImpl(ArrayUtil.toReferenceType((byte[])o));
2383        else if(o instanceof char[])return new ArrayImpl(ArrayUtil.toReferenceType((char[])o));
2384        else if(o instanceof short[])return new ArrayImpl(ArrayUtil.toReferenceType((short[])o));
2385        else if(o instanceof int[])return new ArrayImpl(ArrayUtil.toReferenceType((int[])o));
2386        else if(o instanceof long[])return new ArrayImpl(ArrayUtil.toReferenceType((long[])o));
2387        else if(o instanceof float[])return new ArrayImpl(ArrayUtil.toReferenceType((float[])o));
2388        else if(o instanceof double[])return new ArrayImpl(ArrayUtil.toReferenceType((double[])o));
2389        
2390        return defaultValue;
2391    }
2392    
2393    /**
2394     * cast a Object to a Map Object
2395     * @param o Object to cast
2396     * @return casted Struct
2397     * @throws PageException
2398     */
2399    public static Map toMap(Object o) throws PageException {
2400        return toMap(o,false);
2401    }
2402    
2403    /**
2404     * cast a Object to a Map Object
2405     * @param o Object to cast
2406     * @param defaultValue 
2407     * @return casted Struct
2408     */
2409    public static Map toMap(Object o, Map defaultValue) {
2410        return toMap(o,false,defaultValue);
2411    }
2412    
2413    /**
2414     * cast a Object to a Map Object
2415     * @param o Object to cast
2416     * @param duplicate 
2417     * @param defaultValue 
2418     * @return casted Struct
2419     */
2420    public static Map toMap(Object o, boolean duplicate, Map defaultValue) {
2421        try {
2422            return toMap(o,duplicate);
2423        } catch (PageException e) {
2424            return defaultValue;
2425        }
2426    }
2427    
2428    /**
2429     * cast a Object to a Map Object
2430     * @param o Object to cast
2431     * @param duplicate 
2432     * @return casted Struct
2433     * @throws PageException
2434     */
2435    public static Map toMap(Object o, boolean duplicate) throws PageException {
2436        if(o instanceof Struct) {
2437            if(duplicate) return (Map) Duplicator.duplicate(o,false);
2438            return ((Struct)o);
2439        }
2440        else if(o instanceof Map){
2441            if(duplicate) return (Map)Duplicator.duplicate(o,false);
2442            return (Map)o;
2443        }
2444        else if(o instanceof Node) {
2445            if(duplicate) {
2446                return toMap(XMLCaster.toXMLStruct((Node)o,false),duplicate);
2447            }
2448            return (XMLCaster.toXMLStruct((Node)o,false));
2449        }
2450        else if(o instanceof ObjectWrap) {
2451            return toMap(((ObjectWrap)o).getEmbededObject(),duplicate);
2452        }
2453        throw new CasterException(o,"Map");
2454    }
2455    
2456    /**
2457     * cast a Object to a Struct Object
2458     * @param o Object to cast
2459     * @param defaultValue 
2460     * @return casted Struct
2461     */
2462    
2463    
2464    public static Struct toStruct(Object o, Struct defaultValue, boolean caseSensitive) {
2465        if(o instanceof Struct) return (Struct)o;
2466        else if(o instanceof Map) {
2467            return MapAsStruct.toStruct((Map)o,caseSensitive);
2468        }
2469        else if(o instanceof Node)return XMLCaster.toXMLStruct((Node)o,false);
2470        else if(o instanceof ObjectWrap) {
2471            return toStruct(((ObjectWrap)o).getEmbededObject(defaultValue),defaultValue,caseSensitive);
2472        }
2473        return defaultValue;
2474    }
2475    
2476    /**
2477     * cast a Object to a Struct Object
2478     * @param o Object to cast
2479     * @return casted Struct
2480     */
2481    public static Struct toStruct(Object o) throws PageException {
2482        return toStruct(o,true);
2483    }
2484    
2485    public static Struct toStruct(Object o,Struct defaultValue) {
2486        return toStruct(o, defaultValue, true);
2487    }
2488    
2489    public static Struct toStruct(Object o,boolean caseSensitive) throws PageException {
2490        if(o instanceof Struct) return (Struct)o;
2491        else if(o instanceof Map)return MapAsStruct.toStruct((Map)o,caseSensitive);//_toStruct((Map)o,caseSensitive);
2492        else if(o instanceof Node)return XMLCaster.toXMLStruct((Node)o,false);
2493        else if(o instanceof ObjectWrap) {
2494                if(o instanceof JavaObject ) {
2495                        Struct sct = toStruct(((JavaObject)o).getEmbededObject(null),null,caseSensitive);
2496                if(sct!=null) return sct;
2497                        
2498                        JavaObject jo = (JavaObject)o;
2499                        return new ObjectStruct(jo);
2500                }
2501            return toStruct(((ObjectWrap)o).getEmbededObject(),caseSensitive);
2502        }
2503        if(Decision.isSimpleValue(o) || Decision.isArray(o))
2504                throw new CasterException(o,"Struct");
2505        if(o instanceof Collection) return new CollectionStruct((Collection)o);
2506
2507        if ( o == null )
2508            throw new CasterException( "null can not be casted to a Struct" );
2509
2510        return new ObjectStruct(o);
2511    }
2512    
2513    /*private static Struct _toStruct(Map map) {
2514        Struct sct = new StructImpl();
2515        Iterator it=map.keySet().iterator();
2516        while(it.hasNext()) {
2517            Object key=it.next();
2518            sct.set(StringUtil.toLowerCase(Caster.toString(key)),map.get(key));
2519        }
2520        return sct;
2521    }*/
2522
2523    /**
2524     * cast a Object to a Binary
2525     * @param o Object to cast
2526     * @return casted Binary
2527     * @throws PageException 
2528     */
2529    public static byte[] toBinary(Object o) throws PageException {
2530        if(o instanceof byte[]) return (byte[])o;
2531        else if(o instanceof ObjectWrap) return toBinary(((ObjectWrap)o).getEmbededObject(""));
2532                
2533        else if(o instanceof InputStream) {
2534            ByteArrayOutputStream barr = new ByteArrayOutputStream();
2535            try {
2536                IOUtil.copy((InputStream)o,barr,false,true);
2537            } catch (IOException e) {
2538                throw ExpressionException.newInstance(e);
2539            }
2540            return barr.toByteArray();            
2541        }
2542        else if(o instanceof Image) {
2543                return ((Image)o).getImageBytes(null);
2544        }
2545        else if(o instanceof BufferedImage) {
2546                return new Image(((BufferedImage)o)).getImageBytes("png");
2547        }
2548        else if(o instanceof ByteArrayOutputStream) {
2549                return ((ByteArrayOutputStream)o).toByteArray();
2550        }
2551        else if(o instanceof Blob) {
2552                InputStream is=null;
2553                try {
2554                        is=((Blob)o).getBinaryStream();
2555                        return IOUtil.toBytes(is);
2556                } 
2557                catch (Exception e) {
2558                        throw new ExpressionException(e.getMessage());
2559                        }
2560                finally {
2561                        IOUtil.closeEL(is);
2562                }
2563        }
2564        try {
2565                        return Base64Encoder.decode(toString(o));
2566                } 
2567        catch (CoderException e) {
2568                        throw new CasterException(e.getMessage(),"binary");
2569                }
2570        catch (PageException e) {
2571            throw new CasterException(o,"binary");
2572        }
2573    }
2574    /**
2575     * cast a Object to a Binary
2576     * @param o Object to cast
2577     * @param defaultValue 
2578     * @return casted Binary
2579     */
2580    public static byte[] toBinary(Object o, byte[] defaultValue) {
2581        try {
2582            return toBinary(o);
2583        } 
2584        catch (PageException e) {
2585            return defaultValue;
2586        }
2587    }
2588    
2589    public static Object toCreditCard(Object o) throws PageException {
2590        return ValidateCreditCard.toCreditcard(toString(o));
2591        }
2592    
2593    public static Object toCreditCard(Object o, String defaultValue) {
2594        //print.out("enter");
2595        String str=toString(o,null);
2596        if(str==null)return defaultValue;
2597        //print.out("enter:"+str+":"+ValidateCreditCard.toCreditcard(str,defaultValue));
2598        
2599        return ValidateCreditCard.toCreditcard(str,defaultValue);
2600        }
2601     
2602    /**
2603     * cast a Object to a Base64 value
2604     * @param o Object to cast
2605     * @return to Base64 String
2606     * @throws PageException
2607     */
2608    public static String toBase64(Object o,String charset) throws PageException {
2609        String str=toBase64(o,charset,null);
2610        if(str==null) throw new CasterException(o,"base 64");
2611        return str;
2612    }
2613    
2614    /**
2615     * cast a Object to a Base64 value
2616     * @param o Object to cast
2617     * @param defaultValue 
2618     * @return to Base64 String
2619     */
2620    public static String toBase64(Object o,String charset,String defaultValue) {
2621        byte[] b;
2622        if(o instanceof byte[])b=(byte[]) o;
2623        else if(o instanceof String)return toB64((String)o, charset,defaultValue);
2624        else if(o instanceof ObjectWrap) {
2625            return toBase64(((ObjectWrap)o).getEmbededObject(defaultValue),charset,defaultValue);
2626        }
2627        else if(o == null) return toBase64("",charset,defaultValue);
2628        else {
2629                String str = toString(o,null);
2630                if(str!=null)return toBase64(str,charset,defaultValue);
2631                
2632                b=toBinary(o,null);
2633                if(b==null)return defaultValue;
2634        }
2635        return toB64(b,defaultValue);
2636    }
2637
2638
2639    public static String toB64(String str,String charset) throws UnsupportedEncodingException {
2640        return toB64(str.getBytes(charset));
2641    }
2642    
2643    public static String toB64(byte[] b)  {
2644        return Base64Coder.encode(b);
2645    }
2646
2647    public static String toB64(String str,String charset, String defaultValue) {
2648        if(StringUtil.isEmpty(charset,true))charset="UTF-8";
2649        try {
2650                        return Base64Coder.encodeFromString(str,charset);
2651                } catch (Throwable t) {
2652                        ExceptionUtil.rethrowIfNecessary(t);
2653                        return defaultValue;
2654                }
2655    }
2656    
2657    public static String toB64(byte[] b, String defaultValue) {
2658        try {
2659                        return Base64Coder.encode(b);
2660                } catch (Throwable t) {
2661                        ExceptionUtil.rethrowIfNecessary(t);
2662                        return defaultValue;
2663                }
2664    }
2665
2666    /**
2667     * cast a boolean to a DateTime Object
2668     * @param b boolean to cast
2669     * @param tz
2670     * @return casted DateTime Object
2671     */
2672    public static DateTime toDate(boolean b, TimeZone tz) {
2673        return DateCaster.toDateSimple(b,tz);
2674    }
2675
2676    /**
2677     * cast a char to a DateTime Object
2678     * @param c char to cast
2679     * @param tz
2680     * @return casted DateTime Object
2681     */
2682    public static DateTime toDate(char c, TimeZone tz) {
2683        return DateCaster.toDateSimple(c,tz);
2684    }
2685
2686    /**
2687     * cast a double to a DateTime Object
2688     * @param d double to cast
2689     * @param tz
2690     * @return casted DateTime Object
2691     */
2692    public static DateTime toDate(double d, TimeZone tz) {
2693        return DateCaster.toDateSimple(d,tz);
2694    }
2695
2696    /**
2697     * cast a Object to a DateTime Object
2698     * @param o Object to cast
2699     * @param tz
2700     * @return casted DateTime Object
2701     * @throws PageException
2702     */
2703    public static DateTime toDate(Object o, TimeZone tz) throws PageException {
2704        return DateCaster.toDateAdvanced(o,tz);
2705    }
2706    
2707    /**
2708     * cast a Object to a DateTime Object
2709     * @param str String to cast
2710     * @param tz
2711     * @return casted DateTime Object
2712     * @throws PageException
2713     */
2714    public static DateTime toDate(String str, TimeZone tz) throws PageException {
2715        return DateCaster.toDateAdvanced(str,tz);
2716    }
2717
2718    /**
2719     * cast a Object to a DateTime Object
2720     * @param o Object to cast
2721     * @param alsoNumbers define if also numbers will casted to a datetime value
2722     * @param tz
2723     * @return casted DateTime Object
2724     * @throws PageException 
2725     */
2726    public static DateTime toDate(Object o,boolean alsoNumbers, TimeZone tz) throws PageException {
2727        return DateCaster.toDateAdvanced(o,alsoNumbers?DateCaster.CONVERTING_TYPE_OFFSET:DateCaster.CONVERTING_TYPE_NONE,tz);
2728    }
2729    
2730    /**
2731     * cast a Object to a DateTime Object
2732     * @param o Object to cast
2733     * @param alsoNumbers define if also numbers will casted to a datetime value
2734     * @param tz
2735     * @param defaultValue 
2736     * @return casted DateTime Object
2737     */
2738    public static DateTime toDate(Object o,boolean alsoNumbers, TimeZone tz, DateTime defaultValue) {
2739        return DateCaster.toDateAdvanced(o,alsoNumbers?DateCaster.CONVERTING_TYPE_OFFSET:DateCaster.CONVERTING_TYPE_NONE,tz,defaultValue);
2740    }
2741
2742    /**
2743     * cast a Object to a DateTime Object
2744     * @param str String to cast
2745     * @param alsoNumbers define if also numbers will casted to a datetime value
2746     * @param tz
2747     * @param defaultValue 
2748     * @return casted DateTime Object
2749     */
2750    public static DateTime toDate(String str,boolean alsoNumbers, TimeZone tz, DateTime defaultValue) {
2751        return DateCaster.toDateAdvanced(str,alsoNumbers?DateCaster.CONVERTING_TYPE_OFFSET:DateCaster.CONVERTING_TYPE_NONE,tz,defaultValue);
2752    }
2753
2754    /**
2755     * cast a Object to a DateTime Object
2756     * @param o Object to cast
2757     * @param tz
2758     * @return casted DateTime Object
2759     * @throws PageException
2760     */
2761    public static DateTime toDateTime(Object o, TimeZone tz) throws PageException {
2762        return DateCaster.toDateAdvanced(o,tz);
2763    }
2764    
2765    /**
2766     * cast a Object to a DateTime Object (alias for toDateTime)
2767     * @param o Object to cast
2768     * @param tz
2769     * @return casted DateTime Object
2770     * @throws PageException
2771     */
2772    public static DateTime toDatetime(Object o, TimeZone tz) throws PageException {
2773        return DateCaster.toDateAdvanced(o,tz);
2774    }
2775
2776    /**
2777     * cast a Object to a Query Object
2778     * @param o Object to cast
2779     * @return casted Query Object
2780     * @throws PageException
2781     */
2782    public static Query toQuery(Object o) throws PageException {
2783        if(o instanceof Query) return (Query)o;
2784        if(o instanceof ObjectWrap) {
2785            return toQuery(((ObjectWrap)o).getEmbededObject());
2786        }
2787        if(o instanceof ResultSet) return new QueryImpl((ResultSet)o,"query", ThreadLocalPageContext.getTimeZone());
2788        throw new CasterException(o,"query");
2789    }
2790    
2791    /**
2792     * converts a object to a QueryColumn, if possible
2793     * @param o
2794     * @return
2795     * @throws PageException
2796     */
2797    public static QueryColumn toQueryColumn(Object o) throws PageException {
2798        if(o instanceof QueryColumn) return (QueryColumn)o;
2799        throw new CasterException(o,"querycolumn");
2800    }
2801    
2802    /**
2803     * converts a object to a QueryColumn, if possible, also variable declarations are allowed.
2804     * this method is used within the generated bytecode
2805     * @param o
2806     * @return
2807     * @throws PageException
2808     * @info used in bytecode generation
2809     */
2810    public static QueryColumn toQueryColumn(Object o, PageContext pc) throws PageException { 
2811        if(o instanceof QueryColumn) return (QueryColumn)o;
2812        if(o instanceof String) {
2813                o=VariableInterpreter.getVariableAsCollection(pc, (String)o);
2814                if(o instanceof QueryColumn) return (QueryColumn) o;
2815        }
2816        
2817        throw new CasterException(o,"querycolumn");
2818    }
2819
2820    /**
2821     * cast a Object to a Query Object
2822     * @param o Object to cast
2823     * @param defaultValue 
2824     * @return casted Query Object
2825     */
2826    public static Query toQuery(Object o, Query defaultValue) {
2827        if(o instanceof Query) return (Query)o;
2828        else if(o instanceof ObjectWrap) {
2829            return toQuery(((ObjectWrap)o).getEmbededObject(defaultValue),defaultValue);
2830        }
2831        return defaultValue;
2832    }
2833
2834    /**
2835     * cast a Object to a Query Object
2836     * @param o Object to cast
2837     * @param duplicate duplicate the object or not
2838     * @param defaultValue 
2839     * @return casted Query Object
2840     */
2841    public static Query toQuery(Object o, boolean duplicate, Query defaultValue) {
2842        try {
2843            return toQuery(o,duplicate);
2844        } catch (PageException e) {
2845            return defaultValue;
2846        }
2847    }
2848    
2849    /**
2850     * cast a Object to a Query Object
2851     * @param o Object to cast
2852     * @param duplicate duplicate the object or not
2853     * @return casted Query Object
2854     * @throws PageException
2855     */
2856    public static Query toQuery(Object o, boolean duplicate) throws PageException {
2857        
2858        if(o instanceof Query) {
2859            if(duplicate) {
2860                Query src = (Query)o;
2861                Query trg=new QueryImpl(src.getColumnNames(),src.getRowCount(),"query");
2862
2863                Collection.Key[] keys=src.getColumnNames();
2864                QueryColumn[] columnsSrc=new QueryColumn[keys.length];
2865                for(int i=0;i<columnsSrc.length;i++) {
2866                    columnsSrc[i]=src.getColumn(keys[i]);
2867                }
2868
2869                keys=trg.getColumnNames();
2870                QueryColumn[] columnsTrg=new QueryColumn[keys.length];
2871                for(int i=0;i<columnsTrg.length;i++) {
2872                    columnsTrg[i]=trg.getColumn(keys[i]);
2873                }
2874                
2875                int i;
2876                for(int row=trg.getRecordcount();row>0;row--) {
2877                    for(i=0;i<columnsTrg.length;i++) {
2878                        columnsTrg[i].set(row,columnsSrc[i].get(row,null));
2879                    }
2880                }
2881                return trg;
2882            }
2883            return (Query)o;
2884        }
2885        else if(o instanceof ObjectWrap) {
2886            return toQuery(((ObjectWrap)o).getEmbededObject(),duplicate);
2887        }
2888        throw new CasterException(o,"query");
2889    }
2890    
2891    /**
2892     * cast a Object to a UUID
2893     * @param o Object to cast
2894     * @return casted Query Object
2895     * @throws PageException
2896     */
2897    public static Object toUUId(Object o) throws PageException {
2898        String str=toString(o);
2899        if(!Decision.isUUId(str))
2900            throw new ExpressionException("can't cast ["+str+"] to uuid value");
2901        return str;
2902    }
2903    
2904    /**
2905     * cast a Object to a UUID
2906     * @param o Object to cast
2907     * @param defaultValue 
2908     * @return casted Query Object
2909     */
2910    public static Object toUUId(Object o, Object defaultValue) {
2911        String str=toString(o,null);
2912        if(str==null) return defaultValue;
2913        
2914        if(!Decision.isUUId(str)) return defaultValue;
2915        return str;
2916    }
2917    
2918
2919    /**
2920     * cast a Object to a GUID
2921     * @param o Object to cast
2922     * @return casted Query Object
2923     * @throws PageException
2924     */
2925    public static Object toGUId(Object o) throws PageException {
2926        String str=toString(o);
2927        if(!Decision.isGUId(str))
2928            throw new ExpressionException("can't cast ["+str+"] to guid value");
2929        return str;
2930    }
2931    
2932    /**
2933     * cast a Object to a GUID
2934     * @param o Object to cast
2935     * @param defaultValue 
2936     * @return casted Query Object
2937     */
2938    public static Object toGUId(Object o, Object defaultValue) {
2939        String str=toString(o,null);
2940        if(str==null) return defaultValue;
2941        
2942        if(!Decision.isGUId(str)) return defaultValue;
2943        return str;
2944    }
2945    
2946    /**
2947     * cast a Object to a Variable Name
2948     * @param o Object to cast
2949     * @return casted Variable Name
2950     * @throws PageException
2951     */
2952    public static String toVariableName(Object o) throws PageException {
2953        String str=toString(o);
2954        if(!Decision.isVariableName(str))
2955            throw new ExpressionException("can't cast ["+str+"] to variable name value");
2956        return str;
2957    }
2958    
2959    /**
2960     * cast a Object to a Variable Name
2961     * @param o Object to cast
2962     * @param defaultValue 
2963     * @return casted Variable Name
2964     */
2965    public static Object toVariableName(Object o, Object defaultValue) {
2966        String str=toString(o,null);
2967        
2968        if(str==null || !Decision.isVariableName(str))
2969            return defaultValue;
2970        return str;
2971    }
2972    
2973    /**
2974     * cast a Object to a TimeSpan Object
2975     * @param o Object to cast
2976     * @return casted TimeSpan Object
2977     * @throws PageException
2978     */
2979    public static TimeSpan toTimeSpan(Object o) throws PageException {
2980        return toTimespan(o);
2981    }
2982    
2983    /**
2984     * cast a Object to a TimeSpan Object (alias for toTimeSpan)
2985     * @param o Object to cast
2986     * @param defaultValue 
2987     * @return casted TimeSpan Object
2988     */
2989    public static TimeSpan toTimespan(Object o, TimeSpan defaultValue) {
2990        try {
2991            return toTimespan(o);
2992        } catch (PageException e) {
2993            return defaultValue;
2994        }
2995    }
2996        
2997    /**
2998     * cast a Object to a TimeSpan Object (alias for toTimeSpan)
2999     * @param o Object to cast
3000     * @return casted TimeSpan Object
3001     * @throws PageException
3002     */
3003    public static TimeSpan toTimespan(Object o) throws PageException {
3004        if(o instanceof TimeSpan) return (TimeSpan)o;
3005        else if(o instanceof String) {
3006                String[] arr=o.toString().split(",");
3007                if(arr.length==4) {
3008                    int[] values=new int[4];
3009                    try {
3010                        for(int i=0;i<arr.length;i++) {
3011                            values[i]=toIntValue(arr[i]);
3012                        }
3013                        return new TimeSpanImpl(values[0],values[1],values[2],values[3]);
3014                    }
3015                    catch(ExpressionException e) {}
3016                }
3017        }
3018        else if(o instanceof ObjectWrap) {
3019            return toTimespan(((ObjectWrap)o).getEmbededObject());
3020        }
3021        
3022        double dbl = toDoubleValue(o,true,Double.NaN);
3023        if(!Double.isNaN(dbl))return TimeSpanImpl.fromDays(dbl);
3024        
3025        throw new CasterException(o,"timespan");
3026    }
3027    
3028    /**
3029     * cast a Throwable Object to a PageException Object
3030     * @param t Throwable to cast
3031     * @return casted PageException Object
3032     */
3033    public static PageException toPageException(Throwable t) {
3034        // DO NOT DO THIS ExceptionUtil.rethrowIfNecessary(t);
3035        
3036        if(t instanceof PageException)
3037            return (PageException)t;
3038        else if(t instanceof PageExceptionBox)
3039            return ((PageExceptionBox)t).getPageException();
3040        else if(t instanceof InvocationTargetException){
3041            return toPageException(((InvocationTargetException)t).getTargetException());
3042        }
3043        else if(t instanceof ExceptionInInitializerError){
3044            return toPageException(((ExceptionInInitializerError)t).getCause());
3045        }
3046        else if(t instanceof ExecutionException){
3047            return toPageException(((ExecutionException)t).getCause());
3048        }
3049        else {
3050                if(t instanceof OutOfMemoryError) {
3051                        ThreadLocalPageContext.getConfig().checkPermGenSpace(true);
3052                }
3053                //Throwable cause = t.getCause();
3054                //if(cause!=null && cause!=t) return toPageException(cause);
3055                return new NativeException(t);
3056        }
3057    }
3058    
3059    
3060    
3061    /**
3062     * return the type name of a object (string, boolean, int aso.), type is not same like class name
3063     * @param o Object to get type from 
3064     * @return type of the object
3065    */
3066    public static String toTypeName(Object o) {
3067        if(o == null) return "null";
3068        else if(o instanceof String) return "string";
3069        else if(o instanceof Boolean) return "boolean";
3070        else if(o instanceof Number) return "int";
3071        else if(o instanceof Array) return "array";
3072        else if(o instanceof Component) return "component";
3073        else if(o instanceof Struct) return "struct";
3074        else if(o instanceof Query) return "query";
3075        else if(o instanceof DateTime) return "datetime";
3076        else if(o instanceof byte[]) return "binary";
3077        else if(o instanceof ObjectWrap) {
3078            return toTypeName(((ObjectWrap)o).getEmbededObject(null));
3079        }
3080        
3081        Class clazz=o.getClass();
3082        String className=clazz.getName();
3083                if(className.startsWith("java.lang.")) {
3084                        return className.substring(10);
3085                }
3086                return toClassName(clazz);
3087    }
3088    public static String toTypeName(Class clazz) {
3089        if(Reflector.isInstaneOf(clazz,String.class))   return "string";
3090        if(Reflector.isInstaneOf(clazz,Boolean.class))  return "boolean";
3091        if(Reflector.isInstaneOf(clazz,Number.class))   return "numeric";
3092        if(Reflector.isInstaneOf(clazz,Array.class))    return "array";
3093        if(Reflector.isInstaneOf(clazz,Struct.class))   return "struct";
3094        if(Reflector.isInstaneOf(clazz,Query.class))    return "query";
3095        if(Reflector.isInstaneOf(clazz,DateTime.class)) return "datetime";
3096        if(Reflector.isInstaneOf(clazz,byte[].class))   return "binary";
3097       
3098        String className=clazz.getName();
3099                if(className.startsWith("java.lang.")) {
3100                        return className.substring(10);
3101                }
3102        return toClassName(clazz);
3103    }
3104
3105    public static String toClassName(Object o) {
3106        if(o==null)return "null";
3107        return toClassName(o.getClass());
3108    }
3109    public static String toClassName(Class clazz) {
3110        if(clazz.isArray()){
3111                return toClassName(clazz.getComponentType())+"[]";
3112        }
3113        return clazz.getName();
3114    }
3115    
3116    public static Class cfTypeToClass(String type) throws PageException {
3117        // TODO weitere typen siehe bytecode.cast.Cast
3118        
3119        type=type.trim();
3120        String lcType=StringUtil.toLowerCase(type);
3121        
3122        if(lcType.length()>2) {
3123            char first=lcType.charAt(0);
3124            switch(first) {
3125                case 'a':
3126                    if(lcType.equals("any")) {
3127                        return Object.class;
3128                    }
3129                    else if(lcType.equals("array")) {
3130                        return Array.class;
3131                    }
3132                    break;
3133                case 'b':
3134                    if(lcType.equals("boolean") || lcType.equals("bool")) {
3135                        return Boolean.class;
3136                    }
3137                    else if(lcType.equals("binary")) {
3138                        return byte[].class;
3139                    }
3140                    else if(lcType.equals("base64")) {
3141                        return String.class;
3142                    }
3143                    else if(lcType.equals("byte")) {
3144                        return Byte.class;
3145                    }
3146                    break;
3147                case 'c':
3148                    if(lcType.equals("creditcard")) {
3149                        return String.class;
3150                    }
3151                    else if(lcType.equals("component")) {
3152                        return Component.class;
3153                    }
3154                    break;
3155                case 'd':
3156                    if(lcType.equals("date")) {
3157                        return Date.class;
3158                    }
3159                    else if(lcType.equals("datetime")) {
3160                        return Date.class;
3161                    }
3162                    break;
3163                case 'g':
3164                    if(lcType.equals("guid")) {
3165                        return Object.class;
3166                    }
3167                    break;
3168                case 'n':
3169                    if(lcType.equals("numeric")) {
3170                        return Double.class;
3171                    }
3172                    else if(lcType.equals("number")) {
3173                        return Double.class;
3174                    }
3175                    else if(lcType.equals("node")) {
3176                        return Node.class;
3177                    }
3178                    break;
3179                case 'o':
3180                    if(lcType.equals("object")) {
3181                        return Object.class;
3182                    }
3183                    break;
3184                case 'q':
3185                    if(lcType.equals("query")) {
3186                        return Query.class;
3187                    }
3188                    break;
3189                case 's':
3190                    if(lcType.equals("string")) {
3191                        return String.class;
3192                    }
3193                    else if(lcType.equals("struct")) {
3194                        return Struct.class;
3195                    }
3196                    break;
3197                case 't':
3198                    if(lcType.equals("timespan")) {
3199                        return TimeSpan.class;
3200                    }
3201                    break;
3202                case 'u':
3203                    if(lcType.equals("uuid")) {
3204                        return Object.class;
3205                    }
3206                    break;
3207                case 'v':
3208                    if(lcType.equals("variablename")) {
3209                        return Object.class;
3210                    }
3211                    if(lcType.equals("void")) {
3212                        return Object.class;
3213                    }
3214                    break;
3215                case 'x':
3216                    if(lcType.equals("xml")) {
3217                        return Node.class;
3218                    }
3219                    break;
3220           }
3221        }
3222        // array
3223        if(type.endsWith("[]")) {
3224                Class clazz = cfTypeToClass(type.substring(0,type.length()-2));
3225                clazz=ClassUtil.toArrayClass(clazz);
3226                return clazz;
3227        }
3228        // check for argument
3229        Class<?> clazz;
3230                try {
3231                        clazz = otherTypeToClass(type);
3232                } 
3233                catch (ClassException e) {
3234                        throw Caster.toPageException(e);
3235                }
3236        return clazz;
3237    }
3238    
3239    private static Class<?> otherTypeToClass(String type) throws PageException, ClassException{
3240        PageContext pc = ThreadLocalPageContext.get();
3241        PageException pe=null;
3242        // try to load as cfc
3243        if(pc!=null)    {
3244                try {
3245                        Component c = pc.loadComponent(type);
3246                        return ComponentUtil.getComponentPropertiesClass(pc,c);
3247                } 
3248            catch (PageException e) {
3249                pe=e;
3250            }
3251        }
3252        // try to load as class
3253        try {
3254                        return ClassUtil.loadClass(type);
3255                } 
3256        catch (ClassException ce) {
3257                if(pe!=null) throw pe;
3258                throw ce;
3259        }
3260    }
3261    
3262
3263    
3264    /**
3265     * cast a value to a value defined by type argument
3266     * @param pc
3267     * @param type type of the returning Value
3268     * @param o Object to cast
3269     * @return casted Value
3270     * @throws PageException
3271     */ 
3272    public static Object castTo(PageContext pc,String type, Object o, boolean alsoPattern) throws PageException {
3273        type=StringUtil.toLowerCase(type).trim();
3274        if(type.length()>2) {
3275            char first=type.charAt(0);
3276            switch(first) {
3277                case 'a':
3278                    if(type.equals("any")) {
3279                        return o;
3280                    }
3281                    else if(type.equals("array")) {
3282                        return toArray(o);
3283                    }
3284                    break;
3285                case 'b':
3286                    if(type.equals("boolean") || type.equals("bool")) {
3287                        return toBoolean(o);
3288                    }
3289                    else if(type.equals("binary")) {
3290                        return toBinary(o);
3291                    }
3292                    else if(type.equals("base64")) {
3293                        return toBase64(o,null);
3294                    }
3295                    else if(type.equals("bigdecimal") || type.equals("big_decimal")) {
3296                        return toBigDecimal(o);
3297                    }
3298                    else if(type.equals("biginteger") || type.equals("big_integer")) {
3299                        return toBigInteger(o);
3300                    }
3301                    break;
3302                case 'c':
3303                    if(alsoPattern && type.equals("creditcard")) {
3304                        return toCreditCard(o);
3305                    }
3306                    break;
3307                case 'd':
3308                        if(type.equals("date")) {
3309                        return DateCaster.toDateAdvanced(o,pc.getTimeZone());
3310                    }
3311                    else if(type.equals("datetime")) {
3312                        return DateCaster.toDateAdvanced(o,pc.getTimeZone());
3313                    }
3314                    else if(type.equals("double")) {
3315                        return toDouble(o);
3316                    }
3317                    else if(type.equals("decimal")) {
3318                        return toDecimal(o);
3319                    }
3320                    break;
3321                case 'e':
3322                    if(type.equals("eurodate")) {
3323                        return DateCaster.toEuroDate(o,pc.getTimeZone());
3324                    }
3325                    else if(alsoPattern && type.equals("email")) {
3326                        return toEmail(o);
3327                    }
3328                    break;
3329                case 'f':
3330                    if(type.equals("float")) {
3331                        return toDouble(o);
3332                    }
3333                    else if(type.equals("function")) {
3334                        return toFunction(o);
3335                    }
3336                    break;
3337                case 'g':
3338                    if(type.equals("guid")) {
3339                        return toGUId(o);
3340                    }
3341                    break;
3342                case 'i':
3343                    if(type.equals("integer") || type.equals("int")) {
3344                        return toInteger(o);
3345                    }
3346                    break;
3347                case 'l':
3348                    if(type.equals("long")) {
3349                        return toLong(o);
3350                    }
3351                    break;
3352                case 'n':
3353                    if(type.equals("numeric")) {
3354                        return toDouble(o);
3355                    }
3356                    else if(type.equals("number")) {
3357                        return toDouble(o);
3358                    }
3359                    else if(type.equals("node")) {
3360                        return toXML(o);
3361                    }
3362                    break;
3363                case 'o':
3364                    if(type.equals("object")) {
3365                        return o;
3366                    }
3367                    else if(type.equals("other")) {
3368                        return o;
3369                    }
3370                    break;
3371                case 'p':
3372                    if(alsoPattern && type.equals("phone")) {
3373                        return toPhone(o);
3374                    }
3375                    break;
3376                case 'q':
3377                    if(type.equals("query")) {
3378                        return toQuery(o);
3379                    }
3380                    break;
3381                case 's':
3382                    if(type.equals("string")) {
3383                        return toString(o);
3384                    }
3385                    else if(type.equals("struct")) {
3386                        return toStruct(o);
3387                    }
3388                    else if(type.equals("short")) {
3389                        return toShort(o);
3390                    }
3391                    else if(alsoPattern && (type.equals("ssn") ||type.equals("social_security_number"))) {
3392                        return toSSN(o);
3393                    }
3394                    break;
3395                case 't':
3396                    if(type.equals("timespan")) {
3397                        return toTimespan(o);
3398                    }
3399                    if(type.equals("time")) {
3400                        return DateCaster.toDateAdvanced(o,pc.getTimeZone());
3401                    }
3402                    if(alsoPattern && type.equals("telephone")) {
3403                        return toPhone(o);
3404                    }
3405                    break;
3406                case 'u':
3407                    if(type.equals("uuid")) {
3408                        return toUUId(o);
3409                    }
3410                    if(alsoPattern && type.equals("url")) {
3411                        return toURL(o);
3412                    }
3413                    if(type.equals("usdate")) {
3414                        return DateCaster.toUSDate(o,pc.getTimeZone());
3415                        //return DateCaster.toDate(o,pc.getTimeZone());
3416                    }
3417                    break;
3418                case 'v':
3419                    if(type.equals("variablename")) {
3420                        return toVariableName(o);
3421                    }
3422                    else if(type.equals("void")) {
3423                        return toVoid(o);
3424                    }
3425                    else if(type.equals("variable_name")) {
3426                        return toVariableName(o);
3427                    }
3428                    else if(type.equals("variable-name")) {
3429                        return toVariableName(o);
3430                    }
3431                    break;
3432                case 'x':
3433                    if(type.equals("xml")) {
3434                        return toXML(o);
3435                    }
3436                    case 'z':
3437                        if(alsoPattern && (type.equals("zip") || type.equals("zipcode"))) {
3438                            return toZip(o);
3439                        }
3440                    break;
3441           }
3442        }
3443        
3444        // <type>[]
3445        if(type.endsWith("[]")){
3446                String componentType = type.substring(0,type.length()-2);
3447                Object[] src = toNativeArray(o);
3448                Array trg=new ArrayImpl();
3449                for(int i=0;i<src.length;i++){
3450                        if(src[i]==null){
3451                                continue;
3452                        }
3453                        trg.setE(i+1,castTo(pc, componentType, src[i],alsoPattern));
3454                }               
3455                return trg;     
3456        }
3457
3458        return _castTo(pc, type, o);
3459    }
3460
3461        public static String toZip(Object o) throws PageException {
3462        String str=toString(o);
3463        if(Decision.isZipCode(str)) return str;
3464                throw new ExpressionException("can't cast value ["+str+"] to a zip code");
3465        }
3466    
3467    public static String toZip(Object o, String defaultValue) {
3468        String str=toString(o,null);
3469        if(str==null) return defaultValue;
3470        if(Decision.isZipCode(str)) return str;
3471        return defaultValue;
3472        }
3473
3474        public static String toURL(Object o) throws PageException {
3475        String str=toString(o);
3476        if(Decision.isURL(str)) return str;
3477        
3478        try {
3479                        return HTTPUtil.toURL(str,true).toExternalForm();
3480                } 
3481        catch (MalformedURLException e) {
3482                throw new ExpressionException("can't cast value ["+str+"] to a URL",e.getMessage());
3483        }
3484        }
3485    
3486    public static String toURL(Object o, String defaultValue) {
3487        String str=toString(o,null);
3488        if(str==null) return defaultValue;
3489        if(Decision.isURL(str)) return str;
3490        try {
3491                        return HTTPUtil.toURL(str,true).toExternalForm();
3492                } 
3493        catch (MalformedURLException e) {
3494                return defaultValue;
3495        }
3496        }
3497
3498        public static String toPhone(Object o) throws PageException {
3499        String str=toString(o);
3500        if(Decision.isPhone(str)) return str;
3501                throw new ExpressionException("can't cast value ["+str+"] to a telephone number");
3502        }
3503    
3504    public static String toPhone(Object o, String defaultValue) {
3505        String str=toString(o,null);
3506        if(str==null) return defaultValue;
3507        if(Decision.isPhone(str)) return str;
3508        return defaultValue;
3509        }
3510
3511        public static String toSSN(Object o) throws PageException {
3512        String str=toString(o);
3513        if(Decision.isSSN(str)) return str;
3514                throw new ExpressionException("can't cast value ["+str+"] to a U.S. social security number");
3515        }
3516    
3517    public static String toSSN(Object o, String defaultValue) {
3518        String str=toString(o,null);
3519        if(str==null) return defaultValue;
3520        if(Decision.isSSN(str)) return str;
3521        return defaultValue;
3522        }
3523
3524        public static String toEmail(Object o) throws PageException {
3525                String str=toString(o);
3526        if(Decision.isEmail(str)) return str;
3527                throw new ExpressionException("can't cast value ["+str+"] to a E-Mail Address");
3528        }
3529    
3530    public static String toEmail(Object o, String defaultValue) {
3531        String str=toString(o,null);
3532        if(str==null) return defaultValue;
3533        if(Decision.isEmail(str)) return str;
3534        return defaultValue;
3535        }
3536
3537        /**
3538     * cast a value to a value defined by type argument
3539     * @param pc
3540     * @param type type of the returning Value
3541     * @param strType type as String
3542     * @param o Object to cast
3543     * @return casted Value
3544     * @throws PageException
3545     */
3546    public static Object castTo(PageContext pc, short type, String strType, Object o) throws PageException {
3547//       TODO weitere typen siehe bytecode.cast.Cast
3548        if(type==CFTypes.TYPE_ANY)                 return o;
3549        else if(type==CFTypes.TYPE_ARRAY)          return toArray(o);
3550        else if(type==CFTypes.TYPE_BOOLEAN)        return toBoolean(o);
3551        else if(type==CFTypes.TYPE_BINARY)         return toBinary(o);
3552        else if(type==CFTypes.TYPE_DATETIME)       return DateCaster.toDateAdvanced(o,pc.getTimeZone());
3553        else if(type==CFTypes.TYPE_NUMERIC)        return toDouble(o);
3554        else if(type==CFTypes.TYPE_QUERY)          return toQuery(o);
3555        else if(type==CFTypes.TYPE_QUERY_COLUMN)   return toQueryColumn(o);
3556        else if(type==CFTypes.TYPE_STRING)         return toString(o);
3557        else if(type==CFTypes.TYPE_STRUCT)         return toStruct(o);
3558        else if(type==CFTypes.TYPE_TIMESPAN)       return toTimespan(o);
3559        else if(type==CFTypes.TYPE_UUID)           return toUUId(o);
3560        else if(type==CFTypes.TYPE_GUID)           return toGUId(o);
3561        else if(type==CFTypes.TYPE_VARIABLE_NAME)  return toVariableName(o);
3562        else if(type==CFTypes.TYPE_VOID)           return toVoid(o);
3563        else if(type==CFTypes.TYPE_XML)            return toXML(o);
3564        else if(type==CFTypes.TYPE_FUNCTION)       return toFunction(o);
3565        else if(type==CFTypes.TYPE_IMAGE)          return Image.toImage(pc,o);
3566
3567        return _castTo(pc, strType, o);
3568    }   
3569    
3570    private static Object _castTo(PageContext pc, String strType, Object o) throws PageException {
3571
3572        if(o instanceof Component) {
3573            Component comp=((Component)o);
3574            if(comp.instanceOf(strType)) return o;
3575            throw new ExpressionException("can't cast Component of Type ["+comp.getAbsName()+"] to ["+strType+"]");
3576        }
3577        if(o instanceof Pojo) {
3578                Component cfc = AxisCaster.toComponent(pc,((Pojo)o),strType,null);
3579                if(cfc!=null) return cfc;
3580                throw new ExpressionException("can't cast Pojo of Type ["+o.getClass().getName()+"] to ["+strType+"]");
3581        }
3582        
3583        if(strType.endsWith("[]") && Decision.isArray(o)){
3584                String _strType=strType.substring(0,strType.length()-2);
3585                short _type=CFTypes.toShort(_strType, false, (short)-1);
3586                Array arr = Caster.toArray(o,null);
3587                if(arr!=null){
3588                        
3589                        // convert the values
3590                        Iterator<Entry<Key, Object>> it = arr.entryIterator();
3591                        Array _arr=new ArrayImpl();
3592                        Entry<Key, Object> e;
3593                        Object src,trg;
3594                        boolean hasChanged=false;
3595                        while(it.hasNext()){
3596                                e = it.next();
3597                                src=e.getValue();
3598                                trg=castTo(pc, _type, _strType, src);
3599                                _arr.setEL(e.getKey(), trg);
3600                                if(src!=trg) hasChanged=true;
3601                        }
3602                        if(!hasChanged) return arr;
3603                        return _arr;
3604                }
3605                
3606            }
3607        throw new CasterException(o,strType);
3608    }
3609    
3610    /**
3611     * cast a value to a value defined by type argument
3612     * @param pc
3613     * @param type type of the returning Value
3614     * @param o Object to cast
3615     * @return casted Value
3616     * @throws PageException
3617     */
3618    public static Object castTo(PageContext pc, short type, Object o) throws PageException {
3619        if(type==CFTypes.TYPE_ANY)                 return o;
3620        else if(type==CFTypes.TYPE_ARRAY)          return toArray(o);
3621        else if(type==CFTypes.TYPE_BOOLEAN)        return toBoolean(o);
3622        else if(type==CFTypes.TYPE_BINARY)         return toBinary(o);
3623        else if(type==CFTypes.TYPE_DATETIME)       return DateCaster.toDateAdvanced(o,pc.getTimeZone());
3624        else if(type==CFTypes.TYPE_NUMERIC)        return toDouble(o);
3625        else if(type==CFTypes.TYPE_QUERY)          return toQuery(o);
3626        else if(type==CFTypes.TYPE_QUERY_COLUMN)   return toQueryColumn(o);
3627        else if(type==CFTypes.TYPE_STRING)         return toString(o);
3628        else if(type==CFTypes.TYPE_STRUCT)         return toStruct(o);
3629        else if(type==CFTypes.TYPE_TIMESPAN)       return toTimespan(o);
3630        else if(type==CFTypes.TYPE_UUID)           return toGUId(o);
3631        else if(type==CFTypes.TYPE_UUID)           return toUUId(o);
3632        else if(type==CFTypes.TYPE_VARIABLE_NAME)  return toVariableName(o);
3633        else if(type==CFTypes.TYPE_VOID)           return toVoid(o);
3634        else if(type==CFTypes.TYPE_FUNCTION)       return toFunction(o);
3635        else if(type==CFTypes.TYPE_XML)            return toXML(o);
3636        else if(type==CFTypes.TYPE_IMAGE)            return Image.toImage(pc,o);
3637
3638        if(type==CFTypes.TYPE_UNDEFINED)
3639            throw new ExpressionException("type isn't defined (TYPE_UNDEFINED)");
3640        throw new ExpressionException("invalid type ["+type+"]");
3641    }
3642    
3643
3644        /**
3645     * cast a value to void (Empty String)
3646     * @param o
3647     * @return void value
3648     * @throws ExpressionException
3649     */
3650    public static Object toVoid(Object o) throws ExpressionException {
3651        if(o==null)return null;
3652        else if(o instanceof String && o.toString().length()==0)return null;
3653        else if(o instanceof Number && ((Number)o).intValue()==0 ) return null;
3654        else if(o instanceof Boolean && ((Boolean)o).booleanValue()==false ) return null;
3655        else if(o instanceof ObjectWrap) return toVoid(((ObjectWrap)o).getEmbededObject(null));
3656                throw new CasterException(o,"void");
3657    }
3658    
3659    /**
3660     * cast a value to void (Empty String)
3661     * @param o
3662     * @param defaultValue 
3663     * @return void value
3664     */
3665    public static Object toVoid(Object o, Object defaultValue) {
3666        if(o==null)return null;
3667        else if(o instanceof String && o.toString().length()==0)return null;
3668        else if(o instanceof Number && ((Number)o).intValue()==0 ) return null;
3669        else if(o instanceof Boolean && ((Boolean)o).booleanValue()==false ) return null;
3670        else if(o instanceof ObjectWrap) return toVoid(((ObjectWrap)o).getEmbededObject((defaultValue)),defaultValue);
3671                return defaultValue;
3672    }
3673
3674    /**
3675     * cast a Object to a reference type (Object), in that case this method to nothing, because a Object is already a reference type
3676     * @param o Object to cast
3677     * @return casted Object
3678     */
3679    public static Object toRef(Object o) {
3680        return o;
3681    }
3682    
3683    /**
3684     * cast a String to a reference type (Object), in that case this method to nothing, because a String is already a reference type
3685     * @param o Object to cast
3686     * @return casted Object
3687     */
3688    public static String toRef(String o) {
3689        return o;
3690    }
3691    
3692    /**
3693     * cast a Collection to a reference type (Object), in that case this method to nothing, because a Collection is already a reference type
3694     * @param o Collection to cast
3695     * @return casted Object
3696     */
3697    public static Collection toRef(Collection o) {
3698        return o;
3699    }
3700    
3701    /**
3702     * cast a char value to his (CFML) reference type String
3703     * @param c char to cast
3704     * @return casted String
3705     */
3706    public static String toRef(char c) {
3707        return ""+c;
3708    }
3709    
3710    /**
3711     * cast a boolean value to his (CFML) reference type Boolean
3712     * @param b boolean to cast
3713     * @return casted Boolean
3714     */
3715    public static Boolean toRef(boolean b) {
3716        return b?Boolean.TRUE:Boolean.FALSE;
3717    }
3718    
3719    /**
3720     * cast a byte value to his (CFML) reference type Integer
3721     * @param b byte to cast
3722     * @return casted Integer
3723     */
3724    public static Byte toRef(byte b) {
3725        return new Byte(b);
3726    }
3727    
3728    /**
3729     * cast a int value to his (CFML) reference type Integer
3730     * @param i int to cast
3731     * @return casted Integer
3732     */
3733    public static Integer toRef(int i) {
3734        return Integer.valueOf(i);
3735    }
3736    
3737    /**
3738     * cast a float value to his (CFML) reference type Float
3739     * @param f float to cast 
3740     * @return casted Float
3741     */
3742    public static Float toRef(float f) {
3743        return new Float(f);
3744    }
3745    
3746    /**
3747     * cast a long value to his (CFML) reference type Long
3748     * @param l long to cast
3749     * @return casted Long
3750     */
3751    public static Long toRef(long l) {
3752        return Long.valueOf(l);
3753    }
3754    
3755    /**
3756     * cast a double value to his (CFML) reference type Double
3757     * @param d doble to cast
3758     * @return casted Double
3759     */
3760    public static Double toRef(double d) {
3761        return new Double(d);
3762    }
3763    
3764    /**
3765     * cast a double value to his (CFML) reference type Double
3766     * @param s short to cast
3767     * @return casted Short
3768     */
3769    public static Short toRef(short s) {
3770        return Short.valueOf(s);
3771    }
3772
3773    /**
3774     * cast a Object to a Iterator or get Iterator from Object
3775     * @param o Object to cast
3776     * @return casted Collection
3777     * @throws PageException
3778     */
3779    public static Iterator toIterator(Object o) throws PageException {
3780        if(o instanceof Iterator) return (Iterator)o;
3781        else if(o instanceof Iteratorable) return ((Iteratorable)o).keysAsStringIterator();
3782        else if(o instanceof Enumeration) return new IteratorWrapper((Enumeration)o);
3783        else if(o instanceof JavaObject) {
3784                String[] names = ClassUtil.getFieldNames(((JavaObject)o).getClazz());
3785                return new ArrayIterator(names);
3786        }
3787        else if(o instanceof ObjectWrap) return toIterator(((ObjectWrap)o).getEmbededObject());
3788                return toIterator(toCollection(o));
3789    }
3790    
3791    /**
3792     * cast a Object to a Collection
3793     * @param o Object to cast
3794     * @return casted Collection
3795     * @throws PageException
3796     */
3797    public static Collection toCollection(Object o) throws PageException {
3798        if(o instanceof Collection) return (Collection)o;
3799        else if(o instanceof Node)return XMLCaster.toXMLStruct((Node)o,false);
3800        else if(o instanceof Map) {
3801            return MapAsStruct.toStruct((Map)o,true);//StructImpl((Map)o);
3802        }
3803        else if(o instanceof ObjectWrap) {
3804            return toCollection(((ObjectWrap)o).getEmbededObject());
3805        }
3806        else if(Decision.isArray(o)) {
3807            return toArray(o);
3808        }
3809        throw new CasterException(o,"collection");
3810    }
3811    
3812    public static java.util.Collection toJavaCollection(Object o) throws PageException {
3813        if(o instanceof java.util.Collection) return (java.util.Collection) o;
3814        return toList(o);
3815    }
3816    
3817    
3818    /**
3819     * cast a Object to a Component
3820     * @param o Object to cast
3821     * @return casted Component
3822     * @throws PageException
3823     */
3824    public static Component toComponent(Object o ) throws PageException {
3825        if(o instanceof Component) return (Component)o;
3826        else if(o instanceof ObjectWrap) {
3827            return toComponent(((ObjectWrap)o).getEmbededObject());
3828        }
3829        throw new CasterException(o,"Component");
3830    }
3831    
3832    public static Component toComponent(Object o , Component defaultValue) {
3833        if(o instanceof Component) return (Component)o;
3834        else if(o instanceof ObjectWrap) {
3835            return toComponent(((ObjectWrap)o).getEmbededObject(defaultValue),defaultValue);
3836        }
3837        return defaultValue;
3838    }
3839    
3840    
3841    
3842    /**
3843     * cast a Object to a Collection, if not returns null
3844     * @param o Object to cast
3845     * @param defaultValue 
3846     * @return casted Collection
3847     */
3848    public static Collection toCollection(Object o, Collection defaultValue) {
3849        if(o instanceof Collection) return (Collection)o;
3850        else if(o instanceof Node)return XMLCaster.toXMLStruct((Node)o,false);
3851        else if(o instanceof Map) {
3852            return MapAsStruct.toStruct((Map)o,true);
3853        }
3854        else if(o instanceof ObjectWrap) {
3855            return toCollection(((ObjectWrap)o).getEmbededObject(defaultValue),defaultValue);
3856        }
3857        else if(Decision.isArray(o)) {
3858            try {
3859                return toArray(o);
3860            } catch (PageException e) {
3861                return defaultValue;
3862            }
3863        }
3864        return defaultValue;
3865    }
3866
3867    /**
3868     * convert a object to a File
3869     * @param obj
3870     * @return File
3871     * @throws PageException 
3872      */ 
3873    public static File toFile(Object obj) throws PageException {
3874        if(obj instanceof File) return (File)obj;
3875        return FileUtil.toFile(Caster.toString(obj));
3876    }
3877    
3878    /**
3879     * convert a object to a File
3880     * @param obj
3881     * @param defaultValue 
3882     * @return File
3883     */ 
3884    public static File toFile(Object obj, File defaultValue) {
3885        if(obj instanceof File) return (File)obj;
3886        String str=Caster.toString(obj,null);
3887        if(str==null) return defaultValue;
3888        return FileUtil.toFile(str);
3889    }
3890    
3891    /**
3892     * convert a object array to a HashMap filled with Function value Objects
3893     * @param args Object array to convert
3894     * @return hashmap containing Function values
3895     * @throws ExpressionException
3896     */
3897    public static Struct toFunctionValues(Object[] args) throws ExpressionException {
3898        return toFunctionValues(args, 0, args.length);
3899    }
3900    
3901    public static Struct toFunctionValues(Object[] args, int offset, int len) throws ExpressionException {
3902        // TODO nicht sehr optimal 
3903        Struct sct=new StructImpl(StructImpl.TYPE_LINKED);
3904        for(int i=offset;i<offset+len;i++) {
3905            if(args[i] instanceof FunctionValueImpl){
3906                FunctionValueImpl value = (FunctionValueImpl) args[i];
3907                sct.setEL(value.getNameAsKey(),value.getValue());
3908            }
3909            else throw new ExpressionException("Missing argument name, when using named parameters to a function, every parameter must have a name ["+i+":"+args[i].getClass().getName()+"].");
3910        }
3911        return sct;
3912    }
3913    
3914    
3915    
3916    
3917    public static Object[] toFunctionValues(Struct args) {
3918        // TODO nicht sehr optimal 
3919        Iterator<Entry<Key, Object>> it = args.entryIterator();
3920        Entry<Key, Object> e;
3921        List<FunctionValue> fvalues=new ArrayList<FunctionValue>();
3922        while(it.hasNext()) {
3923                e=it.next();
3924                fvalues.add(new FunctionValueImpl(e.getKey().getString(),e.getValue()));
3925        }
3926        return fvalues.toArray(new FunctionValue[fvalues.size()]);
3927    }
3928
3929    /**
3930     * casts a string to a Locale
3931     * @param strLocale
3932     * @return Locale from String
3933     * @throws ExpressionException
3934     */
3935    public static Locale toLocale(String strLocale) throws ExpressionException {
3936        return LocaleFactory.getLocale(strLocale);
3937    }
3938    
3939    /**
3940     * casts a string to a Locale
3941     * @param strLocale
3942     * @param defaultValue 
3943     * @return Locale from String
3944     */
3945    public static Locale toLocale(String strLocale, Locale defaultValue) {
3946        return LocaleFactory.getLocale(strLocale,defaultValue);
3947    }
3948
3949    /**
3950     * casts a string to a TimeZone
3951     * @param strTimeZone
3952     * @return TimeZone from String
3953     * @throws ExpressionException
3954     */
3955    public static TimeZone toTimeZone(String strTimeZone) throws ExpressionException {
3956        return TimeZoneUtil.toTimeZone(strTimeZone);
3957    }
3958    
3959    /**
3960     * casts a string to a TimeZone
3961     * @param strTimeZone
3962     * @param defaultValue 
3963     * @return TimeZone from String
3964     */
3965    public static TimeZone toTimeZone(String strTimeZone, TimeZone defaultValue) {
3966        return TimeZoneUtil.toTimeZone(strTimeZone,defaultValue);
3967    }
3968    
3969    
3970    public static TimeZone toTimeZone(Object oTimeZone, TimeZone defaultValue) {
3971        if(oTimeZone instanceof TimeZone) return (TimeZone) oTimeZone;
3972        return TimeZoneUtil.toTimeZone(Caster.toString(oTimeZone,null),defaultValue);
3973    }
3974    
3975    
3976    
3977    
3978    /**
3979     * casts a Object to a Node List
3980     * @param o Object to Cast
3981     * @return NodeList from Object
3982     * @throws PageException
3983     */
3984    public static NodeList toNodeList(Object o) throws PageException {
3985        //print.ln("nodeList:"+o);
3986        if(o instanceof NodeList) {
3987            return (NodeList)o;
3988        }
3989        else if(o instanceof ObjectWrap) {
3990            return toNodeList(((ObjectWrap)o).getEmbededObject());
3991        }
3992        throw new CasterException(o,"NodeList");
3993    }
3994    
3995    /**
3996     * casts a Object to a Node List
3997     * @param o Object to Cast
3998     * @param defaultValue 
3999     * @return NodeList from Object
4000     */
4001    public static NodeList toNodeList(Object o, NodeList defaultValue) {
4002        //print.ln("nodeList:"+o);
4003        if(o instanceof NodeList) {
4004            return (NodeList)o;
4005        }
4006        else if(o instanceof ObjectWrap) {
4007            return toNodeList(((ObjectWrap)o).getEmbededObject(defaultValue),defaultValue);
4008        }
4009        return defaultValue;
4010    }   
4011    
4012    /**
4013     * casts a Object to a XML Node
4014     * @param o Object to Cast
4015     * @return Node from Object
4016     * @throws PageException
4017     */
4018    public static Node toNode(Object o) throws PageException {
4019        return toXML(o);
4020        /*if(o instanceof Node)return (Node)o;
4021        else if(o instanceof String)    {
4022            try {
4023                return XMLCaster.toXMLStruct(XMLUtil.parse(o.toString(),false),false);
4024                
4025            } catch (Exception e) {
4026                throw Caster.toPageException(e);
4027            }
4028        }
4029        else if(o instanceof ObjectWrap) {
4030            return toNode(((ObjectWrap)o).getEmbededObject());
4031        }
4032        throw new CasterException(o,"Node");*/
4033    }   
4034    
4035    /**
4036     * casts a Object to a XML Node
4037     * @param o Object to Cast
4038     * @param defaultValue 
4039     * @return Node from Object
4040     */
4041    public static Node toNode(Object o, Node defaultValue) {
4042        return toXML(o,defaultValue);
4043        /*if(o instanceof Node)return (Node)o;
4044        else if(o instanceof String)    {
4045            try {
4046                return XMLCaster.toXMLStruct(XMLUtil.parse(o.toString(),false),false);
4047                
4048            } catch (Exception e) {
4049                return defaultValue;
4050            }
4051        }
4052        else if(o instanceof ObjectWrap) {
4053            return toNode(((ObjectWrap)o).getEmbededObject(defaultValue),defaultValue);
4054        }
4055        return defaultValue;*/
4056    }
4057
4058    /**
4059     * casts a boolean to a Integer
4060     * @param b
4061     * @return Integer from boolean
4062     */
4063    public static Integer toInteger(boolean b) {
4064        return b?Constants.INTEGER_1:Constants.INTEGER_0;
4065    }
4066
4067    /**
4068     * casts a char to a Integer
4069     * @param c
4070     * @return Integer from char
4071     */
4072    public static Integer toInteger(char c) {
4073        return Integer.valueOf(c);
4074    }
4075
4076    /**
4077     * casts a double to a Integer
4078     * @param d
4079     * @return Integer from double
4080     */
4081    public static Integer toInteger(double d) { 
4082        return Integer.valueOf((int)d);
4083    }
4084    
4085    /**
4086     * casts a Object to a Integer
4087     * @param o Object to cast to Integer
4088     * @return Integer from Object
4089     * @throws PageException
4090     */
4091    public static Integer toInteger(Object o) throws PageException {
4092        return Integer.valueOf(toIntValue(o));
4093    }
4094    
4095    /**
4096     * casts a Object to a Integer
4097     * @param str Object to cast to Integer
4098     * @return Integer from Object
4099     * @throws PageException
4100     */
4101    public static Integer toInteger(String str) throws PageException {
4102        return Integer.valueOf(toIntValue(str));
4103    }
4104    
4105    // used in bytecode genrator 
4106    public static Integer toInteger(int i) {
4107        return Integer.valueOf(i);
4108    }
4109    
4110    /**
4111     * casts a Object to a Integer
4112     * @param o Object to cast to Integer
4113     * @param defaultValue 
4114     * @return Integer from Object
4115     */
4116    public static Integer toInteger(Object o, Integer defaultValue) {
4117        if(defaultValue!=null) return Integer.valueOf(toIntValue(o,defaultValue.intValue()));
4118        int res=toIntValue(o,Integer.MIN_VALUE);
4119        if(res==Integer.MIN_VALUE) return defaultValue;
4120        return Integer.valueOf(res);
4121    }
4122    
4123    /**
4124     * casts a Object to null
4125     * @param value
4126     * @return to null from Object
4127     * @throws PageException
4128     */
4129    public static Object toNull(Object value) throws PageException {
4130       if(value==null)return null;
4131       if(value instanceof String && Caster.toString(value).trim().length()==0) return null;
4132       if(value instanceof Number && ((Number)value).intValue()==0) return null;
4133       throw new CasterException(value,"null");
4134    }
4135    
4136    /**
4137     * casts a Object to null
4138     * @param value
4139     * @param defaultValue 
4140     * @return to null from Object
4141     */
4142    public static Object toNull(Object value, Object defaultValue){
4143       if(value==null)return null;
4144       if(value instanceof String && Caster.toString(value,"").trim().length()==0) return null;
4145       if(value instanceof Number && ((Number)value).intValue()==0) return null;
4146       return defaultValue;
4147    }
4148
4149    /**
4150     * cast Object to a XML Node
4151     * @param value
4152     * @param defaultValue 
4153     * @return XML Node
4154     */
4155    public static Node toXML(Object value, Node defaultValue) {
4156        try {
4157            return toXML(value);
4158        } catch (PageException e) {
4159            return defaultValue;
4160        }
4161    }
4162
4163    /**
4164     * cast Object to a XML Node
4165     * @param value
4166     * @return XML Node
4167     * @throws PageException 
4168     */
4169    public static Node toXML(Object value) throws PageException {
4170        if(value instanceof Node) return XMLCaster.toXMLStruct((Node)value,false);
4171        if(value instanceof ObjectWrap) {
4172            return toXML(((ObjectWrap)value).getEmbededObject());
4173        }
4174        try {
4175            return XMLCaster.toXMLStruct(XMLUtil.parse(XMLUtil.toInputSource(null, value),null,false),false);
4176        }
4177        catch(Exception outer) {
4178            throw Caster.toPageException(outer);
4179        }
4180        
4181    }
4182
4183    public static String toStringForce(Object value, String defaultValue) {
4184        String rtn=toString(value,null);
4185        if(rtn!=null)return rtn;
4186        
4187        try {
4188            if(value instanceof Struct) {
4189                return new ScriptConverter().serialize(value);
4190            }
4191            else if(value instanceof Array) {
4192                return new ScriptConverter().serialize(value);
4193            }
4194        } 
4195        catch (ConverterException e) {}
4196        return defaultValue;
4197    }
4198        
4199        public static Resource toResource(PageContext pc,Object src, boolean existing) throws ExpressionException {
4200                return toResource(pc,src,existing,pc.getConfig().allowRealPath());
4201        }
4202        
4203        public static Resource toResource(PageContext pc,Object src, boolean existing,boolean allowRelpath) throws ExpressionException {
4204                if(src instanceof Resource) return (Resource) src;
4205                if(src instanceof File) src=src.toString();
4206                if(src instanceof String) {
4207                        if(existing)
4208                                return ResourceUtil.toResourceExisting(pc, (String)src,allowRelpath);
4209                        return ResourceUtil.toResourceNotExisting(pc, (String)src,allowRelpath,false);
4210                }
4211                if(src instanceof FileStreamWrapper) return ((FileStreamWrapper)src).getResource();
4212        throw new CasterException(src,"Resource");
4213        }
4214        
4215
4216        public static Resource toResource(Config config,Object src, boolean existing) throws ExpressionException {
4217                if(src instanceof Resource) return (Resource) src;
4218                if(src instanceof File) src=src.toString();
4219                if(src instanceof String) {
4220                        if(existing)
4221                                return ResourceUtil.toResourceExisting(config, (String)src);
4222                        return ResourceUtil.toResourceNotExisting(config, (String)src);
4223                }
4224                if(src instanceof FileStreamWrapper) return ((FileStreamWrapper)src).getResource();
4225        throw new CasterException(src,"Resource");
4226        }
4227        
4228
4229        public static Hashtable toHashtable(Object obj) throws PageException {
4230                if(obj instanceof Hashtable) return (Hashtable) obj;
4231                return (Hashtable) Duplicator.duplicateMap(toMap(obj,false), new Hashtable(), false);
4232        }
4233
4234        public static Vector toVetor(Object obj) throws PageException {
4235                if(obj instanceof Vector) return (Vector) obj;
4236                return (Vector) Duplicator.duplicateList(toList(obj,false),new Vector(), false);
4237        } 
4238
4239        public static Calendar toCalendar(Date date, TimeZone tz, Locale l) {
4240                tz=ThreadLocalPageContext.getTimeZone(tz);
4241                Calendar c = tz==null?JREDateTimeUtil.newInstance(tz,l):JREDateTimeUtil.newInstance(tz,l);
4242                c.setTime(date);
4243                return c;
4244        }
4245        
4246        public static Calendar toCalendar(long time, TimeZone tz, Locale l) {
4247                tz=ThreadLocalPageContext.getTimeZone(tz);
4248                Calendar c = tz==null?JREDateTimeUtil.newInstance(tz,l):JREDateTimeUtil.newInstance(tz,l);
4249                c.setTimeInMillis(time);
4250                return c;
4251        }
4252
4253        public static Serializable toSerializable(Object object) throws CasterException {
4254                if(object instanceof Serializable)return (Serializable)object;
4255                throw new CasterException(object,"Serializable");
4256        }
4257
4258        public static Serializable toSerializable(Object object, Serializable defaultValue) {
4259                if(object instanceof Serializable)return (Serializable)object;
4260                return defaultValue;
4261        }
4262
4263        public static byte[] toBytes(Object obj,Charset charset) throws PageException {
4264                try {
4265                        if(obj instanceof byte[]) return (byte[]) obj;
4266                        if(obj instanceof InputStream)return IOUtil.toBytes((InputStream)obj);
4267                        if(obj instanceof Resource)return IOUtil.toBytes((Resource)obj);
4268                        if(obj instanceof File)return IOUtil.toBytes((File)obj);
4269                        if(obj instanceof String) return ((String)obj).getBytes(charset==null?SystemUtil.getCharset():charset);
4270                        if(obj instanceof Blob) {
4271                                InputStream is=null;
4272                                try {
4273                                        is=((Blob)obj).getBinaryStream();
4274                                        return IOUtil.toBytes(is);
4275                                }
4276                                finally {
4277                                        IOUtil.closeEL(is);
4278                                }
4279                        }
4280                }
4281                catch(IOException ioe) {
4282                        throw toPageException(ioe);
4283                }
4284                catch(SQLException ioe) {
4285                        throw toPageException(ioe);
4286                }
4287                throw new CasterException(obj,byte[].class);
4288        }
4289
4290        public static InputStream toInputStream(Object obj,Charset charset) throws PageException {
4291                try {
4292                        if(obj instanceof InputStream)return (InputStream)obj;
4293                        if(obj instanceof byte[]) return new ByteArrayInputStream((byte[]) obj);
4294                        if(obj instanceof Resource)return ((Resource)obj).getInputStream();
4295                        if(obj instanceof File)return new FileInputStream((File)obj);
4296                        if(obj instanceof String) return new ByteArrayInputStream(((String)obj).getBytes(charset==null?SystemUtil.getCharset():charset));
4297                        if(obj instanceof Blob) return ((Blob)obj).getBinaryStream();
4298                }
4299                catch(IOException ioe) {
4300                        throw toPageException(ioe);
4301                }
4302                catch(SQLException ioe) {
4303                        throw toPageException(ioe);
4304                }
4305                throw new CasterException(obj,InputStream.class);
4306        }
4307
4308        public static OutputStream toOutputStream(Object obj) throws PageException {
4309                if(obj instanceof OutputStream)return (OutputStream)obj;
4310                throw new CasterException(obj,OutputStream.class);
4311        }
4312
4313        public static Object castTo(PageContext pc, Class trgClass, Object obj) throws PageException {
4314                if(trgClass==null)return Caster.toNull(obj); 
4315                else if(obj.getClass()==trgClass)       return obj;
4316                
4317                else if(trgClass==boolean.class)return Caster.toBoolean(obj); 
4318                else if(trgClass==byte.class)return Caster.toByte(obj); 
4319                else if(trgClass==short.class)return Caster.toShort(obj); 
4320                else if(trgClass==int.class)return Integer.valueOf(Caster.toDouble(obj).intValue()); 
4321                else if(trgClass==long.class)return Caster.toLong(obj);
4322                else if(trgClass==float.class)return new Float(Caster.toDouble(obj).floatValue()); 
4323                else if(trgClass==double.class)return Caster.toDouble(obj); 
4324                else if(trgClass==char.class)return Caster.toCharacter(obj); 
4325                
4326                else if(trgClass==Boolean.class)return Caster.toBoolean(obj); 
4327                else if(trgClass==Byte.class)return Caster.toByte(obj); 
4328                else if(trgClass==Short.class)return Caster.toShort(obj); 
4329                else if(trgClass==Integer.class)return Integer.valueOf(Caster.toDouble(obj).intValue()); 
4330                else if(trgClass==Long.class)return Caster.toLong(obj); 
4331                else if(trgClass==Float.class)return new Float(Caster.toDouble(obj).floatValue()); 
4332                else if(trgClass==Double.class)return Caster.toDouble(obj); 
4333                else if(trgClass==Character.class)return Caster.toCharacter(obj); 
4334                
4335                else if(trgClass==Object.class)return obj; 
4336                else if(trgClass==String.class)return Caster.toString(obj); 
4337                
4338                if(Reflector.isInstaneOf(obj.getClass(), trgClass)) return obj;
4339                
4340                return Caster.castTo(pc, trgClass.getName(), obj,false);
4341        }
4342
4343        public static Objects toObjects(PageContext pc,Object obj) throws PageException {
4344                if(obj instanceof Objects) return (Objects) obj;
4345                if(obj instanceof ObjectWrap) return toObjects(pc,((ObjectWrap)obj).getEmbededObject());
4346                return new JavaObject(pc.getVariableUtil(), obj);
4347        }
4348
4349        public static BigDecimal toBigDecimal(Object o) throws PageException {
4350                if(o instanceof BigDecimal) return (BigDecimal) o;
4351                if(o instanceof Number) {
4352                        return new BigDecimal(((Number)o).toString());
4353                }
4354        else if(o instanceof Boolean) return new BigDecimal(((Boolean)o).booleanValue()?1:0);
4355        else if(o instanceof String) return new BigDecimal(o.toString());
4356        else if(o instanceof Castable) return new BigDecimal(((Castable)o).castToDoubleValue());
4357        else if(o == null) return BigDecimal.ZERO;
4358        else if(o instanceof ObjectWrap) return toBigDecimal(((ObjectWrap)o).getEmbededObject());
4359        throw new CasterException(o,"number");
4360        }
4361        
4362        public static BigInteger toBigInteger(Object o) throws PageException {
4363                if(o instanceof BigInteger) return (BigInteger) o;
4364                if(o instanceof Number) {
4365                        return new BigInteger(((Number)o).toString());
4366                }
4367        else if(o instanceof Boolean) return new BigInteger(((Boolean)o).booleanValue()?"1":"0");
4368        else if(o instanceof String) return new BigInteger(o.toString());
4369        else if(o instanceof Castable) return new BigInteger(""+Caster.toIntValue(((Castable)o).castToDoubleValue()));
4370        else if(o == null) return BigInteger.ZERO;
4371        else if(o instanceof ObjectWrap) return toBigInteger(((ObjectWrap)o).getEmbededObject());
4372        throw new CasterException(o,"number");
4373        }
4374
4375        public static Object unwrap(Object value) throws PageException {
4376                if(value==null) return null;
4377                if(value instanceof ObjectWrap) {
4378                        return ((ObjectWrap)value).getEmbededObject();
4379                }
4380                return value;
4381        }
4382        
4383        public static Object unwrap(Object value,Object defaultValue) {
4384                if(value==null) return null;
4385                if(value instanceof ObjectWrap) {
4386                        return ((ObjectWrap)value).getEmbededObject(defaultValue);
4387                }
4388                return value;
4389        }
4390
4391        public static CharSequence toCharSequence(Object obj) throws PageException {
4392                if(obj instanceof CharSequence) return (CharSequence) obj;
4393                return Caster.toString(obj);
4394        }
4395
4396        public static CharSequence toCharSequence(Object obj, CharSequence defaultValue) {
4397                if(obj instanceof CharSequence) return (CharSequence) obj;
4398                String str = Caster.toString(obj,null);
4399                if(str==null) return defaultValue;
4400                return str;
4401        }
4402
4403
4404        
4405        
4406}