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 }