1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.collections4.bidimap;
18
19 import java.util.Map;
20 import java.util.Set;
21
22 import org.apache.commons.collections4.BidiMap;
23 import org.apache.commons.collections4.MapIterator;
24 import org.apache.commons.collections4.Unmodifiable;
25 import org.apache.commons.collections4.iterators.UnmodifiableMapIterator;
26 import org.apache.commons.collections4.map.UnmodifiableEntrySet;
27 import org.apache.commons.collections4.set.UnmodifiableSet;
28
29 /**
30 * Decorates another {@link BidiMap} to ensure it can't be altered.
31 * <p>
32 * Attempts to modify it will result in an UnsupportedOperationException.
33 * </p>
34 *
35 * @param <K> The type of the keys in this map
36 * @param <V> The type of the values in this map
37 * @since 3.0
38 */
39 public final class UnmodifiableBidiMap<K, V>
40 extends AbstractBidiMapDecorator<K, V> implements Unmodifiable {
41
42 /**
43 * Factory method to create an unmodifiable map.
44 * <p>
45 * If the map passed in is already unmodifiable, it is returned.
46 *
47 * @param <K> The key type
48 * @param <V> The value type
49 * @param map The map to decorate, must not be null
50 * @return An unmodifiable BidiMap
51 * @throws NullPointerException if map is null
52 * @since 4.0
53 */
54 public static <K, V> BidiMap<K, V> unmodifiableBidiMap(final BidiMap<? extends K, ? extends V> map) {
55 if (map instanceof Unmodifiable) {
56 @SuppressWarnings("unchecked") // safe to upcast
57 final BidiMap<K, V> tmpMap = (BidiMap<K, V>) map;
58 return tmpMap;
59 }
60 return new UnmodifiableBidiMap<>(map);
61 }
62
63 /** The inverse unmodifiable map */
64 private UnmodifiableBidiMap<V, K> inverse;
65
66 /**
67 * Constructor that wraps (not copies).
68 *
69 * @param map The map to decorate, must not be null
70 * @throws NullPointerException if map is null
71 */
72 @SuppressWarnings("unchecked") // safe to upcast
73 private UnmodifiableBidiMap(final BidiMap<? extends K, ? extends V> map) {
74 super((BidiMap<K, V>) map);
75 }
76
77 /**
78 * Always throws {@link UnsupportedOperationException}.
79 *
80 * @throws UnsupportedOperationException Always thrown.
81 */
82 @Override
83 public void clear() {
84 throw new UnsupportedOperationException();
85 }
86
87 @Override
88 public Set<Map.Entry<K, V>> entrySet() {
89 final Set<Map.Entry<K, V>> set = super.entrySet();
90 return UnmodifiableEntrySet.unmodifiableEntrySet(set);
91 }
92
93 @Override
94 public synchronized BidiMap<V, K> inverseBidiMap() {
95 if (inverse == null) {
96 inverse = new UnmodifiableBidiMap<>(decorated().inverseBidiMap());
97 inverse.inverse = this;
98 }
99 return inverse;
100 }
101
102 @Override
103 public Set<K> keySet() {
104 final Set<K> set = super.keySet();
105 return UnmodifiableSet.unmodifiableSet(set);
106 }
107
108 @Override
109 public MapIterator<K, V> mapIterator() {
110 final MapIterator<K, V> it = decorated().mapIterator();
111 return UnmodifiableMapIterator.unmodifiableMapIterator(it);
112 }
113
114 /**
115 * Always throws {@link UnsupportedOperationException}.
116 *
117 * @param key Ignored.
118 * @param value Ignored.
119 * @throws UnsupportedOperationException Always thrown.
120 */
121 @Override
122 public V put(final K key, final V value) {
123 throw new UnsupportedOperationException();
124 }
125
126 /**
127 * Always throws {@link UnsupportedOperationException}.
128 *
129 * @param mapToCopy Ignored.
130 * @throws UnsupportedOperationException Always thrown.
131 */
132 @Override
133 public void putAll(final Map<? extends K, ? extends V> mapToCopy) {
134 throw new UnsupportedOperationException();
135 }
136
137 /**
138 * Always throws {@link UnsupportedOperationException}.
139 *
140 * @param key Ignored.
141 * @throws UnsupportedOperationException Always thrown.
142 */
143 @Override
144 public V remove(final Object key) {
145 throw new UnsupportedOperationException();
146 }
147
148 /**
149 * Always throws {@link UnsupportedOperationException}.
150 *
151 * @param value Ignored.
152 * @throws UnsupportedOperationException Always thrown.
153 */
154 @Override
155 public K removeValue(final Object value) {
156 throw new UnsupportedOperationException();
157 }
158
159 @Override
160 public Set<V> values() {
161 return UnmodifiableSet.unmodifiableSet(super.values());
162 }
163
164 }