/common/common-lang/src/main/java/com/twelvemonkeys/util/IgnoreCaseMap.java
https://github.com/conceptboard/TwelveMonkeys · Java · 176 lines · 46 code · 15 blank · 115 comment · 2 complexity · 9d3fcee23100613c1c0bbc03df4c4717 MD5 · raw file
- /*
- * Copyright (c) 2008, Harald Kuhr
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name "TwelveMonkeys" nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
- package com.twelvemonkeys.util;
-
- import java.util.Iterator;
- import java.util.Map;
- import java.io.Serializable;
-
- /**
- * A {@code Map} decorator that makes the mappings in the backing map
- * case insensitive
- * (this is implemented by converting all keys to uppercase),
- * if the keys used are {@code Strings}. If the keys
- * used are not {@code String}s, it wil work as a normal
- * {@code java.util.Map}.
- * <p/>
- *
- * @see java.util.Map
- *
- * @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
- */
- public class IgnoreCaseMap<V> extends AbstractDecoratedMap<String, V> implements Serializable, Cloneable {
-
- /**
- * Constructs a new empty {@code Map}.
- * The backing map will be a {@link java.util.HashMap}
- */
- public IgnoreCaseMap() {
- super();
- }
-
- /**
- * Constructs a new {@code Map} with the same key-value mappings as the
- * given {@code Map}.
- * The backing map will be a {@link java.util.HashMap}
- * <p/>
- * NOTE: As the keys in the given map parameter will be converted to
- * uppercase (if they are strings), any duplicate key/value pair where
- * {@code key instanceof String && key.equalsIgnoreCase(otherKey)}
- * is true, will be lost.
- *
- * @param pMap the map whose mappings are to be placed in this map.
- */
- public IgnoreCaseMap(Map<String, ? extends V> pMap) {
- super(pMap);
- }
-
- /**
- * Constructs a new {@code Map} with the same key-value mappings as the
- * given {@code Map}.
- * <p/>
- * NOTE: The backing map is structuraly cahnged, and it should NOT be
- * accessed directly, after the wrapped map is created.
- * <p/>
- * NOTE: As the keys in the given map parameter will be converted to
- * uppercase (if they are strings), any duplicate key/value pair where
- * {@code key instanceof String && key.equalsIgnoreCase(otherKey)}
- * is true, will be lost.
- *
- * @param pBacking the backing map of this map. Must be either empty, or
- * the same map as {@code pContents}.
- * @param pContents the map whose mappings are to be placed in this map.
- * May be {@code null}
- *
- * @throws IllegalArgumentException if {@code pBacking} is {@code null}
- * @throws IllegalArgumentException if {@code pBacking} differs from
- * {@code pContent} and is not empty.
- */
- public IgnoreCaseMap(Map pBacking, Map<String, ? extends V> pContents) {
- super(pBacking, pContents);
- }
-
- /**
- * Maps the specified key to the specified value in this map.
- * Note: If the key used is a string, the key will not be case-sensitive.
- *
- * @param pKey the map key.
- * @param pValue the value.
- * @return the previous value of the specified key in this map,
- * or null if it did not have one.
- */
- public V put(String pKey, V pValue) {
- String key = (String) toUpper(pKey);
- return unwrap(entries.put(key, new BasicEntry<String, V>(key, pValue)));
- }
-
- private V unwrap(Entry<String, V> pEntry) {
- return pEntry != null ? pEntry.getValue() : null;
- }
-
- /**
- * Returns the value to which the specified key is mapped in this
- * map.
- * Note: If the key used is a string, the key will not be case-sensitive.
- *
- * @param pKey a key in the map
- * @return the value to which the key is mapped in this map; null if
- * the key is not mapped to any value in this map.
- */
- public V get(Object pKey) {
- return unwrap(entries.get(toUpper(pKey)));
- }
-
- /**
- * Removes the key (and its corresponding value) from this map. This
- * method does nothing if the key is not in the map.
- * Note: If the key used is a string, the key will not be case-sensitive.
- *
- * @param pKey the key that needs to be removed.
- * @return the value to which the key had been mapped in this map,
- * or null if the key did not have a mapping.
- */
- public V remove(Object pKey) {
- return unwrap(entries.remove(toUpper(pKey)));
- }
-
- /**
- * Tests if the specified object is a key in this map.
- * Note: If the key used is a string, the key will not be case-sensitive.
- *
- * @param pKey possible key.
- * @return true if and only if the specified object is a key in this
- * map, as determined by the equals method; false otherwise.
- */
- public boolean containsKey(Object pKey) {
- return entries.containsKey(toUpper(pKey));
- }
-
- /**
- * Converts the parameter to uppercase, if it's a String.
- */
- protected static Object toUpper(final Object pObject) {
- if (pObject instanceof String) {
- return ((String) pObject).toUpperCase();
- }
- return pObject;
- }
-
- protected Iterator<Entry<String, V>> newEntryIterator() {
- return (Iterator) entries.entrySet().iterator();
- }
-
- protected Iterator<String> newKeyIterator() {
- return entries.keySet().iterator();
- }
-
- protected Iterator<V> newValueIterator() {
- return (Iterator<V>) entries.values().iterator();
- }
- }