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.io.Serializable;
020import java.util.Collection;
021import java.util.Iterator;
022
023/**
024 * Decorates another <code>Collection</code> to provide additional behaviour.
025 * <p>
026 * Each method call made on this <code>Collection</code> is forwarded to the
027 * decorated <code>Collection</code>. This class is used as a framework on which
028 * to build to extensions such as synchronized and unmodifiable behaviour. The
029 * main advantage of decoration is that one decorator can wrap any implementation
030 * of <code>Collection</code>, whereas sub-classing requires a new class to be
031 * written for each implementation.
032 * <p>
033 * This implementation does not perform any special processing with
034 * {@link #iterator()}. Instead it simply returns the value from the
035 * wrapped collection. This may be undesirable, for example if you are trying
036 * to write an unmodifiable implementation it might provide a loophole.
037 *
038 * @param <E> the type of the elements in the collection
039 * @since 3.0
040 * @version $Id: AbstractCollectionDecorator.html 887892 2013-11-24 13:43:45Z tn $
041 */
042public abstract class AbstractCollectionDecorator<E>
043        implements Collection<E>, Serializable {
044
045    /** Serialization version */
046    private static final long serialVersionUID = 6249888059822088500L;
047
048    /** The collection being decorated */
049    private Collection<E> collection;
050
051    /**
052     * Constructor only used in deserialization, do not use otherwise.
053     * @since 3.1
054     */
055    protected AbstractCollectionDecorator() {
056        super();
057    }
058
059    /**
060     * Constructor that wraps (not copies).
061     *
062     * @param coll  the collection to decorate, must not be null
063     * @throws IllegalArgumentException if the collection is null
064     */
065    protected AbstractCollectionDecorator(final Collection<E> coll) {
066        if (coll == null) {
067            throw new IllegalArgumentException("Collection must not be null");
068        }
069        this.collection = coll;
070    }
071
072    /**
073     * Gets the collection being decorated.
074     * All access to the decorated collection goes via this method.
075     *
076     * @return the decorated collection
077     */
078    protected Collection<E> decorated() {
079        return collection;
080    }
081
082    /**
083     * Sets the collection being decorated.
084     * <p>
085     * <b>NOTE:</b> this method should only be used during deserialization
086     *
087     * @param coll  the decorated collection
088     */
089    protected void setCollection(final Collection<E> coll) {
090        this.collection = coll;
091    }
092
093    //-----------------------------------------------------------------------
094
095    public boolean add(final E object) {
096        return decorated().add(object);
097    }
098
099    public boolean addAll(final Collection<? extends E> coll) {
100        return decorated().addAll(coll);
101    }
102
103    public void clear() {
104        decorated().clear();
105    }
106
107    public boolean contains(final Object object) {
108        return decorated().contains(object);
109    }
110
111    public boolean isEmpty() {
112        return decorated().isEmpty();
113    }
114
115    public Iterator<E> iterator() {
116        return decorated().iterator();
117    }
118
119    public boolean remove(final Object object) {
120        return decorated().remove(object);
121    }
122
123    public int size() {
124        return decorated().size();
125    }
126
127    public Object[] toArray() {
128        return decorated().toArray();
129    }
130
131    public <T> T[] toArray(final T[] object) {
132        return decorated().toArray(object);
133    }
134
135    public boolean containsAll(final Collection<?> coll) {
136        return decorated().containsAll(coll);
137    }
138
139    public boolean removeAll(final Collection<?> coll) {
140        return decorated().removeAll(coll);
141    }
142
143    public boolean retainAll(final Collection<?> coll) {
144        return decorated().retainAll(coll);
145    }
146
147    @Override
148    public boolean equals(final Object object) {
149        return object == this || decorated().equals(object);
150    }
151
152    @Override
153    public int hashCode() {
154        return decorated().hashCode();
155    }
156
157    @Override
158    public String toString() {
159        return decorated().toString();
160    }
161
162}