| /*=============================================================================# |
| # Copyright (c) 2008, 2021 Stephan Wahlbrink and others. |
| # |
| # This program and the accompanying materials are made available under the |
| # terms of the Eclipse Public License 2.0 which is available at |
| # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 |
| # which is available at https://www.apache.org/licenses/LICENSE-2.0. |
| # |
| # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 |
| # |
| # Contributors: |
| # Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation |
| #=============================================================================*/ |
| |
| package org.eclipse.statet.jcommons.collections; |
| |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import org.eclipse.statet.jcommons.lang.NonNull; |
| import org.eclipse.statet.jcommons.lang.NonNullByDefault; |
| import org.eclipse.statet.jcommons.lang.Nullable; |
| |
| |
| /** |
| * Map with String keys using case insensitive comparison. |
| * <p> |
| * For example for environment variables on windows. |
| */ |
| @NonNullByDefault |
| public class CaseInsensitiveMap<V> extends HashMap<@NonNull String, V> { |
| |
| |
| private static final long serialVersionUID= 1L; |
| |
| |
| // id= upper case key |
| // name= case sensitive key |
| |
| private final Map<String, String> idNameMap; |
| |
| |
| public CaseInsensitiveMap() { |
| this.idNameMap= new HashMap<>(); |
| } |
| |
| public CaseInsensitiveMap(final int initialCapacity) { |
| super(initialCapacity); |
| this.idNameMap= new HashMap<>(initialCapacity); |
| } |
| |
| |
| @Override |
| public @Nullable V put(final String name, final V value) { |
| final String id= name.toUpperCase(); |
| final String oldName= this.idNameMap.put(id, name); |
| @Nullable V prevValue; |
| if (!name.equals(oldName)) { |
| prevValue= super.remove(oldName); |
| super.put(name, value); |
| } |
| else { |
| prevValue= super.put(name, value); |
| } |
| return prevValue; |
| } |
| |
| @Override |
| public void putAll(final Map<? extends String, ? extends V> t) { |
| for (final Map.Entry<? extends String, ? extends V> entry : t.entrySet()) { |
| put(entry.getKey(), entry.getValue()); |
| } |
| } |
| |
| @Override |
| public @Nullable V remove(final @Nullable Object key) { |
| if (!(key instanceof String)) { |
| return null; |
| } |
| final String id= ((String) key).toUpperCase(); |
| final String realName= this.idNameMap.remove(id); |
| if (realName == null) { |
| return null; |
| } |
| return super.remove(realName); |
| } |
| |
| @Override |
| public void clear() { |
| this.idNameMap.clear(); |
| super.clear(); |
| } |
| |
| |
| @Override |
| public boolean isEmpty() { |
| return this.idNameMap.isEmpty(); |
| } |
| |
| @Override |
| public int size() { |
| return this.idNameMap.size(); |
| } |
| |
| @Override |
| public boolean containsKey(final @Nullable Object key) { |
| if (!(key instanceof String)) { |
| return false; |
| } |
| final String id= ((String) key).toUpperCase(); |
| return this.idNameMap.containsKey(id); |
| } |
| |
| // @Override |
| // public boolean containsValue(final Object value) { |
| // return super.containsValue(value); |
| // } |
| |
| @Override |
| public @Nullable V get(final @Nullable Object key) { |
| if (!(key instanceof String)) { |
| return null; |
| } |
| final String id= ((String) key).toUpperCase(); |
| final String name= this.idNameMap.get(id); |
| return (name != null) ? super.get(name) : null; |
| } |
| |
| |
| // @Override |
| // public Set<Entry<String, String>> entrySet() { |
| // return super.entrySet(); |
| // } |
| |
| // @Override |
| // public Set<String> keySet() { |
| // return super.keySet(); |
| // } |
| |
| // @Override |
| // public Collection<String> values() { |
| // return super.values(); |
| // } |
| |
| } |