UnmodifiableBoundedCollection.java

  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.collections4.collection;

  18. import java.util.Collection;
  19. import java.util.Iterator;
  20. import java.util.Objects;
  21. import java.util.function.Predicate;

  22. import org.apache.commons.collections4.BoundedCollection;
  23. import org.apache.commons.collections4.Unmodifiable;
  24. import org.apache.commons.collections4.iterators.UnmodifiableIterator;

  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.  * <p>
  36.  * This class is Serializable from Commons Collections 3.1.
  37.  * </p>
  38.  * <p>
  39.  * Attempts to modify it will result in an UnsupportedOperationException.
  40.  * </p>
  41.  *
  42.  * @param <E> the type of elements in this collection
  43.  * @since 3.0
  44.  */
  45. public final class UnmodifiableBoundedCollection<E> extends AbstractCollectionDecorator<E>
  46.         implements BoundedCollection<E>, Unmodifiable {

  47.     /** Serialization version */
  48.     private static final long serialVersionUID = -7112672385450340330L;

  49.     /**
  50.      * Factory method to create an unmodifiable bounded collection.
  51.      *
  52.      * @param <E> the type of the elements in the collection
  53.      * @param coll  the {@code BoundedCollection} to decorate, must not be null
  54.      * @return a new unmodifiable bounded collection
  55.      * @throws NullPointerException if {@code coll} is {@code null}
  56.      * @since 4.0
  57.      */
  58.     public static <E> BoundedCollection<E> unmodifiableBoundedCollection(final BoundedCollection<? extends E> coll) {
  59.         if (coll instanceof Unmodifiable) {
  60.             @SuppressWarnings("unchecked") // safe to upcast
  61.             final BoundedCollection<E> tmpColl = (BoundedCollection<E>) coll;
  62.             return tmpColl;
  63.         }
  64.         return new UnmodifiableBoundedCollection<>(coll);
  65.     }

  66.     /**
  67.      * Factory method to create an unmodifiable bounded collection.
  68.      * <p>
  69.      * This method is capable of drilling down through up to 1000 other decorators
  70.      * to find a suitable BoundedCollection.
  71.      *
  72.      * @param <E> the type of the elements in the collection
  73.      * @param collection  the {@code BoundedCollection} to decorate, must not be null
  74.      * @return a new unmodifiable bounded collection
  75.      * @throws NullPointerException if coll is null
  76.      * @throws IllegalArgumentException if coll is not a {@code BoundedCollection}
  77.      * @since 4.0
  78.      */
  79.     @SuppressWarnings("unchecked")
  80.     public static <E> BoundedCollection<E> unmodifiableBoundedCollection(Collection<? extends E> collection) {
  81.         Objects.requireNonNull(collection, "collection");

  82.         // handle decorators
  83.         for (int i = 0; i < 1000; i++) {  // counter to prevent infinite looping
  84.             if (collection instanceof BoundedCollection) {
  85.                 break;  // normal loop exit
  86.             }
  87.             if (collection instanceof AbstractCollectionDecorator) {
  88.                 collection = ((AbstractCollectionDecorator<E>) collection).decorated();
  89.             } else if (collection instanceof SynchronizedCollection) {
  90.                 collection = ((SynchronizedCollection<E>) collection).decorated();
  91.             }
  92.         }

  93.         if (!(collection instanceof BoundedCollection)) {
  94.             throw new IllegalArgumentException("Collection is not a bounded collection.");
  95.         }
  96.         return new UnmodifiableBoundedCollection<>((BoundedCollection<E>) collection);
  97.     }

  98.     /**
  99.      * Constructor that wraps (not copies).
  100.      *
  101.      * @param coll  the collection to decorate, must not be null
  102.      * @throws NullPointerException if coll is null
  103.      */
  104.     @SuppressWarnings("unchecked") // safe to upcast
  105.     private UnmodifiableBoundedCollection(final BoundedCollection<? extends E> coll) {
  106.         super((BoundedCollection<E>) coll);
  107.     }

  108.     @Override
  109.     public boolean add(final E object) {
  110.         throw new UnsupportedOperationException();
  111.     }

  112.     @Override
  113.     public boolean addAll(final Collection<? extends E> coll) {
  114.         throw new UnsupportedOperationException();
  115.     }

  116.     @Override
  117.     public void clear() {
  118.         throw new UnsupportedOperationException();
  119.     }

  120.     @Override
  121.     protected BoundedCollection<E> decorated() {
  122.         return (BoundedCollection<E>) super.decorated();
  123.     }

  124.     @Override
  125.     public boolean isFull() {
  126.         return decorated().isFull();
  127.     }

  128.     @Override
  129.     public Iterator<E> iterator() {
  130.         return UnmodifiableIterator.unmodifiableIterator(decorated().iterator());
  131.     }

  132.     @Override
  133.     public int maxSize() {
  134.         return decorated().maxSize();
  135.     }

  136.     @Override
  137.     public boolean remove(final Object object) {
  138.         throw new UnsupportedOperationException();
  139.     }

  140.     @Override
  141.     public boolean removeAll(final Collection<?> coll) {
  142.         throw new UnsupportedOperationException();
  143.     }

  144.     /**
  145.      * @since 4.4
  146.      */
  147.     @Override
  148.     public boolean removeIf(final Predicate<? super E> filter) {
  149.         throw new UnsupportedOperationException();
  150.     }

  151.     @Override
  152.     public boolean retainAll(final Collection<?> coll) {
  153.         throw new UnsupportedOperationException();
  154.     }
  155. }