I've written a program in Java that will fetch JSON information from a service through their API and save it. As I'm new to Java, I want my code looking clean as possible and to understand the language's cultural coding standards as soon as possible. I know JSON data is usually mapped to a POJO, but I still haven't been able to quiet figure out how to do that. Other than that, please feel free to be pedantic!
Main function
public class WeatherTracker {
public static Boolean validData (JsonNode node) {
//get() returns "null" if key does not exist
if (node.get("response").get("error") == null) { return true; }
else { return false; }
}
public static void saveDataAsFile(JsonNode node, String dirPath, String fileName) throws JsonGenerationException, JsonMappingException, IOException {
File dir = new File(dirPath);
boolean success = dir.mkdirs() | dir.exists();
if (success) {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.writeValue(new File(dirPath+fileName), node);
System.out.println("File created at: " + dirPath+fileName);
} else {
System.out.println("Could not make file at " + dirPath); //TODO Raise Exception if !success
}
}
public static void historicalData(String apiKey, String city, String state, String date) throws MalformedURLException, IOException {
// Do not attempt to get historical data unless all parameters have been passed
if (city == null | state == null | date == null) {
System.out.println("City, State, and Date must be provided when using historical look-up");
System.exit(1);
} else {
JsonNode json = new WundergroundData(apiKey).fetchHistorical(city, state, date); //.path("history").path("dailysummary");
if (validData(json)) {
String sysFileSeperator = System.getProperty("file.separator");
//Files will be saved in the format of ${cwd}/${city}/${date}.json
String dirPath = String.format("%s%s%s%s", System.getProperty("user.dir"), sysFileSeperator, city, sysFileSeperator);
String fileName = String.format("%s.json", date);
saveDataAsFile(json.path("history"), dirPath, fileName);
}
else {
System.out.println(json.get("response").get("error"));
}
}
}
public static void main(String args[]) throws IOException, ParseException {
String feature = null;
String city = null;
String state = null;
String date = null;
String apiKey = "*********074e7f5";
//Initialize and set up CLI help options
Options options = new Options();
options.addOption("f", "feature", true , "Feature requested");
options.addOption("c", "city" , true , "City requested");
options.addOption("s", "state" , true , "");
options.addOption("d", "date" , true , "Format as YYYMMDD. Date of look-up when doing a historical query");
options.addOption("k", "key" , true , "Wunderground API Key");
options.addOption("h", "help" , false, "Show help");
//Initialize CLI Parsers/Formatters
HelpFormatter formater = new HelpFormatter();
CommandLineParser parser = new GnuParser();
// Parse CLI input
CommandLine cmd = parser.parse(options, args);
// Set CLI input to variables
if (cmd.hasOption("f")) { feature = cmd.getOptionValue("f"); }
if (cmd.hasOption("c")) { city = cmd.getOptionValue("c"); }
if (cmd.hasOption("d")) { date = cmd.getOptionValue("d"); }
if (cmd.hasOption("s")) { state = cmd.getOptionValue("s"); }
if (cmd.hasOption("k")) { apiKey = cmd.getOptionValue("k"); }
// History Feature
if (cmd.hasOption("f") && feature.equals("history")) { // Check hasOption to avoid Null Pointer Exception
historicalData(apiKey, city, state, date);
} else if (cmd.hasOption("h")) {
formater.printHelp("Query Wunderground for weather data", options);
}
}
}
Wunderground Class/API Interface
public class WundergroundData {
private static final String PROTOCOL = "Http";
private static final String WU_HOST = "api.wunderground.com";
private String apiKey; // Wunderground requires a registered key to use services
public void setApiKey(String apiKey) {
this.apiKey = apiKey;
}
public String getApiKey() {
return apiKey;
}
public URL createUrl(String feature) throws MalformedURLException {
String relativePath = new String(String.format("/api/%s/%s", apiKey, feature));
URL url = new URL(PROTOCOL, WU_HOST, relativePath);
return url;
}
public JsonNode fetchHistorical(String city, String state, String date)
throws MalformedURLException, IOException {
URL url = createUrl(String.format("history_%s/q/%s/%s.json", date, state, city));
return JsonReader.readJsonFromUrl(url);
}
public WundergroundData() {
}
public WundergroundData(String key) {
setApiKey(key);
}
}
JSON Reader Class
public class JsonReader {
public static JsonNode readJsonFromFile(File file)
throws JsonProcessingException, IOException {
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(file);
return root;
}
public static JsonNode readJsonFromUrl(String url)
throws MalformedURLException, IOException {
InputStream inputStream = new URL(url).openStream();
ObjectMapper mapper = new ObjectMapper();
try {
JsonNode root = mapper.readTree(inputStream);
return root;
} finally {
inputStream.close();
}
}
public static JsonNode readJsonFromUrl(URL url)
throws MalformedURLException, IOException {
InputStream inputStream = url.openStream();
ObjectMapper mapper = new ObjectMapper();
try {
JsonNode root = mapper.readTree(inputStream);
return root;
} finally {
inputStream.close();
}
}
}