package jstellarapi.connection;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.json.simple.JSONObject;
//Checkout jetty's FuturePromise class.
public class FutureJSONResponse<T extends JSONSerializable> implements Future<T> {
public final int responseCounter;
JSONResponseHolder responseHolder;
JSONObject response;
T unserializedObj;
public FutureJSONResponse(int requestCounter, JSONResponseHolder responseHolder, T unserializedObj) {
this.responseCounter = requestCounter;
this.responseHolder =responseHolder;
this.unserializedObj = unserializedObj;
}
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
boolean hasCompleted = responseHolder.remove(this);
synchronized (this) {
notifyAll();
}
return hasCompleted;
}
synchronized public void set(JSONObject response){
this.response=response;
notifyAll();
}
public JSONObject getResponse() throws InterruptedException {
synchronized (this) {
if(response==null){
wait();
}
if(response.get("error")!=null){
throw new RuntimeException("failed because "+response);
}
return response;
}
}
@Override
public T get() throws InterruptedException, ExecutionException {
JSONObject response = getResponse();
return deSerialize(response);
}
protected T deSerialize(JSONObject response) {
JSONObject result = (JSONObject) response.get("result");
if(result==null || "success".equals(response.get("status"))==false){
unserializedObj=null;
}
else{
unserializedObj.copyFrom(result);
}
return unserializedObj;
}
public JSONObject getResponse(long timeout, TimeUnit unit) throws InterruptedException {
synchronized (this) {
if(response==null){
unit.timedWait(this, timeout);
}
return response;
}
}
@Override
public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
JSONObject response = getResponse(timeout, unit);
return deSerialize(response);
}
@Override
public boolean isCancelled() {
return responseHolder.isCancelled(this);
}
@Override
public boolean isDone() {
return response!=null;
}
}