| 
1607
 | 
     1 package goodjava.util;
 | 
| 
 | 
     2 
 | 
| 
 | 
     3 import java.util.Map;
 | 
| 
 | 
     4 import java.util.AbstractMap;
 | 
| 
 | 
     5 import java.util.Set;
 | 
| 
 | 
     6 import java.util.AbstractSet;
 | 
| 
 | 
     7 import java.util.Iterator;
 | 
| 
 | 
     8 
 | 
| 
 | 
     9 
 | 
| 
 | 
    10 public final class CaseInsensitiveMap<V> extends AbstractMap<String,V> {
 | 
| 
 | 
    11 
 | 
| 
 | 
    12 	public static final class Value<V> {
 | 
| 
 | 
    13 		private final String s;
 | 
| 
 | 
    14 		private final V v;
 | 
| 
 | 
    15 
 | 
| 
 | 
    16 		private Value(String s,V v) {
 | 
| 
 | 
    17 			this.s = s;
 | 
| 
 | 
    18 			this.v = v;
 | 
| 
 | 
    19 		}
 | 
| 
 | 
    20 	}
 | 
| 
 | 
    21 
 | 
| 
 | 
    22 	private final Map<String,Value<V>> map;
 | 
| 
 | 
    23 
 | 
| 
 | 
    24 	public CaseInsensitiveMap(Map<String,Value<V>> map) {
 | 
| 
 | 
    25 		this.map = map;
 | 
| 
 | 
    26 	}
 | 
| 
 | 
    27 
 | 
| 
 | 
    28 	@Override public int size() {
 | 
| 
 | 
    29 		return map.size();
 | 
| 
 | 
    30 	}
 | 
| 
 | 
    31 
 | 
| 
 | 
    32 	@Override public boolean isEmpty() {
 | 
| 
 | 
    33 		return map.isEmpty();
 | 
| 
 | 
    34 	}
 | 
| 
 | 
    35 
 | 
| 
 | 
    36 	@Override public boolean containsKey(Object key) {
 | 
| 
 | 
    37 		if( !(key instanceof String) )
 | 
| 
 | 
    38 			return false;
 | 
| 
 | 
    39 		String s = (String)key;
 | 
| 
 | 
    40 		return map.containsKey(s.toLowerCase());
 | 
| 
 | 
    41 	}
 | 
| 
 | 
    42 
 | 
| 
 | 
    43 	@Override public V get(Object key) {
 | 
| 
 | 
    44 		if( !(key instanceof String) )
 | 
| 
 | 
    45 			return null;
 | 
| 
 | 
    46 		String s = (String)key;
 | 
| 
 | 
    47 		Value<V> val = map.get(s.toLowerCase());
 | 
| 
 | 
    48 		return val==null ? null : val.v;
 | 
| 
 | 
    49 	}
 | 
| 
 | 
    50 
 | 
| 
 | 
    51 	@Override public V put(String key,V value) {
 | 
| 
 | 
    52 		Value<V> val = map.put( key.toLowerCase(), new Value<V>(key,value) );
 | 
| 
 | 
    53 		return val==null ? null : val.v;
 | 
| 
 | 
    54 	}
 | 
| 
 | 
    55 
 | 
| 
 | 
    56 	@Override public V remove(Object key) {
 | 
| 
 | 
    57 		if( !(key instanceof String) )
 | 
| 
 | 
    58 			return null;
 | 
| 
 | 
    59 		String s = (String)key;
 | 
| 
 | 
    60 		Value<V> val = map.remove(s.toLowerCase());
 | 
| 
 | 
    61 		return val==null ? null : val.v;
 | 
| 
 | 
    62 	}
 | 
| 
 | 
    63 
 | 
| 
 | 
    64 	@Override public void clear() {
 | 
| 
 | 
    65 		map.clear();
 | 
| 
 | 
    66 	}
 | 
| 
 | 
    67 
 | 
| 
 | 
    68 	@Override public Set<Map.Entry<String,V>> entrySet() {
 | 
| 
 | 
    69 		return new MySet();
 | 
| 
 | 
    70 	}
 | 
| 
 | 
    71 
 | 
| 
 | 
    72 	private class MySet extends AbstractSet<Map.Entry<String,V>> {
 | 
| 
 | 
    73 
 | 
| 
 | 
    74 		@Override public int size() {
 | 
| 
 | 
    75 			return CaseInsensitiveMap.this.size();
 | 
| 
 | 
    76 		}
 | 
| 
 | 
    77 
 | 
| 
 | 
    78 		@Override public Iterator<Map.Entry<String,V>> iterator() {
 | 
| 
 | 
    79 			return new MyIterator();
 | 
| 
 | 
    80 		}
 | 
| 
 | 
    81 	}
 | 
| 
 | 
    82 
 | 
| 
 | 
    83 	private class MyIterator implements Iterator<Map.Entry<String,V>> {
 | 
| 
 | 
    84 		final Iterator<Map.Entry<String,Value<V>>> iter = map.entrySet().iterator();
 | 
| 
 | 
    85 
 | 
| 
 | 
    86 		@Override public Map.Entry<String,V> next() {
 | 
| 
 | 
    87 			Value<V> val = iter.next().getValue();
 | 
| 
 | 
    88 			return new AbstractMap.SimpleImmutableEntry<String,V>( val.s, val.v );
 | 
| 
 | 
    89 		}
 | 
| 
 | 
    90 
 | 
| 
 | 
    91 		@Override public boolean hasNext() {
 | 
| 
 | 
    92 			return iter.hasNext();
 | 
| 
 | 
    93 		}
 | 
| 
 | 
    94 
 | 
| 
 | 
    95 		@Override public void remove() {
 | 
| 
 | 
    96 			iter.remove();
 | 
| 
 | 
    97 		}
 | 
| 
 | 
    98 	}
 | 
| 
 | 
    99 }
 |