001: //This file is part of the prose package.
002: //
003: // The contents of this file are subject to the Mozilla Public License
004: // Version 1.1 (the "License"); you may not use this file except in
005: // compliance with the License. You may obtain a copy of the License at
006: // http://www.mozilla.org/MPL/
007: //
008: // Software distributed under the License is distributed on an "AS IS" basis,
009: // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
010: // for the specific language governing rights and limitations under the
011: // License.
012: //
013: // The Original Code is prose.
014: //
015: // The Initial Developers of the Original Code are Angela Nicoara and Gerald Linhofer.
016: // All Rights Reserved.
017: //
018: // Contributor(s):
019: // $Id$
020: // =====================================================================
021: //
022: // (history at end)
023: //
024:
025: package ch.ethz.prose;
026:
027: import java.util.Collection;
028: import java.util.HashSet;
029: import java.util.Iterator;
030: import java.util.Set;
031: import java.lang.ref.WeakReference;
032:
033: /**
034: * Wrapper for a <CODE>Set</CODE> using weak references
035: * to store values. The refered objects may be garbage
036: * collected...
037: *
038: * @see java.util.Set
039: * @see java.lang.ref.WeakReference
040: *
041: * @version $Revision$
042: * @author Angela Nicoara
043: * @author Gerald Linhofer
044: */
045: public class WeakSet implements Set {
046:
047: /// The wrapped <CODE>Set</CODE>.
048: private Set realSet;
049:
050: /**
051: * Default constructor uses a <CODE>HashSet</CODE>
052: * as set implementation.
053: *
054: */
055: public WeakSet() {
056: realSet = new HashSet();
057: }
058:
059: /**
060: * Constructor, which allows to pass the set implementation
061: * as parameter. The passed set may not be null and has to be
062: * empty.
063: *
064: * @param baseSet an empty set that will be used internal as
065: * set implementation.
066: */
067: public WeakSet(Set baseSet) {
068: if (!baseSet.isEmpty())
069: throw new RuntimeException(this .getClass().getName()
070: + " must be initialized with an empty Set");
071:
072: realSet = baseSet;
073: }
074:
075: //
076: // *** Forwarding methods *********************************
077: //
078:
079: /* Returns the size of the set.
080: * @see java.util.Set#size()
081: */
082: public int size() {
083: return realSet.size();
084: }
085:
086: /* (non-Javadoc)
087: * @see java.util.Set#isEmpty()
088: */
089: public boolean isEmpty() {
090: return realSet.isEmpty();
091: }
092:
093: /* (non-Javadoc)
094: * @see java.util.Set#contains(java.lang.Object)
095: */
096: public boolean contains(Object o) {
097: WeakReference wr = new WeakReference(o);
098: return realSet.contains(wr);
099: }
100:
101: /**
102: * Returns an iterator over the elements in this set.
103: * The elements are returned in no particular order
104: * (unless this set uses an instance of some class that
105: * provides a guarantee).
106: *
107: * @return an iterator over the elements in this set.
108: *
109: * @see java.util.Set#iterator()
110: */
111: public Iterator iterator() {
112: return new Iterator() {
113: private Iterator realIter = realSet.iterator();
114:
115: public boolean hasNext() {
116: return realIter.hasNext();
117: }
118:
119: public Object next() {
120: WeakReference wr = (WeakReference) realIter.next();
121: return wr.get();
122: }
123:
124: public void remove() {
125: throw new UnsupportedOperationException();
126: }
127: };
128: }
129:
130: /* (non-Javadoc)
131: * @see java.util.Set#toArray()
132: */
133: public Object[] toArray() {
134: int i = 0;
135: Object[] retval = new Object[realSet.size()];
136:
137: for (Iterator iter = iterator(); iter.hasNext(); retval[i++] = iter
138: .next()) {
139: }
140:
141: return retval;
142: }
143:
144: /* (non-Javadoc)
145: * @see java.util.Set#toArray(T[])
146: */
147: public Object[] toArray(Object[] a) {
148: int i = 0;
149:
150: for (Iterator iter = iterator(); iter.hasNext(); a[i++] = iter
151: .next()) {
152: }
153:
154: return a;
155: }
156:
157: /**
158: * Adds the specified element to this set if it is not
159: * already present (optional operation). More formally,
160: * adds the specified element, o, to this set if this
161: * set contains no element e such that (o==null ? e==null
162: * : o.equals(e)). If this set already contains the
163: * specified element, the call leaves this set unchanged
164: * and returns false. In combination with the restriction
165: * on constructors, this ensures that sets never contain
166: * duplicate elements.
167: *
168: * @see java.util.Set#add
169: */
170: public boolean add(Object o) {
171: WeakReference wr = new WeakReference(o);
172: return realSet.add(wr);
173: }
174:
175: /**
176: * Removes the specified element from this set if it is
177: * present (optional operation). More formally, removes
178: * an element e such that (o==null ? e==null : o.equals(e)),
179: * if the set contains such an element. Returns true if
180: * the set contained the specified element (or equivalently,
181: * if the set changed as a result of the call). (The set
182: * will not contain the specified element once the call
183: * returns.)
184: *
185: * @param o - object to be removed from this set, if present.
186: * @return <CODE>true</CODE> if the set contained the specified
187: * element.
188: *
189: * @throws ClassCastException if the type of the specified
190: * element is incompatible with this set (optional).
191: * @throws NullPointerException if the specified element is
192: * null and this set does not support null elements (optional).
193: * @throws UnsupportedOperationException if the remove method
194: * is not supported by the underlying set.
195: *
196: * @see java.util.Set#remove(java.lang.Object)
197: */
198: public boolean remove(Object o) {
199: WeakReference wr = new WeakReference(o);
200: return realSet.remove(wr);
201: }
202:
203: /**
204: * Returns true if this set contains all of the elements
205: * of the specified collection. If the specified collection
206: * is also a set, this method returns true if it is a
207: * subset of this set.
208: *
209: * @param c collection to be checked for containment in this set.
210: * @return <CODE>true</CODE> if this set contains all of the
211: * elements of the specified collection.
212: *
213: * @throws ClassCastException if the types of one or more elements
214: * in the specified collection are incompatible with this
215: * set (optional).
216: * @throws NullPointerException if the specified collection contains
217: * one or more null elements and this set does not support
218: * null elements (optional). Or if the specified collection
219: * is null.
220: *
221: * @see java.util.Set#containsAll(java.util.Collection)
222: */
223: public boolean containsAll(Collection c) {
224: boolean retval = true;
225:
226: for (Iterator iter = c.iterator(); iter.hasNext(); retval = retval
227: && contains(iter.next())) {
228: }
229:
230: return retval;
231: }
232:
233: /**
234: * Adds all of the elements in the specified collection
235: * to this set if they're not already present.
236: *
237: * @param c Adds all of the elements in the specified
238: * collection to this set if they're not
239: * already present
240: * @return <CODE>true</CODE> if this set was changed during operation
241: *
242: * @throws ClassCastException if the class of some element of the specified collection prevents it from being added to this set.
243: * @throws NullPointerException if the specified collection contains one or more null elements and this set does not support null elements, or if the specified collection is null.
244: * @throws IllegalArgumentException if some aspect of some element of the specified collection prevents it from being added to this set.
245: *
246: * @see java.util.Set#addAll(java.util.Collection)
247: */
248: public boolean addAll(Collection c) {
249: boolean retval = false;
250:
251: for (Iterator iter = c.iterator(); iter.hasNext(); retval = retval
252: || add(iter.next())) {
253: }
254:
255: return retval;
256: }
257:
258: /**
259: * Not implemented.
260: *
261: * @see java.util.Set#retainAll(java.util.Collection)
262: */
263: public boolean retainAll(Collection c) {
264: throw new UnsupportedOperationException();
265: }
266:
267: /** Not implemented.
268: *
269: * @see java.util.Set#removeAll(java.util.Collection)
270: */
271: public boolean removeAll(Collection c) {
272: throw new UnsupportedOperationException();
273: }
274:
275: /* (non-Javadoc)
276: * @see java.util.Set#clear()
277: */
278: public void clear() {
279: realSet.clear();
280: }
281:
282: /**
283: * WeakReference implementation for WeakSet
284: * @author Gerald Linhofer
285: *
286: */
287: private class SetReference extends WeakReference {
288: SetReference(Object o) {
289: super (o);
290: }
291:
292: public void clear() {
293: super .clear();
294: realSet.remove(this );
295: }
296: }
297: }
298:
299: //======================================================================
300: //
301: // $Log$
302: //
|