001: /*
002: * Copyright 2003-2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.apache.commons.collections.collection;
017:
018: import java.io.Serializable;
019: import java.util.Collection;
020: import java.util.Iterator;
021:
022: /**
023: * Decorates another <code>Collection</code> to synchronize its behaviour
024: * for a multi-threaded environment.
025: * <p>
026: * Iterators must be manually synchronized:
027: * <pre>
028: * synchronized (coll) {
029: * Iterator it = coll.iterator();
030: * // do stuff with iterator
031: * }
032: * </pre>
033: * <p>
034: * This class is Serializable from Commons Collections 3.1.
035: *
036: * @since Commons Collections 3.0
037: * @version $Revision: 155406 $ $Date: 2005-02-26 12:55:26 +0000 (Sat, 26 Feb 2005) $
038: *
039: * @author Stephen Colebourne
040: */
041: public class SynchronizedCollection implements Collection, Serializable {
042:
043: /** Serialization version */
044: private static final long serialVersionUID = 2412805092710877986L;
045:
046: /** The collection to decorate */
047: protected final Collection collection;
048: /** The object to lock on, needed for List/SortedSet views */
049: protected final Object lock;
050:
051: /**
052: * Factory method to create a synchronized collection.
053: *
054: * @param coll the collection to decorate, must not be null
055: * @return a new synchronized collection
056: * @throws IllegalArgumentException if collection is null
057: */
058: public static Collection decorate(Collection coll) {
059: return new SynchronizedCollection(coll);
060: }
061:
062: //-----------------------------------------------------------------------
063: /**
064: * Constructor that wraps (not copies).
065: *
066: * @param collection the collection to decorate, must not be null
067: * @throws IllegalArgumentException if the collection is null
068: */
069: protected SynchronizedCollection(Collection collection) {
070: if (collection == null) {
071: throw new IllegalArgumentException(
072: "Collection must not be null");
073: }
074: this .collection = collection;
075: this .lock = this ;
076: }
077:
078: /**
079: * Constructor that wraps (not copies).
080: *
081: * @param collection the collection to decorate, must not be null
082: * @param lock the lock object to use, must not be null
083: * @throws IllegalArgumentException if the collection is null
084: */
085: protected SynchronizedCollection(Collection collection, Object lock) {
086: if (collection == null) {
087: throw new IllegalArgumentException(
088: "Collection must not be null");
089: }
090: this .collection = collection;
091: this .lock = lock;
092: }
093:
094: //-----------------------------------------------------------------------
095: public boolean add(Object object) {
096: synchronized (lock) {
097: return collection.add(object);
098: }
099: }
100:
101: public boolean addAll(Collection coll) {
102: synchronized (lock) {
103: return collection.addAll(coll);
104: }
105: }
106:
107: public void clear() {
108: synchronized (lock) {
109: collection.clear();
110: }
111: }
112:
113: public boolean contains(Object object) {
114: synchronized (lock) {
115: return collection.contains(object);
116: }
117: }
118:
119: public boolean containsAll(Collection coll) {
120: synchronized (lock) {
121: return collection.containsAll(coll);
122: }
123: }
124:
125: public boolean isEmpty() {
126: synchronized (lock) {
127: return collection.isEmpty();
128: }
129: }
130:
131: /**
132: * Iterators must be manually synchronized.
133: * <pre>
134: * synchronized (coll) {
135: * Iterator it = coll.iterator();
136: * // do stuff with iterator
137: * }
138: *
139: * @return an iterator that must be manually synchronized on the collection
140: */
141: public Iterator iterator() {
142: return collection.iterator();
143: }
144:
145: public Object[] toArray() {
146: synchronized (lock) {
147: return collection.toArray();
148: }
149: }
150:
151: public Object[] toArray(Object[] object) {
152: synchronized (lock) {
153: return collection.toArray(object);
154: }
155: }
156:
157: public boolean remove(Object object) {
158: synchronized (lock) {
159: return collection.remove(object);
160: }
161: }
162:
163: public boolean removeAll(Collection coll) {
164: synchronized (lock) {
165: return collection.removeAll(coll);
166: }
167: }
168:
169: public boolean retainAll(Collection coll) {
170: synchronized (lock) {
171: return collection.retainAll(coll);
172: }
173: }
174:
175: public int size() {
176: synchronized (lock) {
177: return collection.size();
178: }
179: }
180:
181: public boolean equals(Object object) {
182: synchronized (lock) {
183: if (object == this ) {
184: return true;
185: }
186: return collection.equals(object);
187: }
188: }
189:
190: public int hashCode() {
191: synchronized (lock) {
192: return collection.hashCode();
193: }
194: }
195:
196: public String toString() {
197: synchronized (lock) {
198: return collection.toString();
199: }
200: }
201:
202: }
|