zack.yovel.clear.infrastructure.model.datapoints.ForecastIoParser.java Source code

Java tutorial

Introduction

Here is the source code for zack.yovel.clear.infrastructure.model.datapoints.ForecastIoParser.java

Source

/*
 * 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();
        }
    }
}