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