001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.collections4.collection; 018 019import java.util.Collection; 020import java.util.Iterator; 021import java.util.function.Predicate; 022 023import org.apache.commons.collections4.BoundedCollection; 024import org.apache.commons.collections4.Unmodifiable; 025import org.apache.commons.collections4.iterators.UnmodifiableIterator; 026 027/** 028 * {@link UnmodifiableBoundedCollection} decorates another 029 * {@link BoundedCollection} to ensure it can't be altered. 030 * <p> 031 * If a BoundedCollection is first wrapped in some other collection decorator, 032 * such as synchronized or predicated, the BoundedCollection methods are no 033 * longer accessible. 034 * The factory on this class will attempt to retrieve the bounded nature by 035 * examining the package scope variables. 036 * </p> 037 * <p> 038 * This class is Serializable from Commons Collections 3.1. 039 * </p> 040 * <p> 041 * Attempts to modify it will result in an UnsupportedOperationException. 042 * </p> 043 * 044 * @param <E> the type of elements in this collection 045 * @since 3.0 046 */ 047public final class UnmodifiableBoundedCollection<E> extends AbstractCollectionDecorator<E> 048 implements BoundedCollection<E>, Unmodifiable { 049 050 /** Serialization version */ 051 private static final long serialVersionUID = -7112672385450340330L; 052 053 /** 054 * Factory method to create an unmodifiable bounded collection. 055 * 056 * @param <E> the type of the elements in the collection 057 * @param coll the <code>BoundedCollection</code> to decorate, must not be null 058 * @return a new unmodifiable bounded collection 059 * @throws NullPointerException if {@code coll} is {@code null} 060 * @since 4.0 061 */ 062 public static <E> BoundedCollection<E> unmodifiableBoundedCollection(final BoundedCollection<? extends E> coll) { 063 if (coll instanceof Unmodifiable) { 064 @SuppressWarnings("unchecked") // safe to upcast 065 final BoundedCollection<E> tmpColl = (BoundedCollection<E>) coll; 066 return tmpColl; 067 } 068 return new UnmodifiableBoundedCollection<>(coll); 069 } 070 071 /** 072 * Factory method to create an unmodifiable bounded collection. 073 * <p> 074 * This method is capable of drilling down through up to 1000 other decorators 075 * to find a suitable BoundedCollection. 076 * 077 * @param <E> the type of the elements in the collection 078 * @param coll the <code>BoundedCollection</code> to decorate, must not be null 079 * @return a new unmodifiable bounded collection 080 * @throws NullPointerException if coll is null 081 * @throws IllegalArgumentException if coll is not a {@code BoundedCollection} 082 * @since 4.0 083 */ 084 @SuppressWarnings("unchecked") 085 public static <E> BoundedCollection<E> unmodifiableBoundedCollection(Collection<? extends E> coll) { 086 if (coll == null) { 087 throw new NullPointerException("Collection must not be null."); 088 } 089 090 // handle decorators 091 for (int i = 0; i < 1000; i++) { // counter to prevent infinite looping 092 if (coll instanceof BoundedCollection) { 093 break; // normal loop exit 094 } 095 if (coll instanceof AbstractCollectionDecorator) { 096 coll = ((AbstractCollectionDecorator<E>) coll).decorated(); 097 } else if (coll instanceof SynchronizedCollection) { 098 coll = ((SynchronizedCollection<E>) coll).decorated(); 099 } 100 } 101 102 if (coll instanceof BoundedCollection == false) { 103 throw new IllegalArgumentException("Collection is not a bounded collection."); 104 } 105 return new UnmodifiableBoundedCollection<>((BoundedCollection<E>) coll); 106 } 107 108 /** 109 * Constructor that wraps (not copies). 110 * 111 * @param coll the collection to decorate, must not be null 112 * @throws NullPointerException if coll is null 113 */ 114 @SuppressWarnings("unchecked") // safe to upcast 115 private UnmodifiableBoundedCollection(final BoundedCollection<? extends E> coll) { 116 super((BoundedCollection<E>) coll); 117 } 118 119 //----------------------------------------------------------------------- 120 @Override 121 public Iterator<E> iterator() { 122 return UnmodifiableIterator.unmodifiableIterator(decorated().iterator()); 123 } 124 125 @Override 126 public boolean add(final E object) { 127 throw new UnsupportedOperationException(); 128 } 129 130 @Override 131 public boolean addAll(final Collection<? extends E> coll) { 132 throw new UnsupportedOperationException(); 133 } 134 135 @Override 136 public void clear() { 137 throw new UnsupportedOperationException(); 138 } 139 140 @Override 141 public boolean remove(final Object object) { 142 throw new UnsupportedOperationException(); 143 } 144 145 /** 146 * @since 4.4 147 */ 148 @Override 149 public boolean removeIf(final Predicate<? super E> filter) { 150 throw new UnsupportedOperationException(); 151 } 152 153 @Override 154 public boolean removeAll(final Collection<?> coll) { 155 throw new UnsupportedOperationException(); 156 } 157 158 @Override 159 public boolean retainAll(final Collection<?> coll) { 160 throw new UnsupportedOperationException(); 161 } 162 163 //----------------------------------------------------------------------- 164 @Override 165 public boolean isFull() { 166 return decorated().isFull(); 167 } 168 169 @Override 170 public int maxSize() { 171 return decorated().maxSize(); 172 } 173 174 @Override 175 protected BoundedCollection<E> decorated() { 176 return (BoundedCollection<E>) super.decorated(); 177 } 178}