/**
* Provides methods to create formatted JSON output data for the REST APIs
*/
package qa.qcri.aidr.output.utils;
import java.util.List;
import java.util.ListIterator;
import org.apache.log4j.Logger;
import com.google.gson.JsonObject;
public class JsonDataFormatter {
private static Logger logger = Logger.getLogger(JsonDataFormatter.class);
String callbackName = null;
int count = 0;
public JsonDataFormatter(String callbackName) {
this.callbackName = callbackName;
count = 0;
}
public int getMessageCount() {
return count;
}
private StringBuilder setPrefix(boolean isArray) {
StringBuilder jsonDataList = new StringBuilder();
if (callbackName != null)
jsonDataList.append(callbackName).append("(");
if (isArray)
jsonDataList.append("[");
return jsonDataList;
}
private StringBuilder setSuffix(StringBuilder jsonDataList, boolean isArray) {
if (isArray)
jsonDataList.append("]");
if (callbackName != null)
jsonDataList.append(")");
return jsonDataList;
}
public StringBuilder createList(List<String> bufferedMessages, int messageCount, boolean rejectNullFlag) {
// Now, build the jsonp object to be sent - data in reverse chronological order.
// The entire collection of json objects are wrapped with a single callback function.
StringBuilder jsonDataList = new StringBuilder();
count = 0;
jsonDataList.append(setPrefix(true));
if (bufferedMessages != null) {
ListIterator<String> itr = bufferedMessages.listIterator(bufferedMessages.size()); // Must be in synchronized block
while (itr.hasPrevious() && count < messageCount) {
final String msg = itr.previous();
final TaggerJsonOutputAdapter jsonOutput = new TaggerJsonOutputAdapter();
final String jsonData = (msg != null) ? jsonOutput.buildJsonString(msg, rejectNullFlag) : null;
//logger.info("json string: " + jsonData);
if (jsonData != null) {
jsonDataList.append(jsonData);
++count;
if ((count < messageCount) && itr.hasPrevious()) jsonDataList.append(","); // otherwise, this was the last message to append
}
}
}
if (count == 0) {
// send empty jsonp object
jsonDataList.append(callbackName != null ? new String("{}])") : new String("{}]"));
}
else {
// there are json objects to send
//jsonDataList.deleteCharAt(jsonDataList.lastIndexOf(",")); // delete the extra "," at the end of the json string
jsonDataList = setSuffix(jsonDataList, true);
}
return jsonDataList;
}
public StringBuilder createRateLimitedList(List<String> bufferedMessages, final SimpleFairScheduler channelSelector, int messageCount, boolean rejectNullFlag) {
// Now, build the jsonp object to be sent - data in reverse chronological order.
// The entire collection of json objects are wrapped with a single callback function.
StringBuilder jsonDataList = null;
boolean attempt = true;
while (attempt) {
boolean existsFlag = false;
jsonDataList = new StringBuilder();
jsonDataList.append(setPrefix(true));
count = 0;
if (bufferedMessages != null) {
ListIterator<String> itr = bufferedMessages.listIterator(bufferedMessages.size());
while (itr.hasPrevious() && count < messageCount) {
final String msg = itr.previous();
final TaggerJsonOutputAdapter jsonOutput = new TaggerJsonOutputAdapter();
final String jsonData = (msg != null) ? jsonOutput.buildJsonString(msg, rejectNullFlag) : null;
//logger.info("channel: " + jsonOutput.getCrisisCode() + ", freq = " + channelSelector.getValue(jsonOutput.getCrisisCode()) + ", rate limited = " + channelSelector.isRateLimited(jsonOutput.getCrisisCode()));
//logger.info(jsonOutput.getCrisisCode() + ": json string = " + jsonData);
existsFlag = (jsonData != null) ? true : false;
if (jsonData != null && !channelSelector.isRateLimited(jsonOutput.getCrisisCode())) {
jsonDataList.append(jsonData);
channelSelector.increment(jsonOutput.getCrisisCode());
//logger.info("Added tweet to send list, freq = " + channelSelector.getValue(jsonOutput.getCrisisCode()));
++count;
if (count < messageCount && itr.hasPrevious()) jsonDataList.append(","); // otherwise, this was the last message to append
}
}
}
if (count == 0) {
//if (existsFlag || (!channelSelector.existsNotRateLimitedKey() && !bufferedMessages.isEmpty())) {
if (existsFlag && !channelSelector.existsNotRateLimitedKey()) {
// reset all rate limits
channelSelector.initializeAll();
//logger.info("Reset rate limits - again attempting, attempt = " + attempt);
} else {
attempt = false; // no point retrying
// send empty jsonp object
//logger.info("Giving up on attempting - no data! attempt = " + attempt);
jsonDataList.append(callbackName != null ? new String("{}])") : new String("{}]"));
}
}
else {
// there are json objects to send
//jsonDataList.deleteCharAt(jsonDataList.lastIndexOf(",")); // delete the extra "," at the end of the json string
attempt = false;
//logger.info("Done attempting: sending data, attempt = " + attempt);
jsonDataList = setSuffix(jsonDataList, true);
}
}
return jsonDataList;
}
public StringBuilder createStreamingList(List<String> bufferedMessages, int messageCount, boolean rejectNullFlag) {
// Now, build the jsonp object to be sent - data in reverse chronological order.
// The entire collection of json objects are wrapped with a single callback function.
StringBuilder jsonDataList = new StringBuilder();
jsonDataList.append(setPrefix(false));
count = 0;
if (bufferedMessages != null) {
ListIterator<String> itr = bufferedMessages.listIterator(bufferedMessages.size()); // Must be in synchronized block
while (itr.hasPrevious() && count < messageCount) {
final String msg = itr.previous();
final TaggerJsonOutputAdapter jsonOutput = new TaggerJsonOutputAdapter();
final String jsonData = (msg != null) ? jsonOutput.buildJsonString(msg, rejectNullFlag) : null;
//logger.info("json string: " + jsonData);
if (jsonData != null) {
try {
JsonObject jsonMessage = new JsonObject();
jsonMessage.addProperty("document_type", "Twitter");
jsonMessage.addProperty("document", jsonData);
jsonDataList.append(jsonMessage);
++count;
} catch (Exception e) {
logger.error("Error in creating json streaming output object");
}
}
}
}
if (count == 0) {
// send empty jsonp object
jsonDataList.append(callbackName != null ? new String("{})") : new String("{}"));
}
else {
// there are json objects to send
//jsonDataList.deleteCharAt(jsonDataList.lastIndexOf(",")); // delete the extra "," at the end of the json string
jsonDataList = setSuffix(jsonDataList, false);
}
return jsonDataList;
}
}