package com.alecgorge.minecraft.jsonapi.streams;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import org.json.simpleForBukkit.JSONObject;
import com.alecgorge.minecraft.jsonapi.JSONAPI;
import com.alecgorge.minecraft.jsonapi.JSONServer;
import com.alecgorge.minecraft.jsonapi.api.JSONAPIStream;
import com.alecgorge.minecraft.jsonapi.api.JSONAPIStreamListener;
import com.alecgorge.minecraft.jsonapi.api.JSONAPIStreamMessage;
public class StreamingResponse extends InputStream implements JSONAPIStreamListener {
private List<JSONAPIStream> stacks = new ArrayList<JSONAPIStream>();
private LinkedBlockingQueue<JSONAPIStreamMessage> queue = new LinkedBlockingQueue<JSONAPIStreamMessage>();
private JSONAPI plugin;
private String callback;
private List<String> tag;
private List<String> streams;
public StreamingResponse(JSONAPI _plugin, List<String> sourceLists, String callback, List<Boolean> showOlder, List<String> tag, List<JSONObject> seed) {
plugin = _plugin;
this.tag = tag;
this.streams = sourceLists;
for(String s : sourceLists) {
if(plugin.getStreamManager().streamExists(s)) {
stacks.add(plugin.getStreamManager().getStream(s));
}
else {
plugin.outLog.warning("The requested stream: '"+s+"' does not exist.");
}
}
int i = 0;
JSONAPI.dbug("Stacks: " + stacks);
for(JSONAPIStream s : stacks) {
JSONAPI.dbug("adding listener for " + s.getName() + ": " + s.getClass());
s.registerListener(this, showOlder.get(i));
i++;
}
if(seed != null) {
for(JSONObject o : seed) {
onMessage(new JSONObjectMessage(o), null);
}
}
}
public StreamingResponse(JSONAPI _plugin, List<String> sourceLists, String callback, boolean showOlder, String tag) {
plugin = _plugin;
List<String> tags = new ArrayList<String>(sourceLists.size());
for(int i = 0; i < sourceLists.size(); i++) {
tags.add(tag);
}
this.tag = tags;
this.streams = sourceLists;
for(String s : sourceLists) {
if(plugin.getStreamManager().streamExists(s)) {
stacks.add(plugin.getStreamManager().getStream(s));
}
else {
plugin.outLog.warning("The requested stream: '"+s+"' does not exist.");
}
}
for(JSONAPIStream s : stacks) {
JSONAPI.dbug("adding listener for " + s.getName());
s.registerListener(this, showOlder);
}
}
public void onMessage(JSONAPIStreamMessage message, JSONAPIStream sender) {
JSONAPI.dbug("recieveing message for " + (sender == null ? null : String.valueOf(sender.getName())));
try {
queue.put(message);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public String nextLine () {
try {
while(true) {
JSONAPIStreamMessage m;
m = queue.take();
return JSONServer.callback(callback, makeResponseObj(m)).concat("\r\n");
}
} catch (InterruptedException e) {
return null;
}
}
@Override
public void close() throws IOException {
for(JSONAPIStream s : stacks) {
JSONAPI.dbug("removing listener for " + s.getName());
s.deregisterListener(this);
}
}
private String makeResponseObj (JSONAPIStreamMessage ja) {
if(ja instanceof JSONObjectMessage) {
return ja.toJSONObject().toJSONString();
}
JSONObject o = new JSONObject();
o.put("result", "success");
o.put("source", ja.streamName());
o.put("success", ja);
try {
o.put("tag", tag.get(streams.indexOf(ja.streamName())));
return o.toJSONString();
}
catch (Exception e) {
return o.toJSONString(); // incase of a concurrence issue
// very hacky but it works
}
}
public int read() throws IOException {
return -1;
}
}