View Javadoc
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.multiset;
18  
19  import java.io.IOException;
20  import java.io.ObjectInputStream;
21  import java.io.ObjectOutputStream;
22  import java.util.Collection;
23  import java.util.Iterator;
24  import java.util.Set;
25  import java.util.function.Predicate;
26  
27  import org.apache.commons.collections4.MultiSet;
28  import org.apache.commons.collections4.Unmodifiable;
29  import org.apache.commons.collections4.iterators.UnmodifiableIterator;
30  import org.apache.commons.collections4.set.UnmodifiableSet;
31  
32  /**
33   * Decorates another {@link MultiSet} to ensure it can't be altered.
34   * <p>
35   * Attempts to modify it will result in an UnsupportedOperationException.
36   * </p>
37   *
38   * @param <E> The type held in the multiset
39   * @since 4.1
40   */
41  public final class UnmodifiableMultiSet<E>
42          extends AbstractMultiSetDecorator<E> implements Unmodifiable {
43  
44      /** Serialization version */
45      private static final long serialVersionUID = 20150611L;
46  
47      /**
48       * Factory method to create an unmodifiable multiset.
49       * <p>
50       * If the multiset passed in is already unmodifiable, it is returned.
51       * </p>
52       *
53       * @param <E>  the type of the elements in the multiset
54       * @param multiset  The multiset to decorate, may not be null
55       * @return An unmodifiable MultiSet
56       * @throws NullPointerException if multiset is null
57       */
58      public static <E> MultiSet<E> unmodifiableMultiSet(final MultiSet<? extends E> multiset) {
59          if (multiset instanceof Unmodifiable) {
60              @SuppressWarnings("unchecked") // safe to upcast
61              final MultiSet<E> tmpMultiSet = (MultiSet<E>) multiset;
62              return tmpMultiSet;
63          }
64          return new UnmodifiableMultiSet<>(multiset);
65      }
66  
67      /**
68       * Constructor that wraps (not copies).
69       *
70       * @param multiset  The multiset to decorate, may not be null
71       * @throws NullPointerException if multiset is null
72       */
73      @SuppressWarnings("unchecked") // safe to upcast
74      private UnmodifiableMultiSet(final MultiSet<? extends E> multiset) {
75          super((MultiSet<E>) multiset);
76      }
77  
78      /**
79       * Always throws {@link UnsupportedOperationException}.
80       *
81       * @param object Ignored.
82       * @throws UnsupportedOperationException Always thrown.
83       */
84      @Override
85      public boolean add(final E object) {
86          throw new UnsupportedOperationException();
87      }
88  
89      /**
90       * Always throws {@link UnsupportedOperationException}.
91       *
92       * @param object Ignored.
93       * @param count Ignored.
94       * @throws UnsupportedOperationException Always thrown.
95       */
96      @Override
97      public int add(final E object, final int count) {
98          throw new UnsupportedOperationException();
99      }
100 
101     /**
102      * Always throws {@link UnsupportedOperationException}.
103      *
104      * @param coll Ignored.
105      * @throws UnsupportedOperationException Always thrown.
106      */
107     @Override
108     public boolean addAll(final Collection<? extends E> coll) {
109         throw new UnsupportedOperationException();
110     }
111 
112     /**
113      * Always throws {@link UnsupportedOperationException}.
114      *
115      * @throws UnsupportedOperationException Always thrown.
116      */
117     @Override
118     public void clear() {
119         throw new UnsupportedOperationException();
120     }
121 
122     @Override
123     public Set<MultiSet.Entry<E>> entrySet() {
124         return UnmodifiableSet.unmodifiableSet(decorated().entrySet());
125     }
126 
127     @Override
128     public Iterator<E> iterator() {
129         return UnmodifiableIterator.<E>unmodifiableIterator(decorated().iterator());
130     }
131 
132     /**
133      * Deserializes the collection 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      * @throws ClassCastException if deserialized object has wrong type
139      */
140     @SuppressWarnings("unchecked") // will throw CCE, see Javadoc
141     private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
142         in.defaultReadObject();
143         setCollection((Collection<E>) in.readObject());
144     }
145 
146     /**
147      * Always throws {@link UnsupportedOperationException}.
148      *
149      * @param object Ignored.
150      * @throws UnsupportedOperationException Always thrown.
151      */
152     @Override
153     public boolean remove(final Object object) {
154         throw new UnsupportedOperationException();
155     }
156 
157     /**
158      * Always throws {@link UnsupportedOperationException}.
159      *
160      * @param object Ignored.
161      * @param count Ignored.
162      * @throws UnsupportedOperationException Always thrown.
163      */
164     @Override
165     public int remove(final Object object, final int count) {
166         throw new UnsupportedOperationException();
167     }
168 
169     /**
170      * Always throws {@link UnsupportedOperationException}.
171      *
172      * @param coll Ignored.
173      * @throws UnsupportedOperationException Always thrown.
174      */
175     @Override
176     public boolean removeAll(final Collection<?> coll) {
177         throw new UnsupportedOperationException();
178     }
179 
180     /**
181      * Always throws {@link UnsupportedOperationException}.
182      *
183      * @param filter Ignored.
184      * @throws UnsupportedOperationException Always thrown.
185      * @since 4.4
186      */
187     @Override
188     public boolean removeIf(final Predicate<? super E> filter) {
189         throw new UnsupportedOperationException();
190     }
191 
192     /**
193      * Always throws {@link UnsupportedOperationException}.
194      *
195      * @param coll Ignored.
196      * @throws UnsupportedOperationException Always thrown.
197      */
198     @Override
199     public boolean retainAll(final Collection<?> coll) {
200         throw new UnsupportedOperationException();
201     }
202 
203     /**
204      * Always throws {@link UnsupportedOperationException}.
205      *
206      * @param object Ignored.
207      * @param count Ignored.
208      * @throws UnsupportedOperationException Always thrown.
209      */
210     @Override
211     public int setCount(final E object, final int count) {
212         throw new UnsupportedOperationException();
213     }
214 
215     @Override
216     public Set<E> uniqueSet() {
217         return UnmodifiableSet.unmodifiableSet(decorated().uniqueSet());
218     }
219 
220     /**
221      * Serializes this object to an ObjectOutputStream.
222      *
223      * @param out The target ObjectOutputStream.
224      * @throws IOException thrown when an I/O errors occur writing to the target stream.
225      */
226     private void writeObject(final ObjectOutputStream out) throws IOException {
227         out.defaultWriteObject();
228         out.writeObject(decorated());
229     }
230 
231 }