package org.commcare.graph.view.c3;
import org.commcare.graph.model.GraphData;
import org.commcare.graph.util.GraphException;
import org.json.JSONObject;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.SortedMap;
import java.util.TreeMap;
/**
* Base class for helper classes that build C3 graph configuration.
* This class itself is not meant to be instantiated. For subclasses,
* the bulk of the work is done in the constructor. The instantiator
* can then call getConfiguration and getVariables to get at the JSON
* configuration and any JavaScript variables that configuration depends on.
*
* Created by jschweers on 11/16/2015.
*/
public class Configuration {
private final SimpleDateFormat mDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
final GraphData mData;
final JSONObject mConfiguration;
final SortedMap<String, String> mVariables;
Configuration(GraphData data) {
mData = data;
mConfiguration = new JSONObject();
mVariables = new TreeMap<>();
}
public JSONObject getConfiguration() {
return mConfiguration;
}
public SortedMap<String, String> getVariables() {
return mVariables;
}
/**
* Parse given time value into string acceptable to C3.
*
* @param value The value, which may be a YYYY-MM-DD string, a YYYY-MM-DD HH:MM:SS,
* or a double representing days since the epoch.
* @param description Something to identify the kind of value, used to augment any error message.
* @return String of format YYYY-MM-DD HH:MM:SS, which is what C3 expects.
* This expected format is set in DataConfiguration as xFormat.
* @throws GraphException
*/
String parseTime(String value, String description) throws GraphException {
if (value.matches(".*[^0-9.].*")) {
if (!value.matches(".*:.*")) {
value += " 00:00:00";
}
} else {
double daysSinceEpoch = parseDouble(value, description);
Date d = new Date((long)(daysSinceEpoch * 86400000L));
value = mDateFormat.format(d);
}
return value;
}
/**
* Attempt to parse a double, but fail on NumberFormatException.
*
* @param description Something to identify the kind of value, used to augment any error message.
*/
double parseDouble(String value, String description) throws GraphException {
try {
Double numeric = Double.valueOf(value);
if (numeric.isNaN()) {
throw new GraphException("Could not understand '" + value + "' in " + description);
}
return numeric;
} catch (NumberFormatException nfe) {
throw new GraphException("Could not understand '" + value + "' in " + description);
}
}
}