package org.infinispan.quickstart.compatibility.commands; import org.infinispan.quickstart.compatibility.common.SharesUpdate; import java.io.Console; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.Date; import java.util.GregorianCalendar; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Checks the requested history of shares. First, parses arguments specifying the length of history and step. * Second, generates a proper key set. Third, retrieves share updates stored under the key set and prints the history. * * @author Martin Gencur */ public class HistoryCommand extends AbstractRestCommand { private Calendar cal = new GregorianCalendar(); @Override public int getNumArgs() { return 3; } @Override public void execute(Console console, String argLine) { String[] args = argLine.split("\\s"); String stockName = args[1]; String maxHistoryArg = args[2]; String stepArg = args[3]; if (args.length != getNumArgs() + 1) { console.printf("The argument list is incorrect\n"); return; } try { //get last existing update and its date SharesUpdate lastUpdate = (SharesUpdate) getSharesUpdateViaRest(composeKey(stockName, "last")); //get all updates between last existing update and requested date in history List<String> stockHistoryKeys = getStockHistoryKeySet(stockName, lastUpdate.getDate(), toSeconds(maxHistoryArg), toSeconds(stepArg)); float previous = 0.0f, current = 0.0f; console.printf("------------- History of %s -------------\n", stockName); for (String key : stockHistoryKeys) { SharesUpdate sharesUpdate = (SharesUpdate) getSharesUpdateViaRest(key); if (sharesUpdate != null) { current = sharesUpdate.getValue(); console.printf("Date: %s, value: %f USD (%s %+f%%)\n", sharesUpdate.getDate().toString(), current, current > previous ? "increase" : "decrease", computeIncreaseInPercent(previous, current)); } previous = current; } } catch (Exception e) { e.printStackTrace(); } } private float computeIncreaseInPercent(float previous, float current) { if (previous == 0.0f) { return 0.0f; } else { return (current / (previous / 100)) - 100.0f; } } /* * Convert numbers like "2m" or "10h" to the number of seconds */ private long toSeconds(String duration) { Pattern regex = Pattern.compile("(\\d+)([smh])"); //an integer followed by 's','m','h' Matcher regexMatcher = regex.matcher(duration); long numSeconds = 1; if (regexMatcher.matches()) { int amount = Integer.parseInt(regexMatcher.group(1)); //get the number Character unitChar = regexMatcher.group(2).charAt(0); //get the unit character switch (unitChar) { case 's': numSeconds = TimeUnit.SECONDS.toSeconds(amount); break; case 'm': numSeconds = TimeUnit.MINUTES.toSeconds(amount); break; case 'h': numSeconds = TimeUnit.HOURS.toSeconds(amount); break; } } return numSeconds; } private List<String> getStockHistoryKeySet(String stockName, Date lastUpdateTime, long seconds, long step) { List<String> keys = new ArrayList<String>(); cal.setTime(lastUpdateTime); //start from latest valid update long counter = 0; while (counter <= seconds) { keys.add(composeKey(stockName, KEY_DATE_FORMAT.format(cal.getTime()))); cal.add(Calendar.SECOND, (int) -step); counter += step; } Collections.reverse(keys); //get the keys in ascending order return Collections.unmodifiableList(keys); } }