001    package railo.runtime.type.wrap;
002    
003    import java.util.Iterator;
004    import java.util.Map;
005    
006    import railo.runtime.PageContext;
007    import railo.runtime.dump.DumpData;
008    import railo.runtime.dump.DumpProperties;
009    import railo.runtime.dump.DumpUtil;
010    import railo.runtime.exp.ExpressionException;
011    import railo.runtime.exp.PageException;
012    import railo.runtime.op.Caster;
013    import railo.runtime.op.Duplicator;
014    import railo.runtime.type.Collection;
015    import railo.runtime.type.KeyImpl;
016    import railo.runtime.type.Struct;
017    import railo.runtime.type.dt.DateTime;
018    import railo.runtime.type.util.StructSupport;
019    
020    /**
021     * 
022     */
023    public  class MapAsStruct extends StructSupport implements Struct {
024        
025        Map map;
026            private boolean caseSensitive;
027    
028        /**
029         * constructor of the class
030         * @param map
031         * @param caseSensitive 
032         */
033        private MapAsStruct(Map map, boolean caseSensitive) {
034            this.map=map;
035            this.caseSensitive=caseSensitive;
036        }
037        
038    
039        public static Struct toStruct(Map map, boolean caseSensitive) {
040            if(map instanceof Struct) return ((Struct)map);
041                    return new MapAsStruct(map,caseSensitive);
042            }
043        
044        /**
045         * @see railo.runtime.type.Collection#size()
046         */
047        public int size() {
048           return map.size();
049        }
050    
051    
052        /**
053         * @see railo.runtime.type.Collection#keysAsString()
054         */
055        public synchronized String[] keysAsString() {
056            int len=size();
057            String[] k=new String[len];
058            Iterator it = map.keySet().iterator();
059            int count=0;
060            while(it.hasNext()) {
061                k[count++]=it.next().toString();
062            }
063            return k;
064        }
065        /**
066         * @see railo.runtime.type.Collection#keys()
067         */
068        public synchronized Collection.Key[] keys() {
069            int len=size();
070            Collection.Key[] k=new Collection.Key[len];
071            Iterator it = map.keySet().iterator();
072            int count=0;
073            while(it.hasNext()) {
074                k[count++]=KeyImpl.init(it.next().toString());
075            }
076            return k;
077        }
078        
079        public static String getCaseSensitiveKey(Map map,String key) {
080            Iterator it = map.keySet().iterator();
081                    String strKey;
082            while(it.hasNext()) {
083                    strKey=Caster.toString(it.next(),"");
084                    if(strKey.equalsIgnoreCase(key)) return strKey;
085            }
086                    return null;
087            }
088    
089        /**
090         * @see railo.runtime.type.Collection#remove(java.lang.String)
091         */
092        public synchronized Object remove(Collection.Key key) throws ExpressionException {
093            Object obj= map.remove(key.getString());
094            if(obj==null) {
095                    if(!caseSensitive){
096                            String csKey = getCaseSensitiveKey(map,key.getString());
097                            if(csKey!=null)obj= map.remove(csKey);
098                            if(obj!=null)return obj;
099                    }
100                    throw new ExpressionException("can't remove key ["+key.getString()+"] from map, key doesn't exists");
101            }
102            return obj;
103        }
104        
105        /**
106         * @see railo.runtime.type.Collection#removeEL(java.lang.String)
107         */
108        public synchronized Object removeEL(Collection.Key key) {
109            Object obj= map.remove(key.getString());
110            if(!caseSensitive && obj==null) {
111                    String csKey = getCaseSensitiveKey(map,key.getString());
112                    if(csKey!=null)obj= map.remove(csKey);
113            }
114            return obj;
115        }
116    
117        /**
118         * @see railo.runtime.type.Collection#clear()
119         */
120        public synchronized void clear() {
121            map.clear();
122        }
123    
124        /**
125         * @see railo.runtime.type.Collection#get(java.lang.String)
126         */
127        public synchronized Object get(Collection.Key key) throws ExpressionException {
128            Object o=map.get(key.getString());
129            if(o==null) {
130                    if(!caseSensitive){
131                            String csKey = getCaseSensitiveKey(map,key.getString());
132                            if(csKey!=null)o= map.get(csKey);
133                            if(o!=null) return o;
134                    }
135                    throw new ExpressionException("key "+key.getString()+" doesn't exists in "+Caster.toClassName(map));
136            }
137            return o;
138        }
139    
140        /**
141         * @see railo.runtime.type.Collection#get(railo.runtime.type.Collection.Key, java.lang.Object)
142         */
143        public synchronized Object get(Collection.Key key, Object defaultValue) {
144            Object obj=map.get(key.getString());
145            if(obj==null) {
146                    if(!caseSensitive){
147                            String csKey = getCaseSensitiveKey(map,key.getString());
148                            if(csKey!=null)obj= map.get(csKey);
149                            if(obj!=null) return obj; 
150                    }
151                return defaultValue;
152            }
153            return obj;
154        }
155    
156        /**
157         * @see railo.runtime.type.Collection#set(java.lang.String, java.lang.Object)
158         */
159        public synchronized Object set(Collection.Key key, Object value) throws PageException {
160            return map.put(key.getString(),value);
161        }
162    
163        /**
164         * @see railo.runtime.type.Collection#setEL(java.lang.String, java.lang.Object)
165         */
166        public synchronized Object setEL(Collection.Key key, Object value) {
167            return map.put(key.getString(),value);
168        }
169        
170        
171        /**
172         * @see railo.runtime.type.Collection#keyIterator()
173         */
174        public synchronized Iterator keyIterator() {
175            return map.keySet().iterator();//new ArrayIterator(map.keySet().toArray());
176        }
177        
178        /**
179             * @see railo.runtime.dump.Dumpable#toDumpData(railo.runtime.PageContext, int)
180             */
181            public DumpData toDumpData(PageContext pageContext, int maxlevel, DumpProperties dp) {
182                return DumpUtil.toDumpData(map, pageContext,maxlevel,dp); 
183        }
184       
185        /**
186         * @see railo.runtime.type.Collection#duplicate(boolean)
187         */
188        public synchronized Collection duplicate(boolean deepCopy) {
189            return new MapAsStruct(Duplicator.duplicateMap(map,deepCopy),caseSensitive);
190        }
191    
192            
193    
194        /**
195         * @see railo.runtime.type.Collection#containsKey(java.lang.String)
196         */
197        public boolean containsKey(Collection.Key key) {
198            
199            //return map.containsKey(key.getString());
200            
201            boolean contains = map.containsKey(key.getString());
202            if(contains) return true; 
203            if(!caseSensitive)return map.containsKey(getCaseSensitiveKey(map,key.getString()));
204            return false;
205        }
206    
207        /**
208         * @see railo.runtime.op.Castable#castToString()
209         */
210        public String castToString() throws ExpressionException {
211            throw new ExpressionException("Can't cast Complex Object Type Struct ["+getClass().getName()+"] to String",
212              "Use Build-In-Function \"serialize(Struct):String\" to create a String from Struct");
213        }
214            /**
215             * @see railo.runtime.type.util.StructSupport#castToString(java.lang.String)
216             */
217            public String castToString(String defaultValue) {
218                    return defaultValue;
219            }
220    
221    
222        /**
223         * @see railo.runtime.op.Castable#castToBooleanValue()
224         */
225        public boolean castToBooleanValue() throws ExpressionException {
226            throw new ExpressionException("Can't cast Complex Object Type Struct ["+getClass().getName()+"] to a boolean value");
227        }
228        
229        /**
230         * @see railo.runtime.op.Castable#castToBoolean(java.lang.Boolean)
231         */
232        public Boolean castToBoolean(Boolean defaultValue) {
233            return defaultValue;
234        }
235    
236    
237        /**
238         * @see railo.runtime.op.Castable#castToDoubleValue()
239         */
240        public double castToDoubleValue() throws ExpressionException {
241            throw new ExpressionException("Can't cast Complex Object Type Struct ["+getClass().getName()+"] to a number value");
242        }
243        
244        /**
245         * @see railo.runtime.op.Castable#castToDoubleValue(double)
246         */
247        public double castToDoubleValue(double defaultValue) {
248            return defaultValue;
249        }
250    
251    
252        /**
253         * @see railo.runtime.op.Castable#castToDateTime()
254         */
255        public DateTime castToDateTime() throws ExpressionException {
256            throw new ExpressionException("Can't cast Complex Object Type Struct ["+getClass().getName()+"] to a Date");
257        }
258        
259        /**
260         * @see railo.runtime.op.Castable#castToDateTime(railo.runtime.type.dt.DateTime)
261         */
262        public DateTime castToDateTime(DateTime defaultValue) {
263            return defaultValue;
264        }
265    
266            /**
267             * @see railo.runtime.op.Castable#compare(boolean)
268             */
269            public int compareTo(boolean b) throws ExpressionException {
270                    throw new ExpressionException("can't compare Complex Object Type Struct ["+getClass().getName()+"] with a boolean value");
271            }
272    
273            /**
274             * @see railo.runtime.op.Castable#compareTo(railo.runtime.type.dt.DateTime)
275             */
276            public int compareTo(DateTime dt) throws PageException {
277                    throw new ExpressionException("can't compare Complex Object Type Struct ["+getClass().getName()+"] with a DateTime Object");
278            }
279    
280            /**
281             * @see railo.runtime.op.Castable#compareTo(double)
282             */
283            public int compareTo(double d) throws PageException {
284                    throw new ExpressionException("can't compare Complex Object Type Struct ["+getClass().getName()+"] with a numeric value");
285            }
286    
287            /**
288             * @see railo.runtime.op.Castable#compareTo(java.lang.String)
289             */
290            public int compareTo(String str) throws PageException {
291                    throw new ExpressionException("can't compare Complex Object Type Struct ["+getClass().getName()+"] with a String");
292            }
293    
294            /**
295             * @see java.util.Map#containsValue(java.lang.Object)
296             */
297            public boolean containsValue(Object value) {
298                    return map.containsValue(value);
299            }
300    
301            /**
302             * @see java.util.Map#values()
303             */
304            public java.util.Collection values() {
305                    return map.values();
306            }
307    }
308    
309    
310    
311    
312    
313