001: /*
002: * Copyright 2002-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;
017:
018: import org.apache.commons.collections.bag.HashBag;
019: import org.apache.commons.collections.bag.PredicatedBag;
020: import org.apache.commons.collections.bag.PredicatedSortedBag;
021: import org.apache.commons.collections.bag.SynchronizedBag;
022: import org.apache.commons.collections.bag.SynchronizedSortedBag;
023: import org.apache.commons.collections.bag.TransformedBag;
024: import org.apache.commons.collections.bag.TransformedSortedBag;
025: import org.apache.commons.collections.bag.TreeBag;
026: import org.apache.commons.collections.bag.TypedBag;
027: import org.apache.commons.collections.bag.TypedSortedBag;
028: import org.apache.commons.collections.bag.UnmodifiableBag;
029: import org.apache.commons.collections.bag.UnmodifiableSortedBag;
030:
031: /**
032: * Provides utility methods and decorators for
033: * {@link Bag} and {@link SortedBag} instances.
034: *
035: * @since Commons Collections 2.1
036: * @version $Revision: 155406 $ $Date: 2005-02-26 12:55:26 +0000 (Sat, 26 Feb 2005) $
037: *
038: * @author Paul Jack
039: * @author Stephen Colebourne
040: * @author Andrew Freeman
041: * @author Matthew Hawthorne
042: */
043: public class BagUtils {
044:
045: /**
046: * An empty unmodifiable bag.
047: */
048: public static final Bag EMPTY_BAG = UnmodifiableBag
049: .decorate(new HashBag());
050:
051: /**
052: * An empty unmodifiable sorted bag.
053: */
054: public static final Bag EMPTY_SORTED_BAG = UnmodifiableSortedBag
055: .decorate(new TreeBag());
056:
057: /**
058: * Instantiation of BagUtils is not intended or required.
059: * However, some tools require an instance to operate.
060: */
061: public BagUtils() {
062: }
063:
064: //-----------------------------------------------------------------------
065: /**
066: * Returns a synchronized (thread-safe) bag backed by the given bag.
067: * In order to guarantee serial access, it is critical that all
068: * access to the backing bag is accomplished through the returned bag.
069: * <p>
070: * It is imperative that the user manually synchronize on the returned
071: * bag when iterating over it:
072: *
073: * <pre>
074: * Bag bag = BagUtils.synchronizedBag(new HashBag());
075: * ...
076: * synchronized(bag) {
077: * Iterator i = bag.iterator(); // Must be in synchronized block
078: * while (i.hasNext())
079: * foo(i.next());
080: * }
081: * }
082: * </pre>
083: *
084: * Failure to follow this advice may result in non-deterministic
085: * behavior.
086: *
087: * @param bag the bag to synchronize, must not be null
088: * @return a synchronized bag backed by that bag
089: * @throws IllegalArgumentException if the Bag is null
090: */
091: public static Bag synchronizedBag(Bag bag) {
092: return SynchronizedBag.decorate(bag);
093: }
094:
095: /**
096: * Returns an unmodifiable view of the given bag. Any modification
097: * attempts to the returned bag will raise an
098: * {@link UnsupportedOperationException}.
099: *
100: * @param bag the bag whose unmodifiable view is to be returned, must not be null
101: * @return an unmodifiable view of that bag
102: * @throws IllegalArgumentException if the Bag is null
103: */
104: public static Bag unmodifiableBag(Bag bag) {
105: return UnmodifiableBag.decorate(bag);
106: }
107:
108: /**
109: * Returns a predicated (validating) bag backed by the given bag.
110: * <p>
111: * Only objects that pass the test in the given predicate can be added to the bag.
112: * Trying to add an invalid object results in an IllegalArgumentException.
113: * It is important not to use the original bag after invoking this method,
114: * as it is a backdoor for adding invalid objects.
115: *
116: * @param bag the bag to predicate, must not be null
117: * @param predicate the predicate for the bag, must not be null
118: * @return a predicated bag backed by the given bag
119: * @throws IllegalArgumentException if the Bag or Predicate is null
120: */
121: public static Bag predicatedBag(Bag bag, Predicate predicate) {
122: return PredicatedBag.decorate(bag, predicate);
123: }
124:
125: /**
126: * Returns a typed bag backed by the given bag.
127: * <p>
128: * Only objects of the specified type can be added to the bag.
129: *
130: * @param bag the bag to limit to a specific type, must not be null
131: * @param type the type of objects which may be added to the bag
132: * @return a typed bag backed by the specified bag
133: */
134: public static Bag typedBag(Bag bag, Class type) {
135: return TypedBag.decorate(bag, type);
136: }
137:
138: /**
139: * Returns a transformed bag backed by the given bag.
140: * <p>
141: * Each object is passed through the transformer as it is added to the
142: * Bag. It is important not to use the original bag after invoking this
143: * method, as it is a backdoor for adding untransformed objects.
144: *
145: * @param bag the bag to predicate, must not be null
146: * @param transformer the transformer for the bag, must not be null
147: * @return a transformed bag backed by the given bag
148: * @throws IllegalArgumentException if the Bag or Transformer is null
149: */
150: public static Bag transformedBag(Bag bag, Transformer transformer) {
151: return TransformedBag.decorate(bag, transformer);
152: }
153:
154: //-----------------------------------------------------------------------
155: /**
156: * Returns a synchronized (thread-safe) sorted bag backed by the given
157: * sorted bag.
158: * In order to guarantee serial access, it is critical that all
159: * access to the backing bag is accomplished through the returned bag.
160: * <p>
161: * It is imperative that the user manually synchronize on the returned
162: * bag when iterating over it:
163: *
164: * <pre>
165: * SortedBag bag = BagUtils.synchronizedSortedBag(new TreeBag());
166: * ...
167: * synchronized(bag) {
168: * Iterator i = bag.iterator(); // Must be in synchronized block
169: * while (i.hasNext())
170: * foo(i.next());
171: * }
172: * }
173: * </pre>
174: *
175: * Failure to follow this advice may result in non-deterministic
176: * behavior.
177: *
178: * @param bag the bag to synchronize, must not be null
179: * @return a synchronized bag backed by that bag
180: * @throws IllegalArgumentException if the SortedBag is null
181: */
182: public static SortedBag synchronizedSortedBag(SortedBag bag) {
183: return SynchronizedSortedBag.decorate(bag);
184: }
185:
186: /**
187: * Returns an unmodifiable view of the given sorted bag. Any modification
188: * attempts to the returned bag will raise an
189: * {@link UnsupportedOperationException}.
190: *
191: * @param bag the bag whose unmodifiable view is to be returned, must not be null
192: * @return an unmodifiable view of that bag
193: * @throws IllegalArgumentException if the SortedBag is null
194: */
195: public static SortedBag unmodifiableSortedBag(SortedBag bag) {
196: return UnmodifiableSortedBag.decorate(bag);
197: }
198:
199: /**
200: * Returns a predicated (validating) sorted bag backed by the given sorted bag.
201: * <p>
202: * Only objects that pass the test in the given predicate can be added to the bag.
203: * Trying to add an invalid object results in an IllegalArgumentException.
204: * It is important not to use the original bag after invoking this method,
205: * as it is a backdoor for adding invalid objects.
206: *
207: * @param bag the sorted bag to predicate, must not be null
208: * @param predicate the predicate for the bag, must not be null
209: * @return a predicated bag backed by the given bag
210: * @throws IllegalArgumentException if the SortedBag or Predicate is null
211: */
212: public static SortedBag predicatedSortedBag(SortedBag bag,
213: Predicate predicate) {
214: return PredicatedSortedBag.decorate(bag, predicate);
215: }
216:
217: /**
218: * Returns a typed sorted bag backed by the given bag.
219: * <p>
220: * Only objects of the specified type can be added to the bag.
221: *
222: * @param bag the bag to limit to a specific type, must not be null
223: * @param type the type of objects which may be added to the bag
224: * @return a typed bag backed by the specified bag
225: */
226: public static SortedBag typedSortedBag(SortedBag bag, Class type) {
227: return TypedSortedBag.decorate(bag, type);
228: }
229:
230: /**
231: * Returns a transformed sorted bag backed by the given bag.
232: * <p>
233: * Each object is passed through the transformer as it is added to the
234: * Bag. It is important not to use the original bag after invoking this
235: * method, as it is a backdoor for adding untransformed objects.
236: *
237: * @param bag the bag to predicate, must not be null
238: * @param transformer the transformer for the bag, must not be null
239: * @return a transformed bag backed by the given bag
240: * @throws IllegalArgumentException if the Bag or Transformer is null
241: */
242: public static SortedBag transformedSortedBag(SortedBag bag,
243: Transformer transformer) {
244: return TransformedSortedBag.decorate(bag, transformer);
245: }
246:
247: }
|