public class ExternalFeedSimulator {
private static final Timer dispatcher = new Timer();
private final String REMOTE_RATE_FEED_URL = "serverurl";
private final ArrayList<RateRow> liverates = new ArrayList<RateRow>();
private final HashMap<String, RateRow> liveratesnew = new HashMap<String, RateRow>();
private final HashMap<String, RateRow> liveratesold = new HashMap<String, RateRow>();
private ExternalFeedListener listener;


public void start() {
sendGet();
// long waitTime = displayrates.computeNextWaitTime();
long waitTime = 500;
liveratescheduleGenerator(liverates, waitTime);
}


// HTTP GET request
public void sendGet() {
String url = REMOTE_RATE_FEED_URL;
URL obj;
try {
obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();


// optional default is GET
con.setRequestMethod("GET");


// add request header
con.setRequestProperty("User-Agent", USER_AGENT);


// int responseCode = con.getResponseCode();


// System.out.println("Response Code : " + responseCode);


BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();


while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();


if (response.toString() == null || response.toString().equals(""))
return;
String strlowerresponse = response.toString();


String trade_type = getItemValue(strlowerresponse, "trade_type");
String rate_display = getItemValue(strlowerresponse, "rate_display");
String update_time = getItemValue(strlowerresponse, "gold_updatetime");
String market_closed_msg = "";
String commodityupdatetime = getItemValue(strlowerresponse, "commodityupdatetime");


trade_type = trade_type.trim();
int startIndex = 0;
liveratesnew.clear();
while (startIndex != -1) {
int item_start_pos = strlowerresponse.indexOf("<Commodity>", startIndex) + 11;
if (item_start_pos < 11)
break;
int item_end_pos = strlowerresponse.indexOf("</Commodity>", item_start_pos + 1);
if (item_end_pos <= -1)
break;
String strnode = strlowerresponse.substring(item_start_pos, item_end_pos);
String instrid = getItemValue(strnode, "id");
String instrname = getItemValue(strnode, "name");
String strsellrate = getItemValue(strnode, "selling_rate");
String strbuyrate = getItemValue(strnode, "buying_rate");
String strhighrate = getItemValue(strnode, "selling_high");
String strlowrate = getItemValue(strnode, "selling_low");


int ordernumber = Integer.parseInt(getItemValue(strnode, "ordernumber"));
if (strbuyrate.equalsIgnoreCase("") || strbuyrate.equalsIgnoreCase("0"))
strbuyrate = "-";
if (strsellrate.equalsIgnoreCase("") || strsellrate.equalsIgnoreCase("0"))
strsellrate = "-";
RateRow commrate = new RateRow("Item" + instrid, instrname, strbuyrate, strsellrate, strlowrate,
strhighrate, ordernumber);


liverates.add(commrate);
liveratesnew.put("Item" + instrid, commrate);
startIndex = item_end_pos;
}


if (trade_type.equalsIgnoreCase("3") || rate_display.equalsIgnoreCase("1")) {
rate_display = "0";
} else {
rate_display = "1";
}
RateRow marketstatus = new RateRow("Marketstatus", rate_display, commodityupdatetime, update_time,
market_closed_msg);
curmarketstatus.add(marketstatus);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NumberFormatException e) {
System.out.println("not a number");
}
}


public synchronized void removeListener() {
// remove the listener
this.listener = null;
}


public String getItemValue(String strdata, String query) {
String strlowerdata = strdata.toLowerCase();
query = query.toLowerCase();
int item_start_pos = strlowerdata.indexOf("<" + query + ">") + query.length() + 2;
if (item_start_pos < query.length() + 2)
return "";
int item_end_pos = strlowerdata.indexOf("</" + query + ">");
if (item_end_pos < query.length() + 2)
return "";


String item_value = strdata.substring(item_start_pos, item_end_pos);
item_value = item_value.trim();
return item_value;
}


private void currentmarketstatusscheduleGenerator(final ArrayList<RateRow> nmarketstatus, long waitTime) {
dispatcher.schedule(new TimerTask() {
@Override
public void run() {
long nextWaitTime;
synchronized (nmarketstatus) {
if (listener != null) {
for (RateRow marketstatus : nmarketstatus) {
final HashMap<String, String> markstatus = new HashMap<String, String>();
markstatus.put("desc", marketstatus.getInstrumentName());
markstatus.put("ratedisplay", marketstatus.getBidRate());
markstatus.put("comupdatetime", marketstatus.getAskRate());
markstatus.put("updatetime", marketstatus.getLow_price());
markstatus.put("msg", marketstatus.getHigh_price());
listener.onEvent(marketstatus.getInstrumentName(), markstatus, false);
}
}
nmarketstatus.clear();
nextWaitTime = 500;
}


currentmarketstatusscheduleGenerator(curmarketstat us, nextWaitTime);
}
}, waitTime);
}
private void liveratescheduleGenerator(final ArrayList<RateRow> displayrates, long waitTime) {
dispatcher.schedule(new TimerTask() {
@Override
public void run() {
long nextWaitTime;
synchronized (displayrates) {
if (listener != null) {
for (RateRow curbidaskrates : displayrates) {
final HashMap<String, String> bidaskevent = new HashMap<String, String>();
bidaskevent.put("key", curbidaskrates.getItemName());
bidaskevent.put("desc", curbidaskrates.getInstrumentName());
bidaskevent.put("bid", curbidaskrates.getBidRate());
bidaskevent.put("ask", curbidaskrates.getAskRate());
bidaskevent.put("low", curbidaskrates.getLow_price());
bidaskevent.put("high", curbidaskrates.getHigh_price());
bidaskevent.put("order", Integer.toString(curbidaskrates.getDisplayorder()) );
listener.onActualStatus(curbidaskrates.getItemName (), bidaskevent, false, 2);
// listener.onEvent(curbidaskrates.getItemName(),
// bidaskevent, false);
}


}
displayrates.clear();
nextWaitTime = 500;


synchronized (liveratesnew) {
if ((liveratesnew.size() != liveratesold.size())) {
if (liveratesnew.size() > liveratesold.size()) {
synchronized (liveratesold) {
liveratesnew.forEach((k, v) -> {
if (!liveratesold.containsKey(liveratesnew.get(k).get ItemName())) {
liveratesold.put(liveratesnew.get(k).getItemName() , v);
final HashMap<String, String> liverateevent = new HashMap<String, String>();
liverateevent.put("key", liveratesnew.get(k).getItemName());
liverateevent.put("desc", liveratesnew.get(k).getInstrumentName());
liverateevent.put("bid", liveratesnew.get(k).getBidRate());
liverateevent.put("ask", liveratesnew.get(k).getAskRate());
liverateevent.put("low", liveratesnew.get(k).getLow_price());
liverateevent.put("high", liveratesnew.get(k).getHigh_price());
liverateevent.put("order",
Integer.toString(liveratesnew.get(k).getDisplayord er()));
listener.onActualStatus(liveratesnew.get(k).getIte mName(), liverateevent,
false, 1);
}
});
}
} else if (liveratesnew.size() < liveratesold.size()) {

final HashMap<String, String> removeoldkey = new HashMap<String, String>();
synchronized (liveratesold) {
for (Entry<String, RateRow> e : liveratesold.entrySet()) {
String key = e.getKey();
if (!liveratesnew.containsKey(liveratesold.get(key))) {
listener.onDeleteStatus(liveratesold.get(key).getI temName());
removeoldkey.put(key, liveratesold.get(key).getItemName());
// liveratesold.remove(liveratesold.get(key).getItemN ame());


}
}
}


for (Entry<String, String> e : removeoldkey.entrySet()) {
String key = e.getKey();
// listener.onDeleteStatus(key);
liveratesold.remove(key);
}
removeoldkey.clear();


}
}
}


}
sendGet();
liveratescheduleGenerator(liverates, nextWaitTime);
}
}, waitTime);
}


public void setFeedListener(ExternalFeedListener listener) {
this.listener = listener;
}


public void sendRates(String itemName) {
liveratesnew.forEach((k, v) -> {
final RateRow liverate = liveratesnew.get(k);
if (liverate.getItemName().contains(itemName)) {
dispatcher.schedule(new TimerTask() {
@Override
public void run() {
synchronized (liverate) {
final HashMap<String, String> crates = new HashMap<String, String>();
crates.put("key", liverate.getItemName());
crates.put("desc", liverate.getInstrumentName());
crates.put("bid", liverate.getBidRate());
crates.put("ask", liverate.getAskRate());
crates.put("low", liverate.getLow_price());
crates.put("high", liverate.getHigh_price());
crates.put("order", Integer.toString(liverate.getDisplayorder()));
listener.onActualStatus(liverate.getItemName(), crates, true, 1);
}
}
}, 0);
}


});
}
}