/* * Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com * The software in this package is published under the terms of the CPAL v1.0 * license, a copy of which has been included with this distribution in the * LICENSE.txt file. */ package org.mule.runtime.core.util; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.Map; import org.apache.commons.collections.map.AbstractHashedMap; /** * A case-insensitive <code>Map</code>. * <p/> * As entries are added to the map, keys hash values are lowercase hash codes of the key. the Real key case is preserved. * <p/> * <p/> * The <code>keySet()</code> method returns all keys in their original case * <p/> * <strong>Note that CaseInsensitiveMap is not synchronized and is not thread-safe.</strong> If you wish to use this map from * multiple threads concurrently, you must use appropriate synchronization. The simplest approach is to wrap this map using * {@link java.util.Collections#synchronizedMap(Map)}. This class may throw exceptions when accessed by concurrent threads without * synchronization. * * @since 3.0.0 */ public class CaseInsensitiveHashMap extends AbstractHashedMap implements Serializable { /** * Serialisation version */ private static final long serialVersionUID = -7074633917369299456L; /** * Constructs a new empty map with default size and load factor. */ public CaseInsensitiveHashMap() { super(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_THRESHOLD); } /** * Constructs a new, empty map with the specified initial capacity. * * @param initialCapacity the initial capacity * @throws IllegalArgumentException if the initial capacity is less than one */ public CaseInsensitiveHashMap(int initialCapacity) throws IllegalArgumentException { super(initialCapacity); } /** * Constructs a new, empty map with the specified initial capacity and load factor. * * @param initialCapacity the initial capacity * @param loadFactor the load factor * @throws IllegalArgumentException if the initial capacity is less than one * @throws IllegalArgumentException if the load factor is less than zero */ public CaseInsensitiveHashMap(int initialCapacity, float loadFactor) throws IllegalArgumentException { super(initialCapacity, loadFactor); } /** * Constructor copying elements from another map. * <p/> * Keys will be converted to lower case strings, which may cause some entries to be removed (if string representation of keys * differ only by character case). * * @param map the map to copy * @throws NullPointerException if the map is null */ public CaseInsensitiveHashMap(Map map) { super(map); } /** * Creates a hash value from the lower case value of the key. The same function will be used when querying a value in the map * also * * @param key the key value to hash * @return a hash value for the lower case key */ @Override protected int hash(Object key) { return super.hash(key.toString().toLowerCase()); } /** * Overloads the default behaviour to compare the keys without case sensitivity * * @param key1 the first key * @param key2 the key to compare against * @return true is the keys match */ @Override protected boolean isEqualKey(Object key1, Object key2) { if (key1 instanceof String && key2 instanceof String) { return (((String) key1).equalsIgnoreCase((String) key2)); } else { return super.isEqualKey(key1, key2); } } // ----------------------------------------------------------------------- /** * Clones the map without cloning the keys or values. * * @return a shallow clone */ @Override public Object clone() { return super.clone(); } /** * Write the map out using a custom routine. */ private void writeObject(ObjectOutputStream out) throws IOException { out.defaultWriteObject(); doWriteObject(out); } /** * Read the map in using a custom routine. */ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); doReadObject(in); } }