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    *      http://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.collections.collection;
18  
19  import java.util.Collection;
20  import java.util.Iterator;
21  
22  import org.apache.commons.collections.BoundedCollection;
23  import org.apache.commons.collections.iterators.UnmodifiableIterator;
24  
25  /**
26   * {@link UnmodifiableBoundedCollection} decorates another
27   * {@link BoundedCollection} to ensure it can't be altered.
28   * <p>
29   * If a BoundedCollection is first wrapped in some other collection decorator,
30   * such as synchronized or predicated, the BoundedCollection methods are no
31   * longer accessible.
32   * The factory on this class will attempt to retrieve the bounded nature by
33   * examining the package scope variables.
34   * <p>
35   * This class is Serializable from Commons Collections 3.1.
36   * <p>
37   * Attempts to modify it will result in an UnsupportedOperationException. 
38   *
39   * @since 3.0
40   * @version $Id: UnmodifiableBoundedCollection.java 1429905 2013-01-07 17:15:14Z ggregory $
41   */
42  public final class UnmodifiableBoundedCollection<E> extends AbstractCollectionDecorator<E>
43          implements BoundedCollection<E> {
44  
45      /** Serialization version */
46      private static final long serialVersionUID = -7112672385450340330L;
47  
48      /**
49       * Factory method to create an unmodifiable bounded collection.
50       *
51       * @param <E> the type of the elements in the collection
52       * @param coll  the <code>BoundedCollection</code> to decorate, must not be null
53       * @return a new unmodifiable bounded collection
54       * @throws IllegalArgumentException if {@code coll} is {@code null}
55       */
56      public static <E> BoundedCollection<E> unmodifiableBoundedCollection(final BoundedCollection<E> coll) {
57          return new UnmodifiableBoundedCollection<E>(coll);
58      }
59  
60      /**
61       * Factory method to create an unmodifiable bounded collection.
62       * <p>
63       * This method is capable of drilling down through up to 1000 other decorators
64       * to find a suitable BoundedCollection.
65       *
66       * @param <E> the type of the elements in the collection
67       * @param coll  the <code>BoundedCollection</code> to decorate, must not be null
68       * @return a new unmodifiable bounded collection
69       * @throws IllegalArgumentException if {@code coll} is {@code null}
70       */
71      @SuppressWarnings("unchecked")
72      public static <E> BoundedCollection<E> unmodifiableBoundedCollection(Collection<? extends E> coll) {
73          if (coll == null) {
74              throw new IllegalArgumentException("The collection must not be null");
75          }
76  
77          // handle decorators
78          for (int i = 0; i < 1000; i++) {  // counter to prevent infinite looping
79              if (coll instanceof BoundedCollection) {
80                  break;  // normal loop exit
81              }
82              if (coll instanceof AbstractCollectionDecorator) {
83                  coll = ((AbstractCollectionDecorator<E>) coll).collection;
84              } else if (coll instanceof SynchronizedCollection) {
85                  coll = ((SynchronizedCollection<E>) coll).collection;
86              }
87          }
88  
89          if (coll instanceof BoundedCollection == false) {
90              throw new IllegalArgumentException("The collection is not a bounded collection");
91          }
92          return new UnmodifiableBoundedCollection<E>((BoundedCollection<E>) coll);
93      }
94  
95      /**
96       * Constructor that wraps (not copies).
97       *
98       * @param coll  the collection to decorate, must not be null
99       * @throws IllegalArgumentException if coll is null
100      */
101     private UnmodifiableBoundedCollection(final BoundedCollection<E> coll) {
102         super(coll);
103     }
104 
105     //-----------------------------------------------------------------------
106     @Override
107     public Iterator<E> iterator() {
108         return UnmodifiableIterator.unmodifiableIterator(decorated().iterator());
109     }
110 
111     @Override
112     public boolean add(final E object) {
113         throw new UnsupportedOperationException();
114     }
115 
116     @Override
117     public boolean addAll(final Collection<? extends E> coll) {
118         throw new UnsupportedOperationException();
119     }
120 
121     @Override
122     public void clear() {
123         throw new UnsupportedOperationException();
124     }
125 
126     @Override
127     public boolean remove(final Object object) {
128         throw new UnsupportedOperationException();
129     }
130 
131     @Override
132     public boolean removeAll(final Collection<?> coll) {
133         throw new UnsupportedOperationException();
134     }
135 
136     @Override
137     public boolean retainAll(final Collection<?> coll) {
138         throw new UnsupportedOperationException();
139     }
140 
141     //-----------------------------------------------------------------------
142     public boolean isFull() {
143         return decorated().isFull();
144     }
145 
146     public int maxSize() {
147         return decorated().maxSize();
148     }
149 
150     @Override
151     protected BoundedCollection<E> decorated() {
152         return (BoundedCollection<E>) super.decorated();
153     }
154 }