001    /*
002     *  Licensed to the Apache Software Foundation (ASF) under one or more
003     *  contributor license agreements.  See the NOTICE file distributed with
004     *  this work for additional information regarding copyright ownership.
005     *  The ASF licenses this file to You under the Apache License, Version 2.0
006     *  (the "License"); you may not use this file except in compliance with
007     *  the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    package org.apache.commons.collections;
018    
019    import org.apache.commons.collections.buffer.BlockingBuffer;
020    import org.apache.commons.collections.buffer.PredicatedBuffer;
021    import org.apache.commons.collections.buffer.SynchronizedBuffer;
022    import org.apache.commons.collections.buffer.TransformedBuffer;
023    import org.apache.commons.collections.buffer.TypedBuffer;
024    import org.apache.commons.collections.buffer.UnmodifiableBuffer;
025    import org.apache.commons.collections.buffer.BoundedBuffer;
026    
027    /**
028     * Provides utility methods and decorators for {@link Buffer} instances.
029     *
030     * @since Commons Collections 2.1
031     * @version $Revision: 646777 $ $Date: 2008-04-10 13:33:15 +0100 (Thu, 10 Apr 2008) $
032     *
033     * @author Paul Jack
034     * @author Stephen Colebourne
035     */
036    public class BufferUtils {
037    
038        /**
039         * An empty unmodifiable buffer.
040         */
041        public static final Buffer EMPTY_BUFFER = UnmodifiableBuffer.decorate(new ArrayStack(1));
042    
043        /**
044         * <code>BufferUtils</code> should not normally be instantiated.
045         */
046        public BufferUtils() {
047        }
048    
049        //-----------------------------------------------------------------------
050        /**
051         * Returns a synchronized buffer backed by the given buffer.
052         * Much like the synchronized collections returned by
053         * {@link java.util.Collections}, you must manually synchronize on
054         * the returned buffer's iterator to avoid non-deterministic behavior:
055         *
056         * <pre>
057         * Buffer b = BufferUtils.synchronizedBuffer(myBuffer);
058         * synchronized (b) {
059         *     Iterator i = b.iterator();
060         *     while (i.hasNext()) {
061         *         process (i.next());
062         *     }
063         * }
064         * </pre>
065         *
066         * @param buffer  the buffer to synchronize, must not be null
067         * @return a synchronized buffer backed by that buffer
068         * @throws IllegalArgumentException  if the Buffer is null
069         */
070        public static Buffer synchronizedBuffer(Buffer buffer) {
071            return SynchronizedBuffer.decorate(buffer);
072        }
073    
074        /**
075         * Returns a synchronized buffer backed by the given buffer that will
076         * block on {@link Buffer#get()} and {@link Buffer#remove()} operations.
077         * If the buffer is empty, then the {@link Buffer#get()} and
078         * {@link Buffer#remove()} operations will block until new elements
079         * are added to the buffer, rather than immediately throwing a
080         * <code>BufferUnderflowException</code>.
081         *
082         * @param buffer  the buffer to synchronize, must not be null
083         * @return a blocking buffer backed by that buffer
084         * @throws IllegalArgumentException  if the Buffer is null
085         */
086        public static Buffer blockingBuffer(Buffer buffer) {
087            return BlockingBuffer.decorate(buffer);
088        }
089    
090        /**
091         * Returns a synchronized buffer backed by the given buffer that will
092         * block on {@link Buffer#get()} and {@link Buffer#remove()} operations
093         * until <code>timeout</code> expires.  If the buffer is empty, then the
094         * {@link Buffer#get()} and {@link Buffer#remove()} operations will block
095         * until new elements are added to the buffer, rather than immediately
096         * throwing a <code>BufferUnderflowException</code>.
097         *
098         * @param buffer  the buffer to synchronize, must not be null
099         * @param timeoutMillis  the timeout value in milliseconds, zero or less for no timeout
100         * @return a blocking buffer backed by that buffer
101         * @throws IllegalArgumentException  if the Buffer is null
102         * @since Commons Collections 3.2
103         */
104        public static Buffer blockingBuffer(Buffer buffer, long timeoutMillis) {
105            return BlockingBuffer.decorate(buffer, timeoutMillis);
106        }
107    
108        /**
109         * Returns a synchronized buffer backed by the given buffer that will
110         * block on {@link Buffer#add(Object)} and
111         * {@link Buffer#addAll(java.util.Collection)} until enough object(s) are
112         * removed from the buffer to allow the object(s) to be added and still
113         * maintain the maximum size.
114         *
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 Commons Collections 3.2
120         */
121        public static Buffer boundedBuffer(Buffer buffer, int maximumSize) {
122            return BoundedBuffer.decorate(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 buffer the buffer to make bounded, must not be null
133         * @param maximumSize the maximum size
134         * @param timeoutMillis  the timeout value in milliseconds, zero or less for no timeout
135         * @return a bounded buffer backed by the given buffer
136         * @throws IllegalArgumentException if the given buffer is null
137         * @since Commons Collections 3.2
138         */
139        public static Buffer boundedBuffer(Buffer buffer, int maximumSize, long timeoutMillis) {
140            return BoundedBuffer.decorate(buffer, maximumSize, timeoutMillis);
141        }
142    
143        /**
144         * Returns an unmodifiable buffer backed by the given buffer.
145         *
146         * @param buffer  the buffer to make unmodifiable, must not be null
147         * @return an unmodifiable buffer backed by that buffer
148         * @throws IllegalArgumentException  if the Buffer is null
149         */
150        public static Buffer unmodifiableBuffer(Buffer buffer) {
151            return UnmodifiableBuffer.decorate(buffer);
152        }
153    
154        /**
155         * Returns a predicated (validating) buffer backed by the given buffer.
156         * <p>
157         * Only objects that pass the test in the given predicate can be added to the buffer.
158         * Trying to add an invalid object results in an IllegalArgumentException.
159         * It is important not to use the original buffer after invoking this method,
160         * as it is a backdoor for adding invalid objects.
161         *
162         * @param buffer  the buffer to predicate, must not be null
163         * @param predicate  the predicate used to evaluate new elements, must not be null
164         * @return a predicated buffer
165         * @throws IllegalArgumentException  if the Buffer or Predicate is null
166         */
167        public static Buffer predicatedBuffer(Buffer buffer, Predicate predicate) {
168            return PredicatedBuffer.decorate(buffer, predicate);
169        }
170    
171        /**
172         * Returns a typed buffer backed by the given buffer.
173         * <p>
174         * Only elements of the specified type can be added to the buffer.
175         *
176         * @param buffer  the buffer to predicate, must not be null
177         * @param type  the type to allow into the buffer, must not be null
178         * @return a typed buffer
179         * @throws IllegalArgumentException  if the buffer or type is null
180         */
181        public static Buffer typedBuffer(Buffer buffer, Class type) {
182            return TypedBuffer.decorate(buffer, type);
183        }
184    
185        /**
186         * Returns a transformed buffer backed by the given buffer.
187         * <p>
188         * Each object is passed through the transformer as it is added to the
189         * Buffer. It is important not to use the original buffer after invoking this 
190         * method, as it is a backdoor for adding untransformed objects.
191         *
192         * @param buffer  the buffer to predicate, must not be null
193         * @param transformer  the transformer for the buffer, must not be null
194         * @return a transformed buffer backed by the given buffer
195         * @throws IllegalArgumentException  if the Buffer or Transformer is null
196         */
197        public static Buffer transformedBuffer(Buffer buffer, Transformer transformer) {
198            return TransformedBuffer.decorate(buffer, transformer);
199        }
200    
201    }