View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.collections;
18  
19  import org.apache.commons.collections.buffer.BlockingBuffer;
20  import org.apache.commons.collections.buffer.BoundedBuffer;
21  import org.apache.commons.collections.buffer.PredicatedBuffer;
22  import org.apache.commons.collections.buffer.SynchronizedBuffer;
23  import org.apache.commons.collections.buffer.TransformedBuffer;
24  import org.apache.commons.collections.buffer.UnmodifiableBuffer;
25  
26  /**
27   * Provides utility methods and decorators for {@link Buffer} instances.
28   *
29   * @since 2.1
30   * @version $Id: BufferUtils.java 1436066 2013-01-21 01:28:08Z sebb $
31   */
32  public class BufferUtils {
33  
34      /**
35       * An empty unmodifiable buffer.
36       */
37      public static final Buffer<Object> EMPTY_BUFFER = UnmodifiableBuffer.unmodifiableBuffer(new ArrayStack<Object>(1));
38  
39      /**
40       * <code>BufferUtils</code> should not normally be instantiated.
41       */
42      public BufferUtils() {
43      }
44  
45      //-----------------------------------------------------------------------
46      /**
47       * Returns a synchronized buffer backed by the given buffer.
48       * Much like the synchronized collections returned by
49       * {@link java.util.Collections}, you must manually synchronize on
50       * the returned buffer's iterator to avoid non-deterministic behavior:
51       *
52       * <pre>
53       * Buffer b = BufferUtils.synchronizedBuffer(myBuffer);
54       * synchronized (b) {
55       *     Iterator i = b.iterator();
56       *     while (i.hasNext()) {
57       *         process (i.next());
58       *     }
59       * }
60       * </pre>
61       *
62       * @param <E> the type of the elements in the buffer
63       * @param buffer  the buffer to synchronize, must not be null
64       * @return a synchronized buffer backed by that buffer
65       * @throws IllegalArgumentException  if the Buffer is null
66       */
67      public static <E> Buffer<E> synchronizedBuffer(final Buffer<E> buffer) {
68          return SynchronizedBuffer.synchronizedBuffer(buffer);
69      }
70  
71      /**
72       * Returns a synchronized buffer backed by the given buffer that will
73       * block on {@link Buffer#get()} and {@link Buffer#remove()} operations.
74       * If the buffer is empty, then the {@link Buffer#get()} and
75       * {@link Buffer#remove()} operations will block until new elements
76       * are added to the buffer, rather than immediately throwing a
77       * <code>BufferUnderflowException</code>.
78       *
79       * @param <E> the type of the elements in the buffer
80       * @param buffer  the buffer to synchronize, must not be null
81       * @return a blocking buffer backed by that buffer
82       * @throws IllegalArgumentException  if the Buffer is null
83       */
84      public static <E> Buffer<E> blockingBuffer(final Buffer<E> buffer) {
85          return BlockingBuffer.blockingBuffer(buffer);
86      }
87  
88      /**
89       * Returns a synchronized buffer backed by the given buffer that will
90       * block on {@link Buffer#get()} and {@link Buffer#remove()} operations
91       * until <code>timeout</code> expires.  If the buffer is empty, then the
92       * {@link Buffer#get()} and {@link Buffer#remove()} operations will block
93       * until new elements are added to the buffer, rather than immediately
94       * throwing a <code>BufferUnderflowException</code>.
95       *
96       * @param <E> the type of the elements in the buffer
97       * @param buffer  the buffer to synchronize, must not be null
98       * @param timeoutMillis  the timeout value in milliseconds, zero or less for no timeout
99       * @return a blocking buffer backed by that buffer
100      * @throws IllegalArgumentException  if the Buffer is null
101      * @since 3.2
102      */
103     public static <E> Buffer<E> blockingBuffer(final Buffer<E> buffer, final long timeoutMillis) {
104         return BlockingBuffer.blockingBuffer(buffer, timeoutMillis);
105     }
106 
107     /**
108      * Returns a synchronized buffer backed by the given buffer that will
109      * block on {@link Buffer#add(Object)} and
110      * {@link Buffer#addAll(java.util.Collection)} until enough object(s) are
111      * removed from the buffer to allow the object(s) to be added and still
112      * maintain the maximum size.
113      *
114      * @param <E> the type of the elements in the buffer
115      * @param buffer  the buffer to make bounded,  must not be null
116      * @param maximumSize  the maximum size
117      * @return a bounded buffer backed by the given buffer
118      * @throws IllegalArgumentException if the given buffer is null
119      * @since 3.2
120      */
121     public static <E> Buffer<E> boundedBuffer(final Buffer<E> buffer, final int maximumSize) {
122         return BoundedBuffer.boundedBuffer(buffer, maximumSize);
123     }
124 
125     /**
126      * Returns a synchronized buffer backed by the given buffer that will
127      * block on {@link Buffer#add(Object)} and
128      * {@link Buffer#addAll(java.util.Collection)} until enough object(s) are
129      * removed from the buffer to allow the object(s) to be added and still
130      * maintain the maximum size or the timeout expires.
131      *
132      * @param <E> the type of the elements in the buffer
133      * @param buffer the buffer to make bounded, must not be null
134      * @param maximumSize the maximum size
135      * @param timeoutMillis  the timeout value in milliseconds, zero or less for no timeout
136      * @return a bounded buffer backed by the given buffer
137      * @throws IllegalArgumentException if the given buffer is null
138      * @since 3.2
139      */
140     public static <E> Buffer<E> boundedBuffer(final Buffer<E> buffer, final int maximumSize, final long timeoutMillis) {
141         return BoundedBuffer.boundedBuffer(buffer, maximumSize, timeoutMillis);
142     }
143 
144     /**
145      * Returns an unmodifiable buffer backed by the given buffer.
146      *
147      * @param <E> the type of the elements in the buffer
148      * @param buffer  the buffer to make unmodifiable, must not be null
149      * @return an unmodifiable buffer backed by that buffer
150      * @throws IllegalArgumentException  if the Buffer is null
151      */
152     public static <E> Buffer<E> unmodifiableBuffer(final Buffer<E> buffer) {
153         return UnmodifiableBuffer.unmodifiableBuffer(buffer);
154     }
155 
156     /**
157      * Returns a predicated (validating) buffer backed by the given buffer.
158      * <p>
159      * Only objects that pass the test in the given predicate can be added to the buffer.
160      * Trying to add an invalid object results in an IllegalArgumentException.
161      * It is important not to use the original buffer after invoking this method,
162      * as it is a backdoor for adding invalid objects.
163      *
164      * @param <E> the type of the elements in the buffer
165      * @param buffer  the buffer to predicate, must not be null
166      * @param predicate  the predicate used to evaluate new elements, must not be null
167      * @return a predicated buffer
168      * @throws IllegalArgumentException  if the Buffer or Predicate is null
169      */
170     public static <E> Buffer<E> predicatedBuffer(final Buffer<E> buffer, final Predicate<? super E> predicate) {
171         return PredicatedBuffer.predicatedBuffer(buffer, predicate);
172     }
173 
174     /**
175      * Returns a transformed buffer backed by the given buffer.
176      * <p>
177      * Each object is passed through the transformer as it is added to the
178      * Buffer. It is important not to use the original buffer after invoking this 
179      * method, as it is a backdoor for adding untransformed objects.
180      * <p>
181      * Existing entries in the specified buffer will not be transformed.
182      * If you want that behaviour, see {@link TransformedBuffer#transformedBuffer}.
183      *
184      * @param <E> the type of the elements in the buffer
185      * @param buffer  the buffer to predicate, must not be null
186      * @param transformer  the transformer for the buffer, must not be null
187      * @return a transformed buffer backed by the given buffer
188      * @throws IllegalArgumentException  if the Buffer or Transformer is null
189      */
190     public static <E> Buffer<E> transformingBuffer(final Buffer<E> buffer,
191             final Transformer<? super E, ? extends E> transformer) {
192         return TransformedBuffer.transformingBuffer(buffer, transformer);
193     }
194 
195     /**
196      * Get an empty <code>Buffer</code>.
197      *
198      * @param <E> the type of the elements in the buffer
199      * @return an empty {@link Buffer}
200      */
201     @SuppressWarnings("unchecked") // OK, empty buffer is compatible with any type
202     public static <E> Buffer<E> emptyBuffer() {
203         return (Buffer<E>) EMPTY_BUFFER;
204     }
205 }