mirror of
https://bitbucket.org/akapribot/owm-japis.git
synced 2025-04-24 23:07:12 -07:00
613 lines
19 KiB
Java
613 lines
19 KiB
Java
/*
|
|
* 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.JSONObject;
|
|
|
|
import java.io.Serializable;
|
|
import java.util.Date;
|
|
|
|
/**
|
|
* <p>
|
|
* Parses current weather 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
|
|
* @see <a href="http://openweathermap.org/current">OWM's Current Weather API</a>
|
|
* @since 2.5.0.1
|
|
*/
|
|
public class CurrentWeather extends AbstractWeather {
|
|
/*
|
|
JSON Keys
|
|
*/
|
|
private static final String JSON_RAIN = "rain";
|
|
private static final String JSON_SNOW = "snow";
|
|
private static final String JSON_SYS = "sys";
|
|
private static final String JSON_BASE = "base";
|
|
private static final String JSON_CITY_ID = "id";
|
|
private static final String JSON_CITY_NAME = "name";
|
|
|
|
/*
|
|
Instance variables
|
|
*/
|
|
private final String base;
|
|
private final long cityId;
|
|
private final String cityName;
|
|
|
|
private final Clouds clouds;
|
|
private final Coord coord;
|
|
private final Main main;
|
|
private final Rain rain;
|
|
private final Snow snow;
|
|
private final Sys sys;
|
|
private final Wind wind;
|
|
|
|
/*
|
|
Constructor
|
|
*/
|
|
CurrentWeather(JSONObject jsonObj) {
|
|
super(jsonObj);
|
|
|
|
this.base = (jsonObj != null) ? jsonObj.optString(JSON_BASE, null) : null;
|
|
this.cityId = (jsonObj != null) ? jsonObj.optLong(JSON_CITY_ID, Long.MIN_VALUE) : Long.MIN_VALUE;
|
|
this.cityName = (jsonObj != null) ? jsonObj.optString(JSON_CITY_NAME, null) : null;
|
|
|
|
JSONObject cloudsObj = (jsonObj != null) ? jsonObj.optJSONObject(JSON_CLOUDS) : null;
|
|
this.clouds = (cloudsObj != null) ? new Clouds(cloudsObj) : null;
|
|
|
|
JSONObject coordObj = (jsonObj != null) ? jsonObj.optJSONObject(JSON_COORD) : null;
|
|
this.coord = (coordObj != null) ? new Coord(coordObj) : null;
|
|
|
|
JSONObject mainObj = (jsonObj != null) ? jsonObj.optJSONObject(JSON_MAIN) : null;
|
|
this.main = (mainObj != null) ? new Main(mainObj) : null;
|
|
|
|
JSONObject rainObj = (jsonObj != null) ? jsonObj.optJSONObject(JSON_RAIN) : null;
|
|
this.rain = (rainObj != null) ? new Rain(rainObj) : null;
|
|
|
|
JSONObject snowObj = (jsonObj != null) ? jsonObj.optJSONObject(JSON_SNOW) : null;
|
|
this.snow = (snowObj != null) ? new Snow(snowObj) : null;
|
|
|
|
JSONObject sysObj = (jsonObj != null) ? jsonObj.optJSONObject(JSON_SYS) : null;
|
|
this.sys = (sysObj != null) ? new Sys(sysObj) : null;
|
|
|
|
JSONObject windObj = (jsonObj != null) ? jsonObj.optJSONObject(JSON_WIND) : null;
|
|
this.wind = (windObj != null) ? new Wind(windObj) : null;
|
|
}
|
|
|
|
/**
|
|
* @return <code>true</code> if base station is available, otherwise <code>false</code>.
|
|
*/
|
|
public boolean hasBaseStation() {
|
|
return this.base != null && (! "".equals(this.base));
|
|
}
|
|
|
|
/**
|
|
* @return <code>true</code> if city code is available, otherwise <code>false</code>.
|
|
*/
|
|
public boolean hasCityCode() {
|
|
return this.cityId != Long.MIN_VALUE;
|
|
}
|
|
|
|
/**
|
|
* @return <code>true</code> if city name is available, otherwise <code>false</code>.
|
|
*/
|
|
public boolean hasCityName() {
|
|
return this.cityName != null && (! "".equals(this.cityName));
|
|
}
|
|
|
|
/**
|
|
* @return <code>true</code> if Clouds instance is available, otherwise <code>false</code>.
|
|
*/
|
|
public boolean hasCloudsInstance() {
|
|
return clouds != null;
|
|
}
|
|
|
|
/**
|
|
* @return <code>true</code> if Coord instance is available, otherwise <code>false</code>.
|
|
*/
|
|
public boolean hasCoordInstance() {
|
|
return coord != 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 Rain instance is available, otherwise <code>false</code>.
|
|
*/
|
|
public boolean hasRainInstance() {
|
|
return rain != null;
|
|
}
|
|
|
|
/**
|
|
* @return <code>true</code> if Snow instance is available, otherwise <code>false</code>.
|
|
*/
|
|
public boolean hasSnowInstance() {
|
|
return snow != 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;
|
|
}
|
|
|
|
/**
|
|
* @return Base station if available, otherwise <code>null</code>.
|
|
*/
|
|
public String getBaseStation() {
|
|
return this.base;
|
|
}
|
|
|
|
/**
|
|
* @return City code if available, otherwise <code>Long.MIN_VALUE</code>.
|
|
*/
|
|
public long getCityCode() {
|
|
return this.cityId;
|
|
}
|
|
|
|
/**
|
|
* @return City name if available, otherwise <code>null</code>.
|
|
*/
|
|
public String getCityName() {
|
|
return this.cityName;
|
|
}
|
|
|
|
/**
|
|
* @return Clouds instance if available, otherwise <code>null</code>.
|
|
*/
|
|
public Clouds getCloudsInstance() {
|
|
return this.clouds;
|
|
}
|
|
|
|
/**
|
|
* @return Coord instance if available, otherwise <code>null</code>.
|
|
*/
|
|
public Coord getCoordInstance() {
|
|
return this.coord;
|
|
}
|
|
|
|
/**
|
|
* @return Main instance if available, otherwise <code>null</code>.
|
|
*/
|
|
public Main getMainInstance() {
|
|
return this.main;
|
|
}
|
|
|
|
/**
|
|
* @return Rain instance if available, otherwise <code>null</code>.
|
|
*/
|
|
public Rain getRainInstance() {
|
|
return this.rain;
|
|
}
|
|
|
|
/**
|
|
* @return Snow instance if available, otherwise <code>null</code>.
|
|
*/
|
|
public Snow getSnowInstance() {
|
|
return this.snow;
|
|
}
|
|
|
|
/**
|
|
* @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 AbstractWeather.Clouds {
|
|
|
|
Clouds() {
|
|
super();
|
|
}
|
|
|
|
Clouds(JSONObject jsonObj) {
|
|
super(jsonObj);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Parses coordination 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 Coord extends AbstractWeather.Coord {
|
|
|
|
Coord() {
|
|
super();
|
|
}
|
|
|
|
Coord(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 AbstractWeather.Main {
|
|
|
|
Main() {
|
|
super();
|
|
}
|
|
|
|
Main(JSONObject jsonObj) {
|
|
super(jsonObj);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Parses rain 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 Rain implements Serializable {
|
|
|
|
private static final String JSON_RAIN_1HOUR = "1h";
|
|
private static final String JSON_RAIN_3HOUR = "3h";
|
|
|
|
private final float rain1h;
|
|
private final float rain3h;
|
|
|
|
Rain() {
|
|
this.rain1h = Float.NaN;
|
|
this.rain3h = Float.NaN;
|
|
}
|
|
|
|
Rain(JSONObject jsonObj) {
|
|
this.rain1h = (float) jsonObj.optDouble(JSON_RAIN_1HOUR, Double.NaN);
|
|
this.rain3h = (float) jsonObj.optDouble(JSON_RAIN_3HOUR, Double.NaN);
|
|
}
|
|
|
|
public boolean hasRain1h() {
|
|
return !Float.isNaN(this.rain1h);
|
|
}
|
|
|
|
public boolean hasRain3h() {
|
|
return !Float.isNaN(this.rain3h);
|
|
}
|
|
|
|
public float getRain1h() {
|
|
return this.rain1h;
|
|
}
|
|
|
|
public float getRain3h() {
|
|
return this.rain3h;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Parses snow 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 2015/01/28
|
|
* @since 2.5.0.4
|
|
*/
|
|
public static class Snow implements Serializable {
|
|
|
|
private static final String JSON_SNOW_1HOUR = "1h";
|
|
private static final String JSON_SNOW_3HOUR = "3h";
|
|
|
|
private final float snow1h;
|
|
private final float snow3h;
|
|
|
|
Snow() {
|
|
this.snow1h = Float.NaN;
|
|
this.snow3h = Float.NaN;
|
|
}
|
|
|
|
Snow(JSONObject jsonObj) {
|
|
this.snow1h = (float) jsonObj.optDouble(JSON_SNOW_1HOUR, Double.NaN);
|
|
this.snow3h = (float) jsonObj.optDouble(JSON_SNOW_3HOUR, Double.NaN);
|
|
}
|
|
|
|
public boolean hasSnow1h() {
|
|
return !Float.isNaN(this.snow1h);
|
|
}
|
|
|
|
public boolean hasSnow3h() {
|
|
return !Float.isNaN(this.snow3h);
|
|
}
|
|
|
|
public float getSnow1h() {
|
|
return this.snow1h;
|
|
}
|
|
|
|
public float getSnow3h() {
|
|
return this.snow3h;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* <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_TYPE = "type";
|
|
private static final String JSON_SYS_ID = "id";
|
|
private static final String JSON_SYS_MESSAGE = "message";
|
|
private static final String JSON_SYS_COUNTRY_CODE = "country";
|
|
private static final String JSON_SYS_SUNRISE = "sunrise";
|
|
private static final String JSON_SYS_SUNSET = "sunset";
|
|
|
|
private final int type;
|
|
private final int id;
|
|
private final double message;
|
|
private final String countryCode;
|
|
private final Date sunrise;
|
|
private final Date sunset;
|
|
|
|
Sys() {
|
|
this.type = Integer.MIN_VALUE;
|
|
this.id = Integer.MIN_VALUE;
|
|
this.message = Double.NaN;
|
|
this.countryCode = null;
|
|
this.sunrise = null;
|
|
this.sunset = null;
|
|
}
|
|
|
|
Sys(JSONObject jsonObj) {
|
|
this.type = jsonObj.optInt(JSON_SYS_TYPE, Integer.MIN_VALUE);
|
|
this.id = jsonObj.optInt(JSON_SYS_ID, Integer.MIN_VALUE);
|
|
this.message = jsonObj.optDouble(JSON_SYS_MESSAGE, Double.NaN);
|
|
this.countryCode = jsonObj.optString(JSON_SYS_COUNTRY_CODE, null);
|
|
|
|
long sr_secs = jsonObj.optLong(JSON_SYS_SUNRISE, Long.MIN_VALUE);
|
|
if (sr_secs != Long.MIN_VALUE) {
|
|
this.sunrise = new Date(sr_secs * 1000);
|
|
} else {
|
|
this.sunrise = null;
|
|
}
|
|
|
|
long ss_secs = jsonObj.optLong(JSON_SYS_SUNSET, Long.MIN_VALUE);
|
|
if (ss_secs != Long.MIN_VALUE) {
|
|
this.sunset = new Date(ss_secs * 1000);
|
|
} else {
|
|
this.sunset = null;
|
|
}
|
|
}
|
|
|
|
public boolean hasType() {
|
|
return this.type != Integer.MIN_VALUE;
|
|
}
|
|
|
|
public boolean hasId() {
|
|
return this.id != Integer.MIN_VALUE;
|
|
}
|
|
|
|
public boolean hasMessage() {
|
|
return !Double.isNaN(this.message);
|
|
}
|
|
|
|
public boolean hasCountryCode() {
|
|
return this.countryCode != null && (! "".equals(this.countryCode));
|
|
}
|
|
|
|
public boolean hasSunriseTime() {
|
|
return this.sunrise != null;
|
|
}
|
|
|
|
public boolean hasSunsetTime() {
|
|
return this.sunset != null;
|
|
}
|
|
|
|
public int getType() {
|
|
return this.type;
|
|
}
|
|
|
|
public int getId() {
|
|
return this.id;
|
|
}
|
|
|
|
public double getMessage() {
|
|
return this.message;
|
|
}
|
|
|
|
public String getCountryCode() {
|
|
return this.countryCode;
|
|
}
|
|
|
|
public Date getSunriseTime() {
|
|
return this.sunrise;
|
|
}
|
|
|
|
public Date getSunsetTime() {
|
|
return this.sunset;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* <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 {
|
|
|
|
private static final String JSON_WIND_GUST = "gust";
|
|
|
|
private final float gust;
|
|
|
|
Wind() {
|
|
super();
|
|
|
|
this.gust = Float.NaN;
|
|
}
|
|
|
|
Wind(JSONObject jsonObj) {
|
|
super(jsonObj);
|
|
|
|
this.gust = (float) jsonObj.optDouble(JSON_WIND_GUST, Double.NaN);
|
|
}
|
|
|
|
public boolean hasWindGust() {
|
|
return !Float.isNaN(this.gust);
|
|
}
|
|
|
|
public float getWindGust() {
|
|
return this.gust;
|
|
}
|
|
}
|
|
}
|