001    package railo.runtime.com;
002    
003    import java.util.ArrayList;
004    import java.util.Iterator;
005    import java.util.List;
006    import java.util.Map.Entry;
007    
008    import railo.runtime.PageContext;
009    import railo.runtime.dump.DumpData;
010    import railo.runtime.dump.DumpProperties;
011    import railo.runtime.dump.DumpTable;
012    import railo.runtime.dump.SimpleDumpData;
013    import railo.runtime.exp.ExpressionException;
014    import railo.runtime.exp.PageException;
015    import railo.runtime.type.Collection;
016    import railo.runtime.type.Collection.Key;
017    import railo.runtime.type.Iteratorable;
018    import railo.runtime.type.KeyImpl;
019    import railo.runtime.type.Objects;
020    import railo.runtime.type.Struct;
021    import railo.runtime.type.dt.DateTime;
022    import railo.runtime.type.it.KeyAsStringIterator;
023    import railo.runtime.type.it.ObjectsEntryIterator;
024    
025    import com.jacob.com.Dispatch;
026    import com.jacob.com.Variant;
027    
028    /**
029     * 
030     */
031    public final class COMObject implements Objects, Iteratorable {
032    
033            private String name;
034        private Dispatch dispatch;
035        private Variant parent;
036    
037        /**
038             * Public Constructor of the class
039             * @param dispatch
040         * @throws ExpressionException 
041             */
042            public COMObject(String dispatch) {
043                    //if(!SystemUtil.isWindows()) throw new ExpressionException("Com Objects are only supported in Windows Enviroments");
044                    this.name=dispatch;
045                    this.dispatch=new Dispatch(dispatch);
046            }
047            
048            /**
049             * Private Constructor of the class for sub Objects
050             * @param parent
051             * @param dispatch
052             * @param name
053             */
054            COMObject(Variant parent,Dispatch dispatch, String name) {
055                    this.parent=parent;
056                    this.name=name;
057                    this.dispatch=dispatch;
058            }
059    
060        /*public Object get(PageContext pc, String propertyName) throws PageException {
061            return COMUtil.toObject(this,Dispatch.call(dispatch,propertyName),propertyName);
062        }*/
063    
064            public Object get(PageContext pc, Collection.Key key) throws PageException {
065                    return COMUtil.toObject(this,Dispatch.call(dispatch,key.getString()),key.getString());
066            }
067    
068        /*public Object get(PageContext pc, String propertyName, Object defaultValue) {
069            return COMUtil.toObject(this,Dispatch.call(dispatch,propertyName),propertyName,defaultValue);
070        }*/
071    
072            @Override
073        public Object get(PageContext pc, Collection.Key key, Object defaultValue) {
074                    return COMUtil.toObject(this,Dispatch.call(dispatch,key.getString()),key.getString(),defaultValue);
075            }
076    
077        /*public Object set(PageContext pc, String propertyName, Object value) {
078            return setEL(pc,propertyName,value);
079        }*/
080    
081            public Object set(PageContext pc, Collection.Key propertyName, Object value) throws PageException {
082                    Dispatch.put(dispatch,propertyName.getString(),value);
083                    return value;
084            }
085    
086        /*public Object setEL(PageContext pc, String propertyName, Object value) {
087                    Dispatch.put(dispatch,propertyName,value);
088                    return value;
089        }*/
090    
091            @Override
092            public Object setEL(PageContext pc, Collection.Key propertyName, Object value) {
093                    Dispatch.put(dispatch,propertyName.getString(),value);
094                    return value;
095            }
096    
097        /*public Object call(PageContext pc, String methodName, Object[] args) throws PageException {
098            Object[] arr=new Object[args.length];
099                    for(int i=0;i<args.length;i++) {
100                            if(args[i] instanceof COMObject)arr[i]=((COMObject)args[i]).dispatch;
101                            else arr[i]=args[i];
102                    }       
103                    return COMUtil.toObject(this,Dispatch.callN(dispatch,methodName,arr),methodName);
104        }*/
105    
106            @Override
107        public Object call(PageContext pc, Collection.Key key, Object[] args) throws PageException {
108                    String methodName=key.getString();
109                    Object[] arr=new Object[args.length];
110                    for(int i=0;i<args.length;i++) {
111                            if(args[i] instanceof COMObject)arr[i]=((COMObject)args[i]).dispatch;
112                            else arr[i]=args[i];
113                    }       
114                    return COMUtil.toObject(this,Dispatch.callN(dispatch,methodName,arr),methodName);
115            }
116    
117        /*public Object callWithNamedValues(PageContext pc, String methodName, Struct args) throws PageException {
118            // TODO gibt es hier eine bessere moeglichkeit?
119            Iterator<Object> it = args.valueIterator();
120            List<Object> values=new ArrayList<Object>();
121            while(it.hasNext()) {
122                values.add(it.next());
123            }   
124            return call(pc,KeyImpl.init(methodName),values.toArray(new Object[values.size()]));
125        }*/
126    
127            @Override
128            public Object callWithNamedValues(PageContext pc, Collection.Key key, Struct args) throws PageException {
129                    String methodName=key.getString();
130                    Iterator<Object> it = args.valueIterator();
131            List<Object> values=new ArrayList<Object>();
132            while(it.hasNext()) {
133                values.add(it.next());
134            }   
135            return call(pc,KeyImpl.init(methodName),values.toArray(new Object[values.size()]));
136            }
137    
138        public boolean isInitalized() {
139            return true;
140        }
141    
142        @Override
143            public DumpData toDumpData(PageContext pageContext, int maxlevel, DumpProperties dp) {
144                    DumpTable table = new DumpTable("com","#ff3300","#ff9966","#660000");
145                    table.appendRow(1,new SimpleDumpData("COM Object"),new SimpleDumpData(name));
146                    return table;
147        }
148    
149        @Override
150        public String castToString() throws ExpressionException {
151            throw new ExpressionException("can't cast Com Object to a String");
152        }
153    
154        @Override
155        public String castToString(String defaultValue) {
156            return defaultValue;
157        }
158    
159        @Override
160        public boolean castToBooleanValue() throws ExpressionException {
161            throw new ExpressionException("can't cast Com Object to a boolean value");
162        }
163        
164        @Override
165        public Boolean castToBoolean(Boolean defaultValue) {
166            return defaultValue;
167        }
168    
169        @Override
170        public double castToDoubleValue() throws ExpressionException {
171            throw new ExpressionException("can't cast Com Object to a number");
172        }
173        
174        @Override
175        public double castToDoubleValue(double defaultValue) {
176            return defaultValue;
177        }
178    
179        @Override
180        public DateTime castToDateTime() throws ExpressionException {
181            throw new ExpressionException("can't cast Com Object to a Date");
182        }
183        
184        @Override
185        public DateTime castToDateTime(DateTime defaultValue) {
186            return defaultValue;
187        }
188        
189        /**
190         * @return Returns the name.
191         */
192        public String getName() {
193            return name;
194        }
195        /**
196         * @return Returns the dispatch.
197         */
198        public Dispatch getDispatch() {
199            return dispatch;
200        }
201        /**
202         * @return Returns the parent.
203         */
204        public Variant getParent() {
205            return parent;
206        }
207    
208        /**
209         * release the com Object
210         */
211        public void release() {
212            dispatch.safeRelease();
213        }
214    
215            @Override
216            public int compareTo(boolean b) throws ExpressionException {
217                    throw new ExpressionException("can't compare Com Object with a boolean value");
218            }
219    
220            @Override
221            public int compareTo(DateTime dt) throws PageException {
222                    throw new ExpressionException("can't compare Com Object with a DateTime Object");
223            }
224    
225            @Override
226            public int compareTo(double d) throws PageException {
227                    throw new ExpressionException("can't compare Com Object with a numeric value");
228            }
229    
230            @Override
231            public int compareTo(String str) throws PageException {
232                    throw new ExpressionException("can't compare Com Object with a String");
233            }
234        
235            public Iterator iterator() {
236                    return valueIterator();
237            }
238            
239            @Override
240        public Iterator<Collection.Key> keyIterator() {
241            return new COMKeyWrapperIterator(this);
242        }
243        
244        @Override
245        public Iterator<String> keysAsStringIterator() {
246            return new KeyAsStringIterator(keyIterator());
247        }
248        
249        @Override
250            public Iterator<Object> valueIterator() {
251            return new COMValueWrapperIterator(this);
252        }
253    
254            @Override
255            public Iterator<Entry<Key, Object>> entryIterator() {
256                    return new ObjectsEntryIterator(keyIterator(), this);
257            }
258    }