001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.internal; 014 015import static org.apache.juneau.common.internal.ArgUtils.*; 016 017import java.util.*; 018 019import org.apache.juneau.*; 020 021/** 022 * Wrapper around a map where the key names are overridden. 023 * 024 * <h5 class='section'>See Also:</h5><ul> 025 026 * </ul> 027 * 028 * @param <K> The key class type. 029 * @param <V> The value class type. 030 */ 031public final class FilteredMap<K,V> extends AbstractMap<K,V> implements Delegate<Map<K,V>> { 032 033 final Map<K,V> innerMap; 034 final Set<Map.Entry<K,V>> entries; 035 final ClassMeta<Map<K,V>> classMeta; 036 037 /** 038 * Constructor. 039 * 040 * @param classMeta The class type of the map being wrapped. 041 * @param innerMap The map being wrapped. Must not be <jk>null</jk>. 042 * @param keys The keys in the new map. Must not be <jk>null</jk>. 043 */ 044 public FilteredMap(ClassMeta<Map<K,V>> classMeta, Map<K,V> innerMap, K[] keys) { 045 assertArgNotNull("innerMap", innerMap); 046 assertArgNotNull("keys", keys); 047 048 this.classMeta = classMeta; 049 this.innerMap = innerMap; 050 List<Map.Entry<K,V>> l = new ArrayList<>(keys.length); 051 for (K k : keys) 052 if (innerMap.containsKey(k)) 053 l.add(createEntry(k)); 054 entries = new ListSet<>(l); 055 } 056 057 private Map.Entry<K,V> createEntry(final K key) { 058 return new Map.Entry<>() { 059 060 @Override /* Map.Entry */ 061 public K getKey() { 062 return key; 063 } 064 065 @Override /* Map.Entry */ 066 public V getValue() { 067 return innerMap.get(key); 068 } 069 070 @Override /* Map.Entry */ 071 public V setValue(V v) { 072 return innerMap.put(key, v); 073 } 074 }; 075 } 076 077 078 @Override /* Map */ 079 public Set<Map.Entry<K,V>> entrySet() { 080 return entries; 081 } 082 083 /** 084 * A set with ordered entries (a List with a Set API). 085 */ 086 private static final class ListSet<E> extends AbstractSet<E> { 087 088 private List<E> entries; 089 090 public ListSet(List<E> entries) { 091 this.entries = entries; 092 } 093 094 @Override /* Set */ 095 public Iterator<E> iterator() { 096 return entries.iterator(); 097 } 098 099 @Override /* Set */ 100 public int size() { 101 return entries.size(); 102 } 103 } 104 105 @Override /* Delegate */ 106 public ClassMeta<Map<K,V>> getClassMeta() { 107 return classMeta; 108 } 109}