/*
* Copyright 2012 The Java HandlerSocket Connection Project
*
* https://github.com/komelgman/Java-HandlerSocket-Connection/
*
* The Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package kom.handlersocket.result;
import org.jboss.netty.buffer.ChannelBuffer;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class HSResultFuture {
private boolean isReady = false;
private final LinkedList<HSResult> resultSet;
private final Iterator<HSResult> resultSetIterator;
private Exception cause = null;
private final long defaultTimeout = 5000;
public HSResultFuture(LinkedList<HSResult> resultSet) {
this.resultSet = resultSet;
this.resultSetIterator = resultSet.iterator();
}
public LinkedList<HSResult> get() {
return get(defaultTimeout, TimeUnit.MILLISECONDS);
}
public LinkedList<HSResult> get(long timeout) {
return get(timeout, TimeUnit.MILLISECONDS);
}
public synchronized LinkedList<HSResult> get(long timeout, TimeUnit unit) {
if (!TimeUnit.MILLISECONDS.equals(unit)) {
timeout = TimeUnit.MILLISECONDS.convert(timeout, unit);
}
while (!isReady && (cause == null)) {
try {
wait(timeout);
if (cause == null) {
cause = new TimeoutException("request reset by timeout");
}
} catch (InterruptedException e) {
// ignore
}
}
if (!isReady) {
while (resultSetIterator.hasNext()) {
resultSetIterator.next().setCause(cause);
}
isReady = true;
}
return resultSet;
}
public synchronized void addResult(List<ChannelBuffer> data) {
if (!isReady) {
resultSetIterator.next().setData(data);
if (!resultSetIterator.hasNext()) {
isReady = true;
notifyAll();
}
}
}
public synchronized void setCause(Exception cause) {
if (this.cause == null) {
this.cause = cause;
notifyAll();
}
}
public synchronized boolean isReady() {
return isReady;
}
public synchronized boolean isSuccess() {
return isReady && (cause == null);
}
public synchronized Exception getCause() {
return cause;
}
}