Java tutorial
/* * Copyright (c) 2014 Yehezkel (Zack) Yovel * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package zack.yovel.clear.infrastructure.model.datapoints; import android.util.Log; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import zack.yovel.clear.infrastructure.model.GenericParserInterface; public class ForecastIoParser implements GenericParserInterface<WeatherReport> { private static final String TAG = "ForecastIoParser"; @Override public WeatherReport parse(String response) { WeatherReport output = new WeatherReport(); JsonReader reader = new JsonReader(new InputStreamReader(new ByteArrayInputStream(response.getBytes()))); try { JsonToken token = reader.peek(); switch (token) { case BEGIN_OBJECT: doParse(reader, output); break; default: // In case api changes and we receive a different json structure, skip a value (and basically break down gracefully). Log.d(TAG, "parse found a different json structure. Root element is not an object."); reader.skipValue(); } } catch (IOException e) { // No real IO operations are done here, hence no exception should be thrown. Log.e(TAG, "parse failed with exception: " + e.getMessage()); } return output; } private void doParse(JsonReader reader, WeatherReport output) throws IOException { reader.beginObject(); while (reader.hasNext()) { String name = reader.nextName(); if (name.equals("latitude")) { output.setLatitude(reader.nextDouble()); } else if (name.equals("longitude")) { output.setLongitude(reader.nextDouble()); } else if (name.equals("currently")) { output.setCurrently(parseDataPoint(reader)); } else if (name.equals("hourly")) { output.setHourly(parseDataBlock(reader)); } else if (name.equals("daily")) { output.setDaily(parseDataBlock(reader)); } else if (name.equals("alerts")) { output.setAlerts(parseAlerts(reader)); } else { reader.skipValue(); } } reader.endObject(); } private ArrayList<Alert> parseAlerts(JsonReader reader) throws IOException { ArrayList<Alert> output = new ArrayList<Alert>(); reader.beginArray(); boolean exit = false; while (!exit && reader.hasNext()) { JsonToken token = reader.peek(); switch (token) { case BEGIN_OBJECT: output.add(parseAlert(reader)); break; case END_ARRAY: exit = true; break; default: reader.skipValue(); } } reader.endArray(); return output; } private Alert parseAlert(JsonReader reader) throws IOException { Alert output = new Alert(); reader.beginObject(); String name = reader.nextName(); if (name.equals("title")) { output.setTitle(reader.nextString()); } else if (name.equals("expires")) { output.setExpires(reader.nextLong()); } else if (name.equals("description")) { output.setDescription(reader.nextString()); } else if (name.equals("uri")) { output.setUri(reader.nextString()); } else { reader.skipValue(); } reader.endObject(); return output; } private DataBlock parseDataBlock(JsonReader reader) throws IOException { DataBlock output = new DataBlock(); reader.beginObject(); while (reader.hasNext()) { JsonToken token = reader.peek(); if (token == JsonToken.END_OBJECT) { break; } getDataBlockProperty(reader, output); } reader.endObject(); return output; } private void getDataBlockProperty(JsonReader reader, DataBlock output) throws IOException { String name = reader.nextName(); if (name.equals("icon")) { output.setIcon(reader.nextString()); } else if (name.equals("data")) { output.setData(getDataPointList(reader)); } else { reader.skipValue(); } } private ArrayList<DataPoint> getDataPointList(JsonReader reader) throws IOException { ArrayList<DataPoint> output = new ArrayList<DataPoint>(); reader.beginArray(); while (reader.hasNext()) { JsonToken token = reader.peek(); switch (token) { case BEGIN_OBJECT: output.add(parseDataPoint(reader)); break; default: reader.skipValue(); } } reader.endArray(); return output; } private DataPoint parseDataPoint(JsonReader reader) throws IOException { DataPoint output = new DataPoint(); reader.beginObject(); boolean exit = false; while (!exit && reader.hasNext()) { JsonToken token = reader.peek(); if (token == JsonToken.END_OBJECT) { break; } getDataPointProperty(reader, output); } reader.endObject(); return output; } private void getDataPointProperty(JsonReader reader, DataPoint output) throws IOException { String name = reader.nextName(); if (name.equals("time")) { output.setTime(reader.nextLong() * 1000); // forecast api gives time in seconds, while Java, Android and joda time work with milliseconds... } else if (name.equals("icon")) { output.setIcon(reader.nextString()); } /*else if (name.equals("precipIntensity")) { output.setPrecipIntensity(reader.nextDouble()); } else if (name.equals("precipProbability")) { output.setPrecipProbability(reader.nextDouble()); } else if (name.equals("precipType")) { output.setPrecipType(reader.nextString()); } else if (name.equals("precipAccumulation")) { output.setPrecipAccumulation(reader.nextDouble()); }*/ else if (name.equals("temperature")) { output.setTemperature(reader.nextDouble()); } else if (name.equals("temperatureMin")) { output.setTemperatureMin(reader.nextDouble()); } else if (name.equals("temperatureMinTime")) { output.setTemperatureMinTime(reader.nextLong()); } else if (name.equals("temperatureMax")) { output.setTemperatureMax(reader.nextDouble()); } else if (name.equals("temperatureMaxTime")) { output.setTemperatureMaxTime(reader.nextLong()); } else if (name.equals("apparentTemperature")) { output.setApparentTemperature(reader.nextDouble()); } else if (name.equals("apparentTemperatureMin")) { output.setApparentTemperatureMin(reader.nextDouble()); } else if (name.equals("apparentTemperatureMax")) { output.setApparentTemperatureMax(reader.nextDouble()); } else if (name.equals("apparentTemperatureMaxTime")) { output.setApparentTemperatureMaxTime(reader.nextLong()); } else if (name.equals("windSpeed")) { output.setWindSpeed(reader.nextDouble()); } else if (name.equals("windBearing")) { output.setWindBearing(reader.nextDouble()); } /*else if (name.equals("cloudCover")) { output.setCloudCover(reader.nextDouble()); }*/ else if (name.equals("humidity")) { output.setHumidity(reader.nextDouble()); } else { reader.skipValue(); } } }