/* * #%L * Gravia :: Resource * %% * Copyright (C) 2010 - 2014 JBoss by Red Hat * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * #L% */ package org.jboss.gravia.utils; import java.util.Collections; import java.util.Dictionary; import java.util.Enumeration; import java.util.HashSet; import java.util.Hashtable; import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.Vector; /** * A case insensitive dictionary. * * @author Thomas.Diesler@jboss.com */ @SuppressWarnings("rawtypes") public class CaseInsensitiveDictionary<V> extends Hashtable<String, V> { private static final long serialVersionUID = 5802491129524016545L; /** The delegate dictionary */ private Dictionary<String, V> delegate; /** The original keys */ private Set<String> originalKeys; /** * Create a new CaseInsensitiveDictionary. * * @param delegate the delegate */ public CaseInsensitiveDictionary(Dictionary<String, V> delegate) { IllegalArgumentAssertion.assertNotNull(delegate, "delegate"); this.delegate = new Hashtable<String, V>(delegate.size()); this.originalKeys = Collections.synchronizedSet(new HashSet<String>()); Enumeration<String> e = delegate.keys(); while (e.hasMoreElements()) { String key = e.nextElement(); if (get(key) != null) throw new IllegalArgumentException("Duplicates for key [" + key + "] in: " + delegate); this.delegate.put(key.toLowerCase(Locale.ENGLISH), delegate.get(key)); originalKeys.add(key); } } @Override public Enumeration<V> elements() { return delegate.elements(); } @Override @SuppressWarnings("unchecked") public synchronized boolean equals(Object obj) { if (obj == this) return true; if (obj == null || obj instanceof Dictionary == false) return false; Dictionary<String, Object> other = (Dictionary) obj; if (size() != other.size()) return false; if (isEmpty()) return true; for (String key : originalKeys) { if (get(key).equals(other.get(key))) return false; } return true; } @Override public V get(Object key) { if (key instanceof String) key = ((String) key).toLowerCase(Locale.ENGLISH); return delegate.get(key); } @Override public int hashCode() { return delegate.hashCode(); } @Override public boolean isEmpty() { return delegate.isEmpty(); } @Override @SuppressWarnings("unchecked") public Enumeration<String> keys() { return new Vector(originalKeys).elements(); } @Override public V put(String key, V value) { throw new UnsupportedOperationException("immutable"); } @Override public V remove(Object key) { throw new UnsupportedOperationException("immutable"); } @Override public Set<String> keySet() { return originalKeys; } @Override public Set<Map.Entry<String, V>> entrySet() { Set<Map.Entry<String, V>> entrySet = new HashSet<Map.Entry<String, V>>(); for (final String key : originalKeys) { final V value = get(key); Map.Entry<String, V> entry = new Map.Entry<String, V>() { @Override public String getKey() { return key; } @Override public V getValue() { return value; } @Override public V setValue(Object value) { throw new UnsupportedOperationException("immutable"); } }; entrySet.add(entry); } return entrySet; } @Override public int size() { return delegate.size(); } @Override public String toString() { return delegate.toString(); } }