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