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.map;
18
19 import java.io.IOException;
20 import java.io.ObjectInputStream;
21 import java.io.ObjectOutputStream;
22 import java.io.Serializable;
23 import java.util.Collection;
24 import java.util.Map;
25 import java.util.Set;
26
27 import org.apache.commons.collections4.OrderedMap;
28 import org.apache.commons.collections4.OrderedMapIterator;
29 import org.apache.commons.collections4.Unmodifiable;
30 import org.apache.commons.collections4.collection.UnmodifiableCollection;
31 import org.apache.commons.collections4.iterators.UnmodifiableOrderedMapIterator;
32 import org.apache.commons.collections4.set.UnmodifiableSet;
33
34 /**
35 * Decorates another {@code OrderedMap} to ensure it can't be altered.
36 * <p>
37 * This class is Serializable from Commons Collections 3.1.
38 * </p>
39 * <p>
40 * Attempts to modify it will result in an UnsupportedOperationException.
41 * </p>
42 *
43 * @param <K> The type of the keys in this map
44 * @param <V> The type of the values in this map
45 * @since 3.0
46 */
47 public final class UnmodifiableOrderedMap<K, V> extends AbstractOrderedMapDecorator<K, V> implements
48 Unmodifiable, Serializable {
49
50 /** Serialization version */
51 private static final long serialVersionUID = 8136428161720526266L;
52
53 /**
54 * Factory method to create an unmodifiable sorted map.
55 *
56 * @param <K> the key type
57 * @param <V> the value type
58 * @param map The map to decorate, must not be null
59 * @return A new ordered map
60 * @throws NullPointerException if map is null
61 * @since 4.0
62 */
63 public static <K, V> OrderedMap<K, V> unmodifiableOrderedMap(final OrderedMap<? extends K, ? extends V> map) {
64 if (map instanceof Unmodifiable) {
65 @SuppressWarnings("unchecked") // safe to upcast
66 final OrderedMap<K, V> tmpMap = (OrderedMap<K, V>) map;
67 return tmpMap;
68 }
69 return new UnmodifiableOrderedMap<>(map);
70 }
71
72 /**
73 * Constructor that wraps (not copies).
74 *
75 * @param map The map to decorate, must not be null
76 * @throws NullPointerException if map is null
77 */
78 @SuppressWarnings("unchecked") // safe to upcast
79 private UnmodifiableOrderedMap(final OrderedMap<? extends K, ? extends V> map) {
80 super((OrderedMap<K, V>) map);
81 }
82
83 /**
84 * Always throws {@link UnsupportedOperationException}.
85 *
86 * @throws UnsupportedOperationException Always thrown.
87 */
88 @Override
89 public void clear() {
90 throw new UnsupportedOperationException();
91 }
92
93 @Override
94 public Set<Map.Entry<K, V>> entrySet() {
95 return UnmodifiableEntrySet.unmodifiableEntrySet(super.entrySet());
96 }
97
98 @Override
99 public Set<K> keySet() {
100 return UnmodifiableSet.unmodifiableSet(super.keySet());
101 }
102
103 @Override
104 public OrderedMapIterator<K, V> mapIterator() {
105 final OrderedMapIterator<K, V> it = decorated().mapIterator();
106 return UnmodifiableOrderedMapIterator.unmodifiableOrderedMapIterator(it);
107 }
108
109 /**
110 * Always throws {@link UnsupportedOperationException}.
111 *
112 * @param key Ignored.
113 * @param value Ignored.
114 * @throws UnsupportedOperationException Always thrown.
115 */
116 @Override
117 public V put(final K key, final V value) {
118 throw new UnsupportedOperationException();
119 }
120
121 /**
122 * Always throws {@link UnsupportedOperationException}.
123 *
124 * @param mapToCopy Ignored.
125 * @throws UnsupportedOperationException Always thrown.
126 */
127 @Override
128 public void putAll(final Map<? extends K, ? extends V> mapToCopy) {
129 throw new UnsupportedOperationException();
130 }
131
132 /**
133 * Deseializes the map in using a custom routine.
134 *
135 * @param in The input stream
136 * @throws IOException Thrown if an error occurs while reading from the stream
137 * @throws ClassNotFoundException if an object read from the stream cannot be loaded
138 * @since 3.1
139 */
140 @SuppressWarnings("unchecked") // (1) should only fail if input stream is incorrect
141 private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
142 in.defaultReadObject();
143 map = (Map<K, V>) in.readObject(); // (1)
144 }
145
146 /**
147 * Always throws {@link UnsupportedOperationException}.
148 *
149 * @param key Ignored.
150 * @throws UnsupportedOperationException Always thrown.
151 */
152 @Override
153 public V remove(final Object key) {
154 throw new UnsupportedOperationException();
155 }
156
157 @Override
158 public Collection<V> values() {
159 return UnmodifiableCollection.unmodifiableCollection(super.values());
160 }
161
162 /**
163 * Serializes this object to an ObjectOutputStream.
164 *
165 * @param out The target ObjectOutputStream.
166 * @throws IOException thrown when an I/O errors occur writing to the target stream.
167 * @since 3.1
168 */
169 private void writeObject(final ObjectOutputStream out) throws IOException {
170 out.defaultWriteObject();
171 out.writeObject(map);
172 }
173
174 }