Java tutorial
/* * 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.List; import org.json.JSONArray; import org.json.JSONObject; /** * Parses daily forecast data (from the JSON data) and provides methods to * get/access the information about daily forecasted 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> * Objects: Data initialized with default/non-parameterized constructor<br> * Others: <code>null</code><br> * <p> * @author Ashutosh Kumar Singh * @version 2013/08/07 * @since 2.5.0.1 */ public class DailyForecastData { /** * Key for JSON object - City */ private final String JSON_CITY = "city"; /** * Key for JSON object - List of forecasts */ private final String JSON_FORECAST_LIST = "list"; /* ************************ * Declaring sub-classes ************************ */ /** * Parses data about city (from the JSON data) and provides methods to * get/access the information. For example, city name, coordinates, country * name, population, etc. 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 City { /** * Key for JSON object - Coordinates */ private final String JSON_CITY_COORD = "coord"; /** * 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 clouds */ public Coord(JSONObject jsonObj) { super(jsonObj); } } /** * 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>Country code of city</code> */ private final String JSON_CITY_COUNTRY_CODE = "country"; /** * Key for JSON variable <code>Population of city</code> */ private final String JSON_CITY_POPULATION = "population"; /** * City code (ID) */ private final long cityID; /** * City name */ private final String cityName; /** * Country code of city */ private final String countryCode; /** * Population of city */ private final long population; private final Coord 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 City() { this.cityID = Long.MIN_VALUE; this.cityName = null; this.countryCode = null; this.population = Long.MIN_VALUE; this.coord = new Coord(); } /** * Parameterized constructor * <p> * Initializes variables from values from the given JSON object. * <p> * @param jsonObj JSON object containing data about city */ public City(JSONObject jsonObj) { 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.countryCode = (jsonObj != null) ? jsonObj.optString(this.JSON_CITY_COUNTRY_CODE, null) : null; this.population = (jsonObj != null) ? jsonObj.optLong(this.JSON_CITY_POPULATION, Long.MIN_VALUE) : Long.MIN_VALUE; JSONObject jsonObjCoord = (jsonObj != null) ? jsonObj.optJSONObject(this.JSON_CITY_COORD) : null; this.coord = (jsonObjCoord != null) ? new Coord(jsonObjCoord) : new Coord(); } public boolean hasCityCode() { return (this.cityID != Long.MIN_VALUE); } public boolean hasCityName() { return (this.cityName != null); } public boolean hasCountryCode() { return (this.countryCode != null); } public boolean hasCityPopulation() { return (this.population != Long.MIN_VALUE); } public long getCityCode() { return this.cityID; } public String getCityName() { return this.cityName; } public String getCountryCode() { return this.countryCode; } public long getCityPopulation() { return this.population; } // Objects public Coord getCoordinates_Object() { return this.coord; } } /** * Parses data about forecasts (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 Forecast extends AbstractWeatherData { /** * Key for JSON object - Temperature */ public final String JSON_TEMP = "temp"; /* *************************** * Declaring sub-sub-classes *************************** */ /** * Parses data about weather (from the JSON data) and provides methods * to get/access the information. For example, weather id, name, etc. * 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 */ public Weather(JSONObject jsonObj) { super(jsonObj); } } /** * Parses data about temperature (from the JSON data) and provides * methods to get/access the information. For example, weather id, name, * etc. 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 Temperature { /** * Key for JSON variable <code>Temp -> Day</code> */ public final String JSON_TEMP_DAY = "day"; /** * Key for JSON variable <code>Temp -> Minimum</code> */ public final String JSON_TEMP_MIN = "min"; /** * Key for JSON variable <code>Temp -> Maximum</code> */ public final String JSON_TEMP_MAX = "max"; /** * Key for JSON variable <code>Temp -> Night</code> */ public final String JSON_TEMP_NIGHT = "night"; /** * Key for JSON variable <code>Temp -> Evening</code> */ public final String JSON_TEMP_EVENING = "eve"; /** * Key for JSON variable <code>Temp -> Morning</code> */ public final String JSON_TEMP_MORNING = "morn"; /** * Day temperature */ private final float dayTemp; /** * Minimum temperature */ private final float minTemp; /** * Maximum temperature */ private final float maxTemp; /** * Night temperature */ private final float nightTemp; /** * Evening temperature */ private final float eveTemp; /** * Morning temperature */ private final float mornTemp; /** * 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 Temperature() { this.dayTemp = Float.NaN; this.minTemp = Float.NaN; this.maxTemp = Float.NaN; this.nightTemp = Float.NaN; this.eveTemp = Float.NaN; this.mornTemp = Float.NaN; } /** * Parameterized constructor * <p> * Initializes variables from values from the given JSON object. * <p> * @param jsonObj JSON object containing data about temperature */ public Temperature(JSONObject jsonObj) { this.dayTemp = (jsonObj != null) ? (float) jsonObj.optDouble(this.JSON_TEMP_DAY, Double.NaN) : Float.NaN; this.minTemp = (jsonObj != null) ? (float) jsonObj.optDouble(this.JSON_TEMP_MIN, Double.NaN) : Float.NaN; this.maxTemp = (jsonObj != null) ? (float) jsonObj.optDouble(this.JSON_TEMP_MAX, Double.NaN) : Float.NaN; this.nightTemp = (jsonObj != null) ? (float) jsonObj.optDouble(this.JSON_TEMP_NIGHT, Double.NaN) : Float.NaN; this.eveTemp = (jsonObj != null) ? (float) jsonObj.optDouble(this.JSON_TEMP_EVENING, Double.NaN) : Float.NaN; this.mornTemp = (jsonObj != null) ? (float) jsonObj.optDouble(this.JSON_TEMP_MORNING, Double.NaN) : Float.NaN; } public boolean hasDayTemperature() { return (this.dayTemp != Float.NaN); } public boolean hasMinimumTemperature() { return (this.minTemp != Float.NaN); } public boolean hasMaximumTemperature() { return (this.maxTemp != Float.NaN); } public boolean hasNightTemperature() { return (this.nightTemp != Float.NaN); } public boolean hasEveningTemperature() { return (this.eveTemp != Float.NaN); } public boolean hasMorningTemperature() { return (this.mornTemp != Float.NaN); } public float getDayTemperature() { return this.dayTemp; } public float getMinimumTemperature() { return this.minTemp; } public float getMaximumTemperature() { return this.maxTemp; } public float getNightTemperature() { return this.nightTemp; } public float getEveningTemperature() { return this.eveTemp; } public float getMorningTemperature() { return this.mornTemp; } } /* ************************ * Declaring this sub-class ************************ */ /** * Key for JSON variable <code>Pressure</code> */ private final String JSON_FORECAST_PRESSURE = "pressure"; /** * Key for JSON variable <code>Humidity</code> */ private final String JSON_FORECAST_HUMIDITY = "humidity"; /** * Key for JSON variable <code>Wind speed</code> */ private final String JSON_FORECAST_WIND_SPEED = "speed"; /** * Key for JSON variable <code>Wind degree</code> */ private final String JSON_FORECAST_WIND_DEGREE = "deg"; /** * Key for JSON variable <code>Percentage of clouds</code> */ private final String JSON_FORECAST_CLOUDS = "clouds"; /** * Pressure */ private final float pressure; /** * Humidity */ private final float humidity; /** * Wind speed */ private final float windSpeed; /** * Wind degree */ private final float windDegree; /** * Percentage of clouds */ private final float cloudsPercent; private final Temperature temp; /** * 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; /** * 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 Forecast() { super(); this.pressure = Float.NaN; this.humidity = Float.NaN; this.windSpeed = Float.NaN; this.windDegree = Float.NaN; this.cloudsPercent = Float.NaN; this.temp = new Temperature(); this.weatherList = Collections.EMPTY_LIST; this.weatherListCount = this.weatherList.size(); } /** * Parameterized constructor * <p> * Initializes variables from values from the given JSON object. * <p> * @param jsonObj JSON object containing data about forecasts */ public Forecast(JSONObject jsonObj) { super(jsonObj); JSONObject jsonObjTemp = (jsonObj != null) ? jsonObj.optJSONObject(this.JSON_TEMP) : null; this.temp = (jsonObjTemp != null) ? new Temperature(jsonObjTemp) : new Temperature(); this.humidity = (jsonObj != null) ? (float) jsonObj.optDouble(this.JSON_FORECAST_HUMIDITY, Double.NaN) : Float.NaN; this.pressure = (jsonObj != null) ? (float) jsonObj.optDouble(this.JSON_FORECAST_PRESSURE, Double.NaN) : Float.NaN; this.windSpeed = (jsonObj != null) ? (float) jsonObj.optDouble(this.JSON_FORECAST_WIND_SPEED, Double.NaN) : Float.NaN; this.windDegree = (jsonObj != null) ? (float) jsonObj.optDouble(this.JSON_FORECAST_WIND_DEGREE, Double.NaN) : Float.NaN; this.cloudsPercent = (jsonObj != null) ? (float) jsonObj.optDouble(this.JSON_FORECAST_CLOUDS, Double.NaN) : Float.NaN; 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(); } public boolean hasHumidity() { return (this.humidity != Float.NaN); } public boolean hasPressure() { return (this.pressure != Float.NaN); } public boolean hasWindSpeed() { return (this.windSpeed != Float.NaN); } public boolean hasWindDegree() { return (this.windDegree != Float.NaN); } public boolean hasPercentageOfClouds() { return (this.cloudsPercent != Float.NaN); } public float getHumidity() { return this.humidity; } public float getPressure() { return this.pressure; } public float getWindSpeed() { return this.windSpeed; } public float getWindDegree() { return this.windDegree; } public float getPercentageOfClouds() { return this.cloudsPercent; } // Objects public Temperature getTemperature_Object() { return this.temp; } // Lists public boolean hasWeather_List() { return (this.weatherListCount != 0); } public int getWeather_List_Count() { return this.weatherListCount; } public List<Weather> getWeather_List() { return this.weatherList; } } /* *********************** * Declaring this class *********************** */ /** * Key for JSON variable <code>Response code</code> */ private final String JSON_RESPONSE_CODE = "cod"; /** * Key for JSON variable <code>Response time</code> */ private final String JSON_RESPONSE_TIME = "message"; /** * Key for JSON variable <code>Forecast count</code> */ private final String JSON_RESPONSE_FORECAST_COUNT = "cnt"; /** * Response code */ private final String responseCode; /** * Response time */ private final float responseTime; /** * Forecast count */ private final int responseForecastCount; private final City city; /** * List of forecast information */ private final List<Forecast> forecastList; /** * Count (number) of elements in list of forecast information */ private final int forecastListCount; /** * Parameterized constructor * <p> * Initializes variables from values from the given JSON object. * <p> * @param jsonObj JSON object containing data about daily forecasts */ public DailyForecastData(JSONObject jsonObj) { this.responseCode = (jsonObj != null) ? jsonObj.optString(this.JSON_RESPONSE_CODE, null) : null; this.responseTime = (jsonObj != null) ? (float) jsonObj.optDouble(this.JSON_RESPONSE_TIME, Double.NaN) : Float.NaN; this.responseForecastCount = (jsonObj != null) ? jsonObj.optInt(this.JSON_RESPONSE_FORECAST_COUNT, Integer.MIN_VALUE) : Integer.MIN_VALUE; JSONObject jsonObjCity = (jsonObj != null) ? jsonObj.optJSONObject(this.JSON_CITY) : null; this.city = (jsonObjCity != null) ? new City(jsonObjCity) : new City(); JSONArray jsonArrForecast = (jsonObj != null) ? jsonObj.optJSONArray(this.JSON_FORECAST_LIST) : null; this.forecastList = (jsonArrForecast != null) ? new ArrayList<Forecast>(jsonArrForecast.length()) : Collections.EMPTY_LIST; if (this.forecastList != Collections.EMPTY_LIST) { for (int i = 0; i < jsonArrForecast.length(); i++) { JSONObject jsonObjWeather = jsonArrForecast.optJSONObject(i); if (jsonObjWeather != null) { this.forecastList.add(new Forecast(jsonObjWeather)); } } } this.forecastListCount = this.forecastList.size(); } public boolean hasResponseCode() { return (this.responseCode != null); } public boolean hasResponseTime() { return (this.responseTime != Float.NaN); } public boolean hasResponseForecastCount() { return (this.responseForecastCount != Integer.MIN_VALUE); } public String getResponseCode() { return this.responseCode; } public float getResponseTime() { return this.responseTime; } public int getResponseForecastCount() { return this.responseForecastCount; } // Objects public City getCity_Object() { return this.city; } // Lists public boolean hasForecast_List() { return (this.forecastListCount != 0); } public int getForecast_List_Count() { return this.forecastListCount; } public List<Forecast> getForecast_List() { return this.forecastList; } }