001    package railo.runtime.com;
002    
003    import java.lang.reflect.Method;
004    
005    import railo.runtime.exp.ExpressionException;
006    import railo.runtime.op.Caster;
007    import railo.runtime.type.ArrayImpl;
008    import railo.runtime.type.dt.DateTimeImpl;
009    
010    import com.jacob.com.Variant;
011    
012    /**
013     * 
014     */
015    public final class COMUtil {
016            
017    
018        /**
019         * translate a Variant Object to Object, when it is a Dispatch translate it to COMWrapper
020         * @param parent 
021         * @param variant
022         * @param key
023         * @return Object from Variant
024         */
025        public static Object toObject(COMObject parent, Variant variant, String key, Object defaultValue) {
026            try {
027                    return toObject(parent, variant,key);
028            }
029            catch(ExpressionException ee) {
030                return defaultValue;
031            }
032        }
033        
034        /**
035         * translate a Variant Object to Object, when it is a Dispatch translate it to COMWrapper
036         * @param parent
037         * @param variant
038         * @param key
039         * @return Object from Variant
040         * @throws ExpressionException
041         */
042        public static Object toObject(COMObject parent,Variant variant, String key) throws ExpressionException {
043            short type=variant.getvt();
044            //print.ln(key+" -> variant.getvt("+toStringType(type)+")");
045                    
046                    /*
047                    TODO impl this
048                    Variant.VariantByref;
049                    Variant.VariantError;
050                    Variant.VariantTypeMask;
051                    */
052                    
053                    
054                    if(type==Variant.VariantEmpty) return null;
055                    else if(type==Variant.VariantNull) return null;
056                    else if(type==Variant.VariantShort) return Short.valueOf(variant.getShort());
057                    else if(type==Variant.VariantInt) return Integer.valueOf(variant.getInt());
058                    else if(type==Variant.VariantFloat) return new Float(variant.getFloat());
059                    else if(type==Variant.VariantDouble) return new Double(variant.getDouble());
060                    else if(type==Variant.VariantCurrency) {
061                            long l;
062                            try{
063                                    l=variant.getCurrency().longValue();
064                            }
065                            // this reflection allows support for old and new jacob version
066                            catch(Throwable t){
067                                    try{
068                                            Method toCurrency = variant.getClass().getMethod("toCurrency", new Class[0]);
069                                            Object curreny = toCurrency.invoke(variant, new Object[0]);
070                                            
071                                            Method longValue = curreny.getClass().getMethod("longValue", new Class[0]);
072                                            l=Caster.toLongValue(longValue.invoke(curreny, new Object[0]),0);
073                                    }
074                                    catch(Throwable t2){
075                                            l=0;
076                                    }
077                            }
078                            return Long.valueOf(l);
079                    }
080                    else if(type==Variant.VariantObject) return variant.toEnumVariant();
081                    else if(type==Variant.VariantDate) return new DateTimeImpl((long)variant.getDate(),true);
082                    else if(type==Variant.VariantString) return variant.getString();
083                    else if(type==Variant.VariantBoolean) return variant.getBoolean()?Boolean.TRUE:Boolean.FALSE;
084                    else if(type==Variant.VariantByte) return new Byte(variant.getByte());
085                    else if(type==Variant.VariantVariant) {
086                        throw new ExpressionException("type variant is not supported");
087                        //return toObject(variant.getV.get());
088                    }
089                    else if(type==Variant.VariantArray) {
090                            Variant[] varr = variant.getVariantArrayRef();
091                            Object[] oarr = new Object[varr.length];
092                            for(int i=0;i<varr.length;i++) {
093                                    oarr[i]=toObject(parent,varr[i],Caster.toString(i));
094                            }
095                            return new ArrayImpl(oarr);
096                    }
097                    else if(type==Variant.VariantDispatch) {
098                        
099                        return new COMObject(variant,variant.toDispatch(),parent.getName()+"."+key);
100                    }
101                    // TODO  ?? else if(type==Variant.VariantError) return variant.toError();
102    
103                    throw new ExpressionException("COM Type ["+toStringType(type)+"] not supported");
104        }
105        
106    
107            /**
108             * translate a short Variant Type Defintion to a String (string,empty,null,short ...)
109             * @param type
110             * @return String Variant Type
111             */
112            public static String toStringType(short type) {
113                    if(type==Variant.VariantEmpty) return "empty";
114                    else if(type==Variant.VariantNull) return "null";
115                    else if(type==Variant.VariantShort) return "Short";
116                    else if(type==Variant.VariantInt) return "Integer";
117                    else if(type==Variant.VariantFloat) return "Float";
118                    else if(type==Variant.VariantDouble) return "Double";
119                    else if(type==Variant.VariantCurrency) return "Currency";
120                    else if(type==Variant.VariantDate) return "Date";
121                    else if(type==Variant.VariantString) return "String";
122                    else if(type==Variant.VariantBoolean) return "Boolean";
123                    else if(type==Variant.VariantByte) return "Byte";
124                    else if(type==Variant.VariantArray) return "Array";
125                    else if(type==Variant.VariantDispatch) return "Dispatch";
126                    else if(type==Variant.VariantByref) return "Byref";
127                    else if(type==Variant.VariantCurrency) return "Currency";
128                    else if(type==Variant.VariantError) return "Error";
129                    else if(type==Variant.VariantInt) return "int";
130                    else if(type==Variant.VariantObject) return "Object";
131                    else if(type==Variant.VariantTypeMask) return "TypeMask";
132                    else if(type==Variant.VariantVariant) return "Variant";
133                    else return "unknow";
134            }
135    
136    }