net.aksingh.java.api.owm.CurrentWeatherData.java Source code

Java tutorial

Introduction

Here is the source code for net.aksingh.java.api.owm.CurrentWeatherData.java

Source

/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2013-2014 Ashutosh Kumar Singh [me@aksingh.net]
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
*/

package net.aksingh.java.api.owm;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONObject;

/**
 * Parses current weather data (from the JSON data) and provides methods to
 * get/access the information about current weather. This class provides
 * <code>has</code> and <code>get</code> methods to access the information.
 * <p>
 * <p>
 * <code>has</code> methods can be used to check if the data exists, i.e., if
 * the data was available (successfully downloaded) and was parsed correctly.
 * <p>
 * <p>
 * <code>get</code> methods can be used to access the data, if the data exists,
 * otherwise <code>get</code> methods will give value as per following
 * basis:<br>
 * Boolean: <code>false</code><br>
 * Integral: Minimum value (MIN_VALUE)<br>
 * Floating point: Not a number (NaN)<br>
 * Others: <code>null</code><br>
 * <p>
 * @author Ashutosh Kumar Singh
 * @version 2013/08/07
 * @since 2.5.0.1
 */
public class CurrentWeatherData extends AbstractWeatherData {

    /**
     * Key for JSON object - Rain
     */
    private final String JSON_RAIN = "rain";
    /**
     * Key for JSON object - Sys
     */
    private final String JSON_SYS = "sys";

    /*
     ************************
     * Declaring sub-classes
     ************************
     */
    /**
     * Parses data about clouds (from the JSON data) and provides methods to
     * get/access the information. This class provides <code>has</code> and
     * <code>get</code> methods to access the information.
     * <p>
     * <p>
     * <code>has</code> methods can be used to check if the data exists, i.e.,
     * if the data was available (successfully downloaded) and was parsed
     * correctly.
     * <p>
     * <p>
     * <code>get</code> methods can be used to access the data, if the data
     * exists, otherwise <code>get</code> methods will give value as per
     * following basis:<br>
     * Boolean: <code>false</code><br>
     * Integral: Minimum value (MIN_VALUE)<br>
     * Floating point: Not a number (NaN)<br>
     * Others: <code>null</code><br>
     * <p>
     * @author Ashutosh Kumar Singh
     * @version 2013/08/07
     * @since 2.5.0.1
     */
    public static class Clouds extends AbstractWeatherData.Clouds {

        /**
         * Non-parameterized constructor
         * <p>
         * <p>
         * Initializes variables as per following basis:<br>
         * Boolean: <code>false</code><br>
         * Integral: Minimum value (MIN_VALUE)<br>
         * Floating point: Not a number (NaN)<br>
         * Others: <code>null</code><br>
         */
        public Clouds() {
            super();
        }

        /**
         * Parameterized constructor
         * <p>
         * Initializes variables from values from the given JSON object.
         * <p>
         * @param jsonObj JSON object containing data about clouds
         */
        public Clouds(JSONObject jsonObj) {
            super(jsonObj);
        }
    }

    /**
     * Parses data about geographic coordinates (from the JSON data) and
     * provides methods to get/access the information. This class provides
     * <code>has</code> and <code>get</code> methods to access the information.
     * <p>
     * <p>
     * <code>has</code> methods can be used to check if the data exists, i.e.,
     * if the data was available (successfully downloaded) and was parsed
     * correctly.
     * <p>
     * <p>
     * <code>get</code> methods can be used to access the data, if the data
     * exists, otherwise <code>get</code> methods will give value as per
     * following basis:<br>
     * Boolean: <code>false</code><br>
     * Integral: Minimum value (MIN_VALUE)<br>
     * Floating point: Not a number (NaN)<br>
     * Others: <code>null</code><br>
     * <p>
     * @author Ashutosh Kumar Singh
     * @version 2013/08/07
     * @since 2.5.0.1
     */
    public static class Coord extends AbstractWeatherData.Coord {

        /**
         * Non-parameterized constructor
         * <p>
         * <p>
         * Initializes variables as per following basis:<br>
         * Boolean: <code>false</code><br>
         * Integral: Minimum value (MIN_VALUE)<br>
         * Floating point: Not a number (NaN)<br>
         * Others: <code>null</code><br>
         */
        public Coord() {
            super();
        }

        /**
         * Parameterized constructor
         * <p>
         * Initializes variables from values from the given JSON object.
         * <p>
         * @param jsonObj JSON object containing data about coordinates
         */
        public Coord(JSONObject jsonObj) {
            super(jsonObj);
        }
    }

    /**
     * Parses data about main weather elements (from the JSON data) and provides
     * methods to get/access the information. This class provides
     * <code>has</code> and <code>get</code> methods to access the information.
     * <p>
     * <p>
     * <code>has</code> methods can be used to check if the data exists, i.e.,
     * if the data was available (successfully downloaded) and was parsed
     * correctly.
     * <p>
     * <p>
     * <code>get</code> methods can be used to access the data, if the data
     * exists, otherwise <code>get</code> methods will give value as per
     * following basis:<br>
     * Boolean: <code>false</code><br>
     * Integral: Minimum value (MIN_VALUE)<br>
     * Floating point: Not a number (NaN)<br>
     * Others: <code>null</code><br>
     * <p>
     * @author Ashutosh Kumar Singh
     * @version 2013/08/07
     * @since 2.5.0.1
     */
    public static class Main extends AbstractWeatherData.Main {

        /**
         * Non-parameterized constructor
         * <p>
         * <p>
         * Initializes variables as per following basis:<br>
         * Boolean: <code>false</code><br>
         * Integral: Minimum value (MIN_VALUE)<br>
         * Floating point: Not a number (NaN)<br>
         * Others: <code>null</code><br>
         */
        public Main() {
            super();
        }

        /**
         * Parameterized constructor
         * <p>
         * Initializes variables from values from the given JSON object.
         * <p>
         * @param jsonObj JSON object containing data about main weather
         *                elements (temperature, pressure, etc.)
         */
        public Main(JSONObject jsonObj) {
            super(jsonObj);
        }
    }

    /**
     * Parses data about rain (from the JSON data) and provides methods to
     * get/access the information. This class provides <code>has</code> and
     * <code>get</code> methods to access the information.
     * <p>
     * <p>
     * <code>has</code> methods can be used to check if the data exists, i.e.,
     * if the data was available (successfully downloaded) and was parsed
     * correctly.
     * <p>
     * <p>
     * <code>get</code> methods can be used to access the data, if the data
     * exists, otherwise <code>get</code> methods will give value as per
     * following basis:<br>
     * Boolean: <code>false</code><br>
     * Integral: Minimum value (MIN_VALUE)<br>
     * Floating point: Not a number (NaN)<br>
     * Others: <code>null</code><br>
     * <p>
     * @author Ashutosh Kumar Singh
     * @version 2013/08/07
     * @since 2.5.0.1
     */
    public static class Rain {

        /**
         * Key for JSON variable <code>Rain -> Rain per 3 hours</code>
         */
        private final String JSON_RAIN_3HOURS = "3h";

        /**
         * Rain per 3 hours
         */
        private final float rain3h;

        /**
         * Non-parameterized constructor
         * <p>
         * <p>
         * Initializes variables as per following basis:<br>
         * Boolean: <code>false</code><br>
         * Integral: Minimum value (MIN_VALUE)<br>
         * Floating point: Not a number (NaN)<br>
         * Others: <code>null</code><br>
         */
        public Rain() {
            this.rain3h = Float.NaN;
        }

        /**
         * Parameterized constructor
         * <p>
         * Initializes variables from values from the given JSON object.
         * <p>
         * @param jsonObj JSON object containing data about rain
         */
        public Rain(JSONObject jsonObj) {
            this.rain3h = (float) jsonObj.optDouble(this.JSON_RAIN_3HOURS, Double.NaN);
        }

        public boolean hasRain3Hours() {
            return (this.rain3h != Float.NaN);
        }

        public float getRain3Hours() {
            return this.rain3h;
        }
    }

    /**
     * Parses data about country, sunrise, and sunset (from the JSON data) and
     * provides methods to get/access the information. This class provides
     * <code>has</code> and <code>get</code> methods to access the information.
     * <p>
     * <p>
     * <code>has</code> methods can be used to check if the data exists, i.e.,
     * if the data was available (successfully downloaded) and was parsed
     * correctly.
     * <p>
     * <p>
     * <code>get</code> methods can be used to access the data, if the data
     * exists, otherwise <code>get</code> methods will give value as per
     * following basis:<br>
     * Boolean: <code>false</code><br>
     * Integral: Minimum value (MIN_VALUE)<br>
     * Floating point: Not a number (NaN)<br>
     * Others: <code>null</code><br>
     * <p>
     * @author Ashutosh Kumar Singh
     * @version 2013/08/07
     * @since 2.5.0.1
     */
    public static class Sys {

        /**
         * Key for JSON variable <code>Sys -> Country</code>
         */
        private final String JSON_SYS_COUNTRY_CODE = "country";
        /**
         * Key for JSON variable <code>Sys -> Sunrise</code>
         */
        private final String JSON_SYS_SUNRISE = "sunrise";
        /**
         * Key for JSON variable <code>Sys -> Sunset</code>
         */
        private final String JSON_SYS_SUNSET = "sunset";

        /**
         * Country code for the city
         */
        private final String countryCode;
        /**
         * Sunrise time
         */
        private final Date sunrise;
        /**
         * Sunset time
         */
        private final Date sunset;

        /**
         * Non-parameterized constructor
         * <p>
         * <p>
         * Initializes variables as per following basis:<br>
         * Boolean: <code>false</code><br>
         * Integral: Minimum value (MIN_VALUE)<br>
         * Floating point: Not a number (NaN)<br>
         * Others: <code>null</code><br>
         */
        public Sys() {
            this.countryCode = null;
            this.sunrise = null;
            this.sunset = null;
        }

        /**
         * Parameterized constructor
         * <p>
         * Initializes variables from values from the given JSON object.
         * <p>
         * @param jsonObj JSON object containing data about country, sunrise,
         *                and sunset.
         */
        public Sys(JSONObject jsonObj) {
            this.countryCode = jsonObj.optString(this.JSON_SYS_COUNTRY_CODE, null);

            long sr_secs = jsonObj.optLong(this.JSON_SYS_SUNRISE, Long.MIN_VALUE);
            if (sr_secs != Long.MIN_VALUE) {
                /*
                 @bugfix Incorrect date and time
                 Issue: #3 given at http://code.aksingh.net/owm-japis/issue/3/problem-with-datetime
                 Incorrect: this.sunrise = new Date(sr_secs);
                 Correct: this.sunrise = new Date(sr_secs * 1000);
                 Reason: Date requires milliseconds but previously, seconds were provided.
                 */
                this.sunrise = new Date(sr_secs * 1000);
            } else {
                this.sunrise = null;
            }

            long ss_secs = jsonObj.optLong(this.JSON_SYS_SUNSET, Long.MIN_VALUE);
            if (ss_secs != Long.MIN_VALUE) {
                /*
                 @bugfix Incorrect date and time
                 Issue: #3 given at http://code.aksingh.net/owm-japis/issue/3/problem-with-datetime
                 Incorrect: this.sunrise = new Date(ss_secs);
                 Correct: this.sunrise = new Date(ss_secs * 1000);
                 Reason: Date requires milliseconds but previously, seconds were provided.
                 */
                this.sunset = new Date(ss_secs * 1000);
            } else {
                this.sunset = null;
            }
        }

        public boolean hasCountryCode() {
            return (this.countryCode != null);
        }

        public boolean hasSunriseTime() {
            return (this.sunrise != null);
        }

        public boolean hasSunsetTime() {
            return (this.sunset != null);
        }

        public String getCountryCode() {
            return this.countryCode;
        }

        public Date getSunriseTime() {
            return this.sunrise;
        }

        public Date getSunsetTime() {
            return this.sunset;
        }
    }

    /**
     * Parses data about weather code, name, etc. (from the JSON data) and
     * provides methods to get/access the information. This class provides
     * <code>has</code> and <code>get</code> methods to access the information.
     * <p>
     * <p>
     * <code>has</code> methods can be used to check if the data exists, i.e.,
     * if the data was available (successfully downloaded) and was parsed
     * correctly.
     * <p>
     * <p>
     * <code>get</code> methods can be used to access the data, if the data
     * exists, otherwise <code>get</code> methods will give value as per
     * following basis:<br>
     * Boolean: <code>false</code><br>
     * Integral: Minimum value (MIN_VALUE)<br>
     * Floating point: Not a number (NaN)<br>
     * Others: <code>null</code><br>
     * <p>
     * @author Ashutosh Kumar Singh
     * @version 2013/08/07
     * @since 2.5.0.1
     */
    public static class Weather extends AbstractWeatherData.Weather {

        /**
         * Non-parameterized constructor
         * <p>
         * <p>
         * Initializes variables as per following basis:<br>
         * Boolean: <code>false</code><br>
         * Integral: Minimum value (MIN_VALUE)<br>
         * Floating point: Not a number (NaN)<br>
         * Others: <code>null</code><br>
         */
        public Weather() {
            super();
        }

        /**
         * Parameterized constructor
         * <p>
         * Initializes variables from values from the given JSON object.
         * <p>
         * @param jsonObj JSON object containing data about weather id, name,
         *                etc.
         */
        public Weather(JSONObject jsonObj) {
            super(jsonObj);
        }
    }

    /**
     * Parses data about winds (from the JSON data) and provides methods to
     * get/access the information. This class provides <code>has</code> and
     * <code>get</code> methods to access the information.
     * <p>
     * <p>
     * <code>has</code> methods can be used to check if the data exists, i.e.,
     * if the data was available (successfully downloaded) and was parsed
     * correctly.
     * <p>
     * <p>
     * <code>get</code> methods can be used to access the data, if the data
     * exists, otherwise <code>get</code> methods will give value as per
     * following basis:<br>
     * Boolean: <code>false</code><br>
     * Integral: Minimum value (MIN_VALUE)<br>
     * Floating point: Not a number (NaN)<br>
     * Others: <code>null</code><br>
     * <p>
     * @author Ashutosh Kumar Singh
     * @version 2013/08/07
     * @since 2.5.0.1
     */
    public static class Wind extends AbstractWeatherData.Wind {

        /**
         * Key for JSON variable <code>Wind -> Gust</code>
         */
        private final String JSON_WIND_GUST = "gust";

        /**
         * Wind gust
         */
        private final float gust;

        /**
         * Non-parameterized constructor
         * <p>
         * <p>
         * Initializes variables as per following basis:<br>
         * Boolean: <code>false</code><br>
         * Integral: Minimum value (MIN_VALUE)<br>
         * Floating point: Not a number (NaN)<br>
         * Others: <code>null</code><br>
         */
        public Wind() {
            super();

            this.gust = Float.NaN;
        }

        /**
         * Parameterized constructor
         * <p>
         * Initializes variables from values from the given JSON object.
         * <p>
         * @param jsonObj JSON object containing data about wind
         */
        public Wind(JSONObject jsonObj) {
            super(jsonObj);

            this.gust = (float) jsonObj.optDouble(this.JSON_WIND_GUST, Double.NaN);
        }

        public boolean hasWindGust() {
            return (this.gust != Float.NaN);
        }

        public float getWindGust() {
            return this.gust;
        }
    }

    /*
     ***********************
     * Declaring this class
     ***********************
     */
    /**
     * Key for JSON variable <code>Base</code>
     */
    private final String JSON_BASE = "base";
    /**
     * Key for JSON variable <code>City code (ID)</code>
     */
    private final String JSON_CITY_ID = "id";
    /**
     * Key for JSON variable <code>City name</code>
     */
    private final String JSON_CITY_NAME = "name";
    /**
     * Key for JSON variable <code>Response code</code>
     */
    private final String JSON_RESPONSE_CODE = "cod";

    /**
     * Base
     */
    private final String base;
    /**
     * City code (ID)
     */
    private final long cityID;
    /**
     * City name
     */
    private final String cityName;
    /**
     * Response code
     */
    private final int responseCode;

    private final Clouds clouds;
    private final Coord coord;
    private final Main main;
    private final Rain rain;
    private final Sys sys;
    private final Wind wind;

    /**
     * List of weather information (code, name, etc.)
     */
    private final List<Weather> weatherList;
    /**
     * Count (number) of elements in list of weather information
     */
    private final int weatherListCount;

    /**
     * Parameterized constructor
     * <p>
     * Initializes variables from values from the given JSON object.
     * <p>
     * @param jsonObj JSON object containing current weather data
     */
    public CurrentWeatherData(JSONObject jsonObj) {
        super(jsonObj);

        this.base = (jsonObj != null) ? jsonObj.optString(this.JSON_BASE, null) : null;
        this.cityID = (jsonObj != null) ? jsonObj.optLong(this.JSON_CITY_ID, Long.MIN_VALUE) : Long.MIN_VALUE;
        this.cityName = (jsonObj != null) ? jsonObj.optString(this.JSON_CITY_NAME, null) : null;
        this.responseCode = (jsonObj != null) ? jsonObj.optInt(this.JSON_RESPONSE_CODE, Integer.MIN_VALUE)
                : Integer.MIN_VALUE;

        JSONObject jsonObjClouds = (jsonObj != null) ? jsonObj.optJSONObject(this.JSON_CLOUDS) : null;
        this.clouds = (jsonObjClouds != null) ? new Clouds(jsonObjClouds) : new Clouds();

        JSONObject jsonObjCoord = (jsonObj != null) ? jsonObj.optJSONObject(this.JSON_COORD) : null;
        this.coord = (jsonObjCoord != null) ? new Coord(jsonObjCoord) : new Coord();

        JSONObject jsonObjMain = (jsonObj != null) ? jsonObj.optJSONObject(this.JSON_MAIN) : null;
        this.main = (jsonObjMain != null) ? new Main(jsonObjMain) : new Main();

        JSONObject jsonObjRain = (jsonObj != null) ? jsonObj.optJSONObject(this.JSON_RAIN) : null;
        this.rain = (jsonObjRain != null) ? new Rain(jsonObjRain) : new Rain();

        JSONObject jsonObjSys = (jsonObj != null) ? jsonObj.optJSONObject(this.JSON_SYS) : null;
        this.sys = (jsonObjSys != null) ? new Sys(jsonObjSys) : new Sys();

        JSONArray jsonArrWeather = (jsonObj != null) ? jsonObj.optJSONArray(this.JSON_WEATHER) : null;
        this.weatherList = (jsonArrWeather != null) ? new ArrayList<Weather>(jsonArrWeather.length())
                : Collections.EMPTY_LIST;
        if (this.weatherList != Collections.EMPTY_LIST) {
            for (int i = 0; i < jsonArrWeather.length(); i++) {
                JSONObject jsonObjWeather = jsonArrWeather.optJSONObject(i);
                if (jsonObjWeather != null) {
                    this.weatherList.add(new Weather(jsonObjWeather));
                }
            }
        }
        this.weatherListCount = this.weatherList.size();

        JSONObject jsonObjWind = (jsonObj != null) ? jsonObj.optJSONObject(this.JSON_WIND) : null;
        this.wind = (jsonObjWind != null) ? new Wind(jsonObjWind) : new Wind();
    }

    public boolean hasBaseStation() {
        return (this.base != null);
    }

    public boolean hasCityCode() {
        return (this.cityID != Long.MIN_VALUE);
    }

    public boolean hasCityName() {
        return (this.cityName != null);
    }

    public boolean hasResponseCode() {
        return (this.responseCode != Integer.MIN_VALUE);
    }

    public String getBaseStation() {
        return this.base;
    }

    public long getCityCode() {
        return this.cityID;
    }

    public String getCityName() {
        return this.cityName;
    }

    public int getResponseCode() {
        return this.responseCode;
    }

    // Objects
    public Clouds getCloudsObject() {
        return this.clouds;
    }

    public Coord getCoordObject() {
        return this.coord;
    }

    public Main getMainObject() {
        return this.main;
    }

    public Rain getRainObject() {
        return this.rain;
    }

    public Sys getSysDataObject() {
        return this.sys;
    }

    public Wind getWindObject() {
        return this.wind;
    }

    // Lists
    public boolean hasWeatherList() {
        return (this.weatherListCount != 0);
    }

    public int getWeatherListCount() {
        return this.weatherListCount;
    }

    public List<Weather> getWeatherList() {
        return this.weatherList;
    }
}