001/*-------------------------------------------------------------------------+
002|                                                                          |
003
004| Copyright 2005-2011 The ConQAT Project                                   |
005|                                                                          |
006| Licensed under the Apache License, Version 2.0 (the "License");          |
007| you may not use this file except in compliance with the License.         |
008| You may obtain a copy of the License at                                  |
009|                                                                          |
010|    http://www.apache.org/licenses/LICENSE-2.0                            |
011|                                                                          |
012| Unless required by applicable law or agreed to in writing, software      |
013| distributed under the License is distributed on an "AS IS" BASIS,        |
014| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
015| See the License for the specific language governing permissions and      |
016| limitations under the License.                                           |
017+-------------------------------------------------------------------------*/
018package org.conqat.lib.commons.collections;
019
020import java.io.Serializable;
021import java.util.Collection;
022import java.util.Collections;
023
024/**
025 * This is a wrapper for a {@link Collection} prohibiting all calls which would
026 * modify its contents. As the construction of this class is performed in
027 * constant time it is preferred over copying the collection (which takes linear
028 * time). Using this class is also preferred to using the
029 * <code>unmodifiableX()</code> in class {@link Collections} as they return the
030 * collection base type that does not signal, that the object is unmodifiable.
031 * Using the classes in this package makes unmodifiability more explicit.
032 * <p>
033 * All prohibited methods throw an {@link UnsupportedOperationException}. The
034 * class is nearly the same as the one returned by
035 * {@link Collections#unmodifiableCollection(Collection)}, but by making it a
036 * public class we can make the return value of some methods more explicit.
037 * <p>
038 * This collection is serializable if the wrapped collection is serializable.
039 */
040public class UnmodifiableCollection<E> implements Collection<E>, Serializable {
041
042        /** Version used for serialization. */
043        private static final long serialVersionUID = 1;
044
045        /** The underlying collection. */
046        private final Collection<E> c;
047
048        /**
049         * Creates a new unmodifiable collection from another collection. All
050         * modifications to the underlying collection will directly be visible in this
051         * wrapper.
052         */
053        public UnmodifiableCollection(Collection<E> c) {
054                if (c == null) {
055                        throw new IllegalArgumentException("Underlying collection may not be null!");
056                }
057                this.c = c;
058        }
059
060        /** {@inheritDoc} */
061        @Override
062        public boolean isEmpty() {
063                return c.isEmpty();
064        }
065
066        /** {@inheritDoc} */
067        @Override
068        public int size() {
069                return c.size();
070        }
071
072        /** {@inheritDoc} */
073        @Override
074        public boolean contains(Object o) {
075                return c.contains(o);
076        }
077
078        /** {@inheritDoc} */
079        @Override
080        public boolean containsAll(Collection<?> other) {
081                return c.containsAll(other);
082        }
083
084        /** {@inheritDoc} */
085        @Override
086        public UnmodifiableIterator<E> iterator() {
087                return new UnmodifiableIterator<E>(c.iterator());
088        }
089
090        /** {@inheritDoc} */
091        @Override
092        public Object[] toArray() {
093                return c.toArray();
094        }
095
096        /** {@inheritDoc} */
097        @Override
098        public <T> T[] toArray(T[] a) {
099                return c.toArray(a);
100        }
101
102        /** Operation is not supported. */
103        @Override
104        public boolean add(E arg0) {
105                throw new UnsupportedOperationException();
106        }
107
108        /** Operation is not supported. */
109        @Override
110        public boolean addAll(Collection<? extends E> arg0) {
111                throw new UnsupportedOperationException();
112        }
113
114        /** Operation is not supported. */
115        @Override
116        public void clear() {
117                throw new UnsupportedOperationException();
118        }
119
120        /** Operation is not supported. */
121        @Override
122        public boolean remove(Object arg0) {
123                throw new UnsupportedOperationException();
124        }
125
126        /** Operation is not supported. */
127        @Override
128        public boolean removeAll(Collection<?> arg0) {
129                throw new UnsupportedOperationException();
130        }
131
132        /** Operation is not supported. */
133        @Override
134        public boolean retainAll(Collection<?> arg0) {
135                throw new UnsupportedOperationException();
136        }
137
138        /**
139         * Returns a string representation of this collection.
140         */
141        @Override
142        public String toString() {
143                return c.toString();
144        }
145
146        /** {@inheritDoc} */
147        @Override
148        public boolean equals(Object obj) {
149                if (this == obj) {
150                        return true;
151                }
152                if (obj instanceof UnmodifiableCollection<?>) {
153                        return c.equals(((UnmodifiableCollection<?>) obj).c);
154                }
155                return c.equals(obj);
156        }
157
158        /** {@inheritDoc} */
159        @Override
160        public int hashCode() {
161                return c.hashCode();
162        }
163}