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.OrderedBidiMap;
23 import org.apache.commons.collections4.OrderedMapIterator;
24 import org.apache.commons.collections4.Unmodifiable;
25 import org.apache.commons.collections4.iterators.UnmodifiableOrderedMapIterator;
26 import org.apache.commons.collections4.map.UnmodifiableEntrySet;
27 import org.apache.commons.collections4.set.UnmodifiableSet;
28
29 /**
30 * Decorates another {@link OrderedBidiMap} 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 UnmodifiableOrderedBidiMap<K, V>
40 extends AbstractOrderedBidiMapDecorator<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 OrderedBidiMap
51 * @throws NullPointerException if map is null
52 * @since 4.0
53 */
54 public static <K, V> OrderedBidiMap<K, V> unmodifiableOrderedBidiMap(
55 final OrderedBidiMap<? extends K, ? extends V> map) {
56 if (map instanceof Unmodifiable) {
57 @SuppressWarnings("unchecked") // safe to upcast
58 final OrderedBidiMap<K, V> tmpMap = (OrderedBidiMap<K, V>) map;
59 return tmpMap;
60 }
61 return new UnmodifiableOrderedBidiMap<>(map);
62 }
63
64 /** The inverse unmodifiable map */
65 private UnmodifiableOrderedBidiMap<V, K> inverse;
66
67 /**
68 * Constructor that wraps (not copies).
69 *
70 * @param map The map to decorate, must not be null
71 * @throws NullPointerException if map is null
72 */
73 @SuppressWarnings("unchecked") // safe to upcast
74 private UnmodifiableOrderedBidiMap(final OrderedBidiMap<? extends K, ? extends V> map) {
75 super((OrderedBidiMap<K, V>) map);
76 }
77
78 /**
79 * Always throws {@link UnsupportedOperationException}.
80 *
81 * @throws UnsupportedOperationException Always thrown.
82 */
83 @Override
84 public void clear() {
85 throw new UnsupportedOperationException();
86 }
87
88 @Override
89 public Set<Map.Entry<K, V>> entrySet() {
90 final Set<Map.Entry<K, V>> set = super.entrySet();
91 return UnmodifiableEntrySet.unmodifiableEntrySet(set);
92 }
93
94 @Override
95 public OrderedBidiMap<V, K> inverseBidiMap() {
96 return inverseOrderedBidiMap();
97 }
98
99 /**
100 * Gets an unmodifiable view of this map where the keys and values are reversed.
101 *
102 * @return An inverted unmodifiable bidirectional map
103 */
104 public OrderedBidiMap<V, K> inverseOrderedBidiMap() {
105 if (inverse == null) {
106 inverse = new UnmodifiableOrderedBidiMap<>(decorated().inverseBidiMap());
107 inverse.inverse = this;
108 }
109 return inverse;
110 }
111
112 @Override
113 public Set<K> keySet() {
114 final Set<K> set = super.keySet();
115 return UnmodifiableSet.unmodifiableSet(set);
116 }
117
118 @Override
119 public OrderedMapIterator<K, V> mapIterator() {
120 final OrderedMapIterator<K, V> it = decorated().mapIterator();
121 return UnmodifiableOrderedMapIterator.unmodifiableOrderedMapIterator(it);
122 }
123
124 /**
125 * Always throws {@link UnsupportedOperationException}.
126 *
127 * @param key Ignored.
128 * @param value Ignored.
129 * @throws UnsupportedOperationException Always thrown.
130 */
131 @Override
132 public V put(final K key, final V value) {
133 throw new UnsupportedOperationException();
134 }
135
136 /**
137 * Always throws {@link UnsupportedOperationException}.
138 *
139 * @param mapToCopy Ignored.
140 * @throws UnsupportedOperationException Always thrown.
141 */
142 @Override
143 public void putAll(final Map<? extends K, ? extends V> mapToCopy) {
144 throw new UnsupportedOperationException();
145 }
146
147 /**
148 * Always throws {@link UnsupportedOperationException}.
149 *
150 * @param key Ignored.
151 * @throws UnsupportedOperationException Always thrown.
152 */
153 @Override
154 public V remove(final Object key) {
155 throw new UnsupportedOperationException();
156 }
157
158 /**
159 * Always throws {@link UnsupportedOperationException}.
160 *
161 * @param value Ignored.
162 * @throws UnsupportedOperationException Always thrown.
163 */
164 @Override
165 public K removeValue(final Object value) {
166 throw new UnsupportedOperationException();
167 }
168
169 @Override
170 public Set<V> values() {
171 return UnmodifiableSet.unmodifiableSet(super.values());
172 }
173
174 }