1. /*
  2. * Copyright 2002-2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.apache.commons.collections;
  17. import org.apache.commons.collections.bag.HashBag;
  18. import org.apache.commons.collections.bag.PredicatedBag;
  19. import org.apache.commons.collections.bag.PredicatedSortedBag;
  20. import org.apache.commons.collections.bag.SynchronizedBag;
  21. import org.apache.commons.collections.bag.SynchronizedSortedBag;
  22. import org.apache.commons.collections.bag.TransformedBag;
  23. import org.apache.commons.collections.bag.TransformedSortedBag;
  24. import org.apache.commons.collections.bag.TreeBag;
  25. import org.apache.commons.collections.bag.TypedBag;
  26. import org.apache.commons.collections.bag.TypedSortedBag;
  27. import org.apache.commons.collections.bag.UnmodifiableBag;
  28. import org.apache.commons.collections.bag.UnmodifiableSortedBag;
  29. /**
  30. * Provides utility methods and decorators for
  31. * {@link Bag} and {@link SortedBag} instances.
  32. *
  33. * @since Commons Collections 2.1
  34. * @version $Revision: 1.20 $ $Date: 2004/04/01 20:12:00 $
  35. *
  36. * @author Paul Jack
  37. * @author Stephen Colebourne
  38. * @author Andrew Freeman
  39. * @author Matthew Hawthorne
  40. */
  41. public class BagUtils {
  42. /**
  43. * An empty unmodifiable bag.
  44. */
  45. public static final Bag EMPTY_BAG = UnmodifiableBag.decorate(new HashBag());
  46. /**
  47. * An empty unmodifiable sorted bag.
  48. */
  49. public static final Bag EMPTY_SORTED_BAG = UnmodifiableSortedBag.decorate(new TreeBag());
  50. /**
  51. * Instantiation of BagUtils is not intended or required.
  52. * However, some tools require an instance to operate.
  53. */
  54. public BagUtils() {
  55. }
  56. //-----------------------------------------------------------------------
  57. /**
  58. * Returns a synchronized (thread-safe) bag backed by the given bag.
  59. * In order to guarantee serial access, it is critical that all
  60. * access to the backing bag is accomplished through the returned bag.
  61. * <p>
  62. * It is imperative that the user manually synchronize on the returned
  63. * bag when iterating over it:
  64. *
  65. * <pre>
  66. * Bag bag = BagUtils.synchronizedBag(new HashBag());
  67. * ...
  68. * synchronized(bag) {
  69. * Iterator i = bag.iterator(); // Must be in synchronized block
  70. * while (i.hasNext())
  71. * foo(i.next());
  72. * }
  73. * }
  74. * </pre>
  75. *
  76. * Failure to follow this advice may result in non-deterministic
  77. * behavior.
  78. *
  79. * @param bag the bag to synchronize, must not be null
  80. * @return a synchronized bag backed by that bag
  81. * @throws IllegalArgumentException if the Bag is null
  82. */
  83. public static Bag synchronizedBag(Bag bag) {
  84. return SynchronizedBag.decorate(bag);
  85. }
  86. /**
  87. * Returns an unmodifiable view of the given bag. Any modification
  88. * attempts to the returned bag will raise an
  89. * {@link UnsupportedOperationException}.
  90. *
  91. * @param bag the bag whose unmodifiable view is to be returned, must not be null
  92. * @return an unmodifiable view of that bag
  93. * @throws IllegalArgumentException if the Bag is null
  94. */
  95. public static Bag unmodifiableBag(Bag bag) {
  96. return UnmodifiableBag.decorate(bag);
  97. }
  98. /**
  99. * Returns a predicated (validating) bag backed by the given bag.
  100. * <p>
  101. * Only objects that pass the test in the given predicate can be added to the bag.
  102. * Trying to add an invalid object results in an IllegalArgumentException.
  103. * It is important not to use the original bag after invoking this method,
  104. * as it is a backdoor for adding invalid objects.
  105. *
  106. * @param bag the bag to predicate, must not be null
  107. * @param predicate the predicate for the bag, must not be null
  108. * @return a predicated bag backed by the given bag
  109. * @throws IllegalArgumentException if the Bag or Predicate is null
  110. */
  111. public static Bag predicatedBag(Bag bag, Predicate predicate) {
  112. return PredicatedBag.decorate(bag, predicate);
  113. }
  114. /**
  115. * Returns a typed bag backed by the given bag.
  116. * <p>
  117. * Only objects of the specified type can be added to the bag.
  118. *
  119. * @param bag the bag to limit to a specific type, must not be null
  120. * @param type the type of objects which may be added to the bag
  121. * @return a typed bag backed by the specified bag
  122. */
  123. public static Bag typedBag(Bag bag, Class type) {
  124. return TypedBag.decorate(bag, type);
  125. }
  126. /**
  127. * Returns a transformed bag backed by the given bag.
  128. * <p>
  129. * Each object is passed through the transformer as it is added to the
  130. * Bag. It is important not to use the original bag after invoking this
  131. * method, as it is a backdoor for adding untransformed objects.
  132. *
  133. * @param bag the bag to predicate, must not be null
  134. * @param transformer the transformer for the bag, must not be null
  135. * @return a transformed bag backed by the given bag
  136. * @throws IllegalArgumentException if the Bag or Transformer is null
  137. */
  138. public static Bag transformedBag(Bag bag, Transformer transformer) {
  139. return TransformedBag.decorate(bag, transformer);
  140. }
  141. //-----------------------------------------------------------------------
  142. /**
  143. * Returns a synchronized (thread-safe) sorted bag backed by the given
  144. * sorted bag.
  145. * In order to guarantee serial access, it is critical that all
  146. * access to the backing bag is accomplished through the returned bag.
  147. * <p>
  148. * It is imperative that the user manually synchronize on the returned
  149. * bag when iterating over it:
  150. *
  151. * <pre>
  152. * SortedBag bag = BagUtils.synchronizedSortedBag(new TreeBag());
  153. * ...
  154. * synchronized(bag) {
  155. * Iterator i = bag.iterator(); // Must be in synchronized block
  156. * while (i.hasNext())
  157. * foo(i.next());
  158. * }
  159. * }
  160. * </pre>
  161. *
  162. * Failure to follow this advice may result in non-deterministic
  163. * behavior.
  164. *
  165. * @param bag the bag to synchronize, must not be null
  166. * @return a synchronized bag backed by that bag
  167. * @throws IllegalArgumentException if the SortedBag is null
  168. */
  169. public static SortedBag synchronizedSortedBag(SortedBag bag) {
  170. return SynchronizedSortedBag.decorate(bag);
  171. }
  172. /**
  173. * Returns an unmodifiable view of the given sorted bag. Any modification
  174. * attempts to the returned bag will raise an
  175. * {@link UnsupportedOperationException}.
  176. *
  177. * @param bag the bag whose unmodifiable view is to be returned, must not be null
  178. * @return an unmodifiable view of that bag
  179. * @throws IllegalArgumentException if the SortedBag is null
  180. */
  181. public static SortedBag unmodifiableSortedBag(SortedBag bag) {
  182. return UnmodifiableSortedBag.decorate(bag);
  183. }
  184. /**
  185. * Returns a predicated (validating) sorted bag backed by the given sorted bag.
  186. * <p>
  187. * Only objects that pass the test in the given predicate can be added to the bag.
  188. * Trying to add an invalid object results in an IllegalArgumentException.
  189. * It is important not to use the original bag after invoking this method,
  190. * as it is a backdoor for adding invalid objects.
  191. *
  192. * @param bag the sorted bag to predicate, must not be null
  193. * @param predicate the predicate for the bag, must not be null
  194. * @return a predicated bag backed by the given bag
  195. * @throws IllegalArgumentException if the SortedBag or Predicate is null
  196. */
  197. public static SortedBag predicatedSortedBag(SortedBag bag, Predicate predicate) {
  198. return PredicatedSortedBag.decorate(bag, predicate);
  199. }
  200. /**
  201. * Returns a typed sorted bag backed by the given bag.
  202. * <p>
  203. * Only objects of the specified type can be added to the bag.
  204. *
  205. * @param bag the bag to limit to a specific type, must not be null
  206. * @param type the type of objects which may be added to the bag
  207. * @return a typed bag backed by the specified bag
  208. */
  209. public static SortedBag typedSortedBag(SortedBag bag, Class type) {
  210. return TypedSortedBag.decorate(bag, type);
  211. }
  212. /**
  213. * Returns a transformed sorted bag backed by the given bag.
  214. * <p>
  215. * Each object is passed through the transformer as it is added to the
  216. * Bag. It is important not to use the original bag after invoking this
  217. * method, as it is a backdoor for adding untransformed objects.
  218. *
  219. * @param bag the bag to predicate, must not be null
  220. * @param transformer the transformer for the bag, must not be null
  221. * @return a transformed bag backed by the given bag
  222. * @throws IllegalArgumentException if the Bag or Transformer is null
  223. */
  224. public static SortedBag transformedSortedBag(SortedBag bag, Transformer transformer) {
  225. return TransformedSortedBag.decorate(bag, transformer);
  226. }
  227. }