1 16 package org.apache.commons.collections.buffer; 17 18 import java.io.PrintWriter ; 19 import java.io.StringWriter ; 20 import java.util.Collection ; 21 import java.util.Iterator ; 22 23 import org.apache.commons.collections.BoundedCollection; 24 import org.apache.commons.collections.Buffer; 25 import org.apache.commons.collections.BufferOverflowException; 26 import org.apache.commons.collections.BufferUnderflowException; 27 import org.apache.commons.collections.iterators.AbstractIteratorDecorator; 28 29 47 public class BoundedBuffer extends SynchronizedBuffer implements BoundedCollection { 48 49 50 private static final long serialVersionUID = 1536432911093974264L; 51 52 53 private final int maximumSize; 54 55 private final long timeout; 56 57 69 public static BoundedBuffer decorate(Buffer buffer, int maximumSize) { 70 return new BoundedBuffer(buffer, maximumSize, 0L); 71 } 72 73 84 public static BoundedBuffer decorate(Buffer buffer, int maximumSize, long timeout) { 85 return new BoundedBuffer(buffer, maximumSize, timeout); 86 } 87 88 99 protected BoundedBuffer(Buffer buffer, int maximumSize, long timeout) { 100 super(buffer); 101 if (maximumSize < 1) { 102 throw new IllegalArgumentException (); 103 } 104 this.maximumSize = maximumSize; 105 this.timeout = timeout; 106 } 107 108 public Object remove() { 110 synchronized (lock) { 111 Object returnValue = getBuffer().remove(); 112 lock.notifyAll(); 113 return returnValue; 114 } 115 } 116 117 public boolean add(Object o) { 118 synchronized (lock) { 119 timeoutWait(1); 120 return getBuffer().add(o); 121 } 122 } 123 124 public boolean addAll(final Collection c) { 125 synchronized (lock) { 126 timeoutWait(c.size()); 127 return getBuffer().addAll(c); 128 } 129 } 130 131 public Iterator iterator() { 132 return new NotifyingIterator(collection.iterator()); 133 } 134 135 private void timeoutWait(final int nAdditions) { 136 if (nAdditions > maximumSize) { 138 throw new BufferOverflowException( 139 "Buffer size cannot exceed " + maximumSize); 140 } 141 if (timeout <= 0) { 142 if (getBuffer().size() + nAdditions > maximumSize) { 144 throw new BufferOverflowException( 145 "Buffer size cannot exceed " + maximumSize); 146 } 147 return; 148 } 149 final long expiration = System.currentTimeMillis() + timeout; 150 long timeLeft = expiration - System.currentTimeMillis(); 151 while (timeLeft > 0 && getBuffer().size() + nAdditions > maximumSize) { 152 try { 153 lock.wait(timeLeft); 154 timeLeft = expiration - System.currentTimeMillis(); 155 } catch (InterruptedException ex) { 156 PrintWriter out = new PrintWriter (new StringWriter ()); 157 ex.printStackTrace(out); 158 throw new BufferUnderflowException( 159 "Caused by InterruptedException: " + out.toString()); 160 } 161 } 162 if (getBuffer().size() + nAdditions > maximumSize) { 163 throw new BufferOverflowException("Timeout expired"); 164 } 165 } 166 167 public boolean isFull() { 168 return (size() == maxSize()); 170 } 171 172 public int maxSize() { 173 return maximumSize; 174 } 175 176 180 private class NotifyingIterator extends AbstractIteratorDecorator { 181 182 public NotifyingIterator(Iterator it) { 183 super(it); 184 } 185 186 public void remove() { 187 synchronized (lock) { 188 iterator.remove(); 189 lock.notifyAll(); 190 } 191 } 192 } 193 } 194 | Popular Tags |