net.aksingh.owmjapis.HourlyForecast.java Source code

Java tutorial

Introduction

Here is the source code for net.aksingh.owmjapis.HourlyForecast.java

Source

/*
 * Copyright (c) 2013-2015 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.owmjapis;

import org.json.JSONArray;
import org.json.JSONObject;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * <p>
 * Parses hourly forecast data and provides methods to get/access the same 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.
 * <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:
 * Boolean: <code>false</code>
 * Integral: Minimum value (MIN_VALUE)
 * Floating point: Not a number (NaN)
 * Others: <code>null</code>
 * </p>
 *
 * @author Ashutosh Kumar Singh
 * @version 2014/12/27
 * @see <a href="http://openweathermap.org/forecast">OWM's Weather Forecast API</a>
 * @since 2.5.0.3
 */
public class HourlyForecast extends AbstractForecast {
    /*
    Instance variables
     */
    private final List<Forecast> forecastList;

    /*
    Constructor
     */
    HourlyForecast(JSONObject jsonObj) {
        super(jsonObj);

        JSONArray forecastArr = (jsonObj != null) ? jsonObj.optJSONArray(this.JSON_FORECAST_LIST) : new JSONArray();
        this.forecastList = (forecastArr != null) ? new ArrayList<Forecast>(forecastArr.length())
                : Collections.EMPTY_LIST;
        if (forecastArr != null && this.forecastList != Collections.EMPTY_LIST) {
            for (int i = 0; i < forecastArr.length(); i++) {
                JSONObject forecastObj = forecastArr.optJSONObject(i);
                if (forecastObj != null) {
                    this.forecastList.add(new Forecast(forecastObj));
                }
            }
        }
    }

    /**
     * @param index Index of Forecast instance in the list.
     * @return Forecast instance if available, otherwise <code>null</code>.
     */
    public Forecast getForecastInstance(int index) {
        return this.forecastList.get(index);
    }

    /**
     * <p>
     * Parses forecast data (one element in the forecastList) and provides methods to get/access the same 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.
     * <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:
     * Boolean: <code>false</code>
     * Integral: Minimum value (MIN_VALUE)
     * Floating point: Not a number (NaN)
     * Others: <code>null</code>
     * </p>
     */
    public static class Forecast extends AbstractForecast.Forecast {
        /*
        JSON Keys
         */
        private static final String JSON_SYS = "sys";
        private static final String JSON_DT_TEXT = "dt_txt";

        /*
        Instance Variables
         */
        private final String dateTimeText;

        private final Clouds clouds;
        private final Main main;
        private final Sys sys;
        private final Wind wind;

        /*
        Constructor
         */
        Forecast(JSONObject jsonObj) {
            super(jsonObj);

            this.dateTimeText = (jsonObj != null) ? jsonObj.optString(JSON_DT_TEXT, null) : null;

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

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

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

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

        public boolean hasDateTimeText() {
            return this.dateTimeText != null;
        }

        /**
         * @return <code>true</code> if Clouds instance is available, otherwise <code>false</code>.
         */
        public boolean hasCloudsInstance() {
            return clouds != null;
        }

        /**
         * @return <code>true</code> if Main instance is available, otherwise <code>false</code>.
         */
        public boolean hasMainInstance() {
            return main != null;
        }

        /**
         * @return <code>true</code> if Sys instance is available, otherwise <code>false</code>.
         */
        public boolean hasSysInstance() {
            return sys != null;
        }

        /**
         * @return <code>true</code> if Wind instance is available, otherwise <code>false</code>.
         */
        public boolean hasWindInstance() {
            return wind != null;
        }

        public String getDateTimeText() {
            return this.dateTimeText;
        }

        /**
         * @return Clouds instance if available, otherwise <code>null</code>.
         */
        public Clouds getCloudsInstance() {
            return this.clouds;
        }

        /**
         * @return Main instance if available, otherwise <code>null</code>.
         */
        public Main getMainInstance() {
            return this.main;
        }

        /**
         * @return Sys instance if available, otherwise <code>null</code>.
         */
        public Sys getSysInstance() {
            return this.sys;
        }

        /**
         * @return Wind instance if available, otherwise <code>null</code>.
         */
        public Wind getWindInstance() {
            return this.wind;
        }

        /**
         * <p>
         * Parses clouds data and provides methods to get/access the same 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.
         * <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:
         * Boolean: <code>false</code>
         * Integral: Minimum value (MIN_VALUE)
         * Floating point: Not a number (NaN)
         * Others: <code>null</code>
         * </p>
         *
         * @author Ashutosh Kumar Singh
         * @version 2014/12/26
         * @since 2.5.0.1
         */
        public static class Clouds extends AbstractForecast.Forecast.Clouds {

            Clouds() {
                super();
            }

            Clouds(JSONObject jsonObj) {
                super(jsonObj);
            }
        }

        /**
         * <p>
         * Parses main data and provides methods to get/access the same 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.
         * <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:
         * Boolean: <code>false</code>
         * Integral: Minimum value (MIN_VALUE)
         * Floating point: Not a number (NaN)
         * Others: <code>null</code>
         * </p>
         *
         * @author Ashutosh Kumar Singh
         * @version 2014/12/26
         * @since 2.5.0.1
         */
        public static class Main extends AbstractForecast.Forecast.Main {
            private static final String JSON_MAIN_SEA_LEVEL = "sea_level";
            private static final String JSON_MAIN_GRND_LEVEL = "grnd_level";
            private static final String JSON_MAIN_TMP_KF = "temp_kf";

            private final float seaLevel;
            private final float groundLevel;
            private final float tempKF;

            Main() {
                super();

                this.seaLevel = Float.NaN;
                this.groundLevel = Float.NaN;
                this.tempKF = Float.NaN;
            }

            Main(JSONObject jsonObj) {
                super(jsonObj);

                this.seaLevel = (jsonObj != null) ? (float) jsonObj.optDouble(JSON_MAIN_SEA_LEVEL, Float.NaN)
                        : Float.NaN;
                this.groundLevel = (jsonObj != null) ? (float) jsonObj.optDouble(JSON_MAIN_GRND_LEVEL, Float.NaN)
                        : Float.NaN;
                this.tempKF = (jsonObj != null) ? (float) jsonObj.optDouble(JSON_MAIN_TMP_KF, Float.NaN)
                        : Float.NaN;
            }

            public boolean hasSeaLevel() {
                return !Float.isNaN(this.seaLevel);
            }

            public boolean hasGroundLevel() {
                return !Float.isNaN(this.groundLevel);
            }

            public boolean hasTempKF() {
                return !Float.isNaN(this.tempKF);
            }

            public float getSeaLevel() {
                return this.seaLevel;
            }

            public float getGroundLevel() {
                return this.groundLevel;
            }

            public float getTempKF() {
                return this.tempKF;
            }
        }

        /**
         * <p>
         * Parses sys data and provides methods to get/access the same 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.
         * <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:
         * Boolean: <code>false</code>
         * Integral: Minimum value (MIN_VALUE)
         * Floating point: Not a number (NaN)
         * Others: <code>null</code>
         * </p>
         *
         * @author Ashutosh Kumar Singh
         * @version 2014/12/26
         * @since 2.5.0.1
         */
        public static class Sys implements Serializable {
            private static final String JSON_SYS_POD = "pod";

            private final String pod;

            Sys() {
                this.pod = null;
            }

            Sys(JSONObject jsonObj) {
                this.pod = (jsonObj != null) ? jsonObj.optString(JSON_SYS_POD, null) : null;
            }

            public boolean hasPod() {
                return this.pod != null && (!"".equals(this.pod));
            }

            public String getPod() {
                return this.pod;
            }
        }

        /**
         * <p>
         * Parses wind data and provides methods to get/access the same 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.
         * <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:
         * Boolean: <code>false</code>
         * Integral: Minimum value (MIN_VALUE)
         * Floating point: Not a number (NaN)
         * Others: <code>null</code>
         * </p>
         *
         * @author Ashutosh Kumar Singh
         * @version 2014/12/26
         * @since 2.5.0.1
         */
        public static class Wind extends AbstractWeather.Wind {

            Wind() {
                super();
            }

            Wind(JSONObject jsonObj) {
                super(jsonObj);
            }
        }
    }
}