001    package railo.commons.util.mod;
002    
003    import java.io.Serializable;
004    import java.util.Collection;
005    import java.util.HashSet;
006    import java.util.Iterator;
007    import java.util.Map;
008    import java.util.Set;
009    
010    import railo.runtime.exp.ExpressionException;
011    import railo.runtime.exp.PageException;
012    
013    public class MapProWrapper<K, V> implements MapPro<K, V>,Serializable {
014    
015            private final V NULL;
016            private Map<K, V> map;
017    
018            public MapProWrapper(Map<K, V> map,V NULL){
019                    this.map=map;
020                    this.NULL=NULL;
021            }
022            
023            @Override
024            public void clear() {
025                    map.clear();
026            }
027    
028            @Override
029            public boolean containsKey(Object key) {
030                    return map.containsKey(key);
031            }
032    
033            @Override
034            public boolean containsValue(Object value) {
035                    if(value==null)value=NULL;
036                    return map.containsValue(value);
037            }
038    
039            @Override
040            public Set<java.util.Map.Entry<K, V>> entrySet() {
041                    Set<Entry<K, V>> src = map.entrySet();
042                    Iterator<Entry<K, V>> it = src.iterator();
043                    Entry<K, V> e;
044                    while(it.hasNext()){
045                            e = it.next();
046                            if(e.getValue()==NULL) e.setValue(null);
047                    }
048                    return src;
049            }
050    
051            @Override
052            public V get(Object key) {
053                    V v = map.get(key);
054                    if(v==NULL) return null;
055                    return v;
056            }
057    
058            @Override
059            public V g(K key, V defaultValue) {
060                    V v = map.get(key);
061                    if(v==NULL) return null;
062                    if(v==null) return defaultValue;
063                    return v;
064            }
065    
066            @Override
067            public V g(K key) throws PageException {
068                    V v = map.get(key);
069                    if(v==NULL) return null;
070                    if(v==null) throw invalidKey(this,key,false);
071                    return v;
072            }
073    
074            @Override
075            public V r(K key, V defaultValue) {
076                    V v = map.remove(key);
077                    if(v==NULL) return null;
078                    if(v==null) return defaultValue;
079                    return v;
080            }
081    
082            @Override
083            public V r(K key) throws PageException {
084                    V v = map.get(key);
085                    if(v==NULL) return null;
086                    if(v==null) throw invalidKey(this,key,true);
087                    return v;
088            }
089            
090            private ExpressionException invalidKey(Map<K,V> map,K key, boolean remove) {
091    
092                    StringBuilder sb=new StringBuilder();
093                    Iterator<K> it = map.keySet().iterator();
094                    K k;
095                    while(it.hasNext()){
096                            k = it.next();
097                            if(sb.length()>0)sb.append(',');
098                            sb.append(k.toString());
099                    }
100    
101                    return new ExpressionException(
102                                    (remove?
103                                                    "cannot remove key ["+key+"] from struct, key doesn't exist":
104                                                    "key [" + key + "] doesn't exist") +
105                                    " (existing keys:" + sb.toString() + ")" );
106            }
107            
108            @Override
109            public boolean isEmpty() {
110                    return map.isEmpty();
111            }
112    
113            @Override
114            public Set<K> keySet() {
115                    return map.keySet();
116            }
117    
118            @Override
119            public V put(K key, V value) {
120                    V old;
121                    if(value==null) old=map.put(key, NULL);
122                    else old=map.put(key, value);
123                    
124                    if(old==NULL) return null;
125                    return old;
126            }
127    
128            @Override
129            public void putAll(Map<? extends K, ? extends V> m) {
130                    for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) {
131                put(e.getKey(), e.getValue());
132                    }
133            }
134    
135            @Override
136            public V remove(Object key) {
137                    return map.remove(key);
138            }
139    
140            @Override
141            public int size() {
142                    return map.size();
143            }
144    
145            @Override
146            public Collection<V> values() {
147                    Collection<V> src = map.values();
148                    Set<V> trg = new HashSet<V>();
149                    Iterator<V> it = src.iterator();
150                    V v;
151                    while(it.hasNext()){
152                            v = it.next();
153                            if(v==NULL) trg.add(null);
154                            else trg.add(v);
155                    }
156                    return trg;
157            }
158    
159            @Override
160            public boolean equals(Object arg0) {
161                    return map.equals(arg0);
162            }
163    
164            @Override
165            public int hashCode() {
166                    return map.hashCode();
167            }
168    
169            @Override
170            public String toString() {
171                    return map.toString();
172            }
173            
174            public Map<K, V> getMap(){
175                    return map;
176            }
177    }