diff --git a/src/main/java/by/prominence/openweather/api/WeatherProviderManager.java b/src/main/java/by/prominence/openweather/api/OpenWeatherProviderManager.java similarity index 75% rename from src/main/java/by/prominence/openweather/api/WeatherProviderManager.java rename to src/main/java/by/prominence/openweather/api/OpenWeatherProviderManager.java index 64ffbf2..acfc5c0 100644 --- a/src/main/java/by/prominence/openweather/api/WeatherProviderManager.java +++ b/src/main/java/by/prominence/openweather/api/OpenWeatherProviderManager.java @@ -22,19 +22,23 @@ package by.prominence.openweather.api; -import by.prominence.openweather.api.provider.DefaultWeatherProvider; +import by.prominence.openweather.api.provider.ForecastProvider; import by.prominence.openweather.api.provider.WeatherProvider; +import by.prominence.openweather.api.provider.OpenWeatherProvider; -public class WeatherProviderManager { +public class OpenWeatherProviderManager { private String authToken; - public WeatherProviderManager(String token) { + public OpenWeatherProviderManager(String token) { this.authToken = token; } - public WeatherProvider getProvider() { - return new DefaultWeatherProvider(authToken); + public OpenWeatherProvider getWeather() { + return new WeatherProvider(authToken); + } + public OpenWeatherProvider getForecast() { + return new ForecastProvider(authToken); } } diff --git a/src/main/java/by/prominence/openweather/api/constants/System.java b/src/main/java/by/prominence/openweather/api/constants/System.java new file mode 100644 index 0000000..d45d5e2 --- /dev/null +++ b/src/main/java/by/prominence/openweather/api/constants/System.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2018 Alexey Zinchenko + * + * 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 by.prominence.openweather.api.constants; + +public class System { + + public static final String OPEN_WEATHER_API_VERSION = "2.5"; + public static final String OPEN_WEATHER_API_URL = "http://api.openweathermap.org/data/" + OPEN_WEATHER_API_VERSION + "/"; +} diff --git a/src/main/java/by/prominence/openweather/api/exception/InvalidAuthTokenException.java b/src/main/java/by/prominence/openweather/api/exception/InvalidAuthTokenException.java index b7dca0f..55a8765 100644 --- a/src/main/java/by/prominence/openweather/api/exception/InvalidAuthTokenException.java +++ b/src/main/java/by/prominence/openweather/api/exception/InvalidAuthTokenException.java @@ -25,7 +25,7 @@ package by.prominence.openweather.api.exception; public class InvalidAuthTokenException extends Exception { public InvalidAuthTokenException() { - super("Please, check you authentication token!"); + super("Please, check you authentication token! You can get it here: https://home.openweathermap.org/api_keys/."); } public InvalidAuthTokenException(String message) { diff --git a/src/main/java/by/prominence/openweather/api/model/OpenWeatherResponse.java b/src/main/java/by/prominence/openweather/api/model/OpenWeatherResponse.java new file mode 100644 index 0000000..f660350 --- /dev/null +++ b/src/main/java/by/prominence/openweather/api/model/OpenWeatherResponse.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2018 Alexey Zinchenko + * + * 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 by.prominence.openweather.api.model; + +public interface OpenWeatherResponse { + + short getResponseCode(); +} diff --git a/src/main/java/by/prominence/openweather/api/model/forecast/City.java b/src/main/java/by/prominence/openweather/api/model/forecast/City.java new file mode 100644 index 0000000..e54f16a --- /dev/null +++ b/src/main/java/by/prominence/openweather/api/model/forecast/City.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2018 Alexey Zinchenko + * + * 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 by.prominence.openweather.api.model.forecast; + +import by.prominence.openweather.api.model.Coordinates; +import com.alibaba.fastjson.annotation.JSONField; + +import java.util.Objects; + +public class City { + + // City ID + private long id; + + // City name + private String name; + + @JSONField(name = "coord") + private Coordinates coordinates; + + // Country code (GB, JP etc.) + private String country; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Coordinates getCoordinates() { + return coordinates; + } + + public void setCoordinates(Coordinates coordinates) { + this.coordinates = coordinates; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + + @Override + public String toString() { + return "City{" + + "id=" + id + + ", name='" + name + '\'' + + ", coordinates=" + coordinates + + ", country='" + country + '\'' + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + City city = (City) o; + return id == city.id && + Objects.equals(name, city.name) && + Objects.equals(coordinates, city.coordinates) && + Objects.equals(country, city.country); + } + + @Override + public int hashCode() { + + return Objects.hash(id, name, coordinates, country); + } +} diff --git a/src/main/java/by/prominence/openweather/api/model/forecast/ForecastInfo.java b/src/main/java/by/prominence/openweather/api/model/forecast/ForecastInfo.java new file mode 100644 index 0000000..c3e98cc --- /dev/null +++ b/src/main/java/by/prominence/openweather/api/model/forecast/ForecastInfo.java @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2018 Alexey Zinchenko + * + * 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 by.prominence.openweather.api.model.forecast; + +import by.prominence.openweather.api.model.*; +import com.alibaba.fastjson.annotation.JSONField; + +import java.util.Date; +import java.util.List; +import java.util.Objects; + +public class ForecastInfo { + + @JSONField(name = "dt") + // Time of data forecasted, unix, UTC + private long dataCalculationTime; + + @JSONField(name = "main") + private MainInfo mainInfo; + + @JSONField(name = "weather") + private List weathers; + + private Clouds clouds; + + private Wind wind; + + private Snow snow; + + private Rain rain; + + @JSONField(name = "sys") + private ForecastSystemInfo systemInfo; + + // Data/time of calculation, UTC + private String dt_txt; + + public long getDataCalculationTime() { + return dataCalculationTime; + } + + public void setDataCalculationTime(long dataCalculationTime) { + this.dataCalculationTime = dataCalculationTime; + } + + public MainInfo getMainInfo() { + return mainInfo; + } + + public void setMainInfo(MainInfo mainInfo) { + this.mainInfo = mainInfo; + } + + public List getWeathers() { + return weathers; + } + + public void setWeathers(List weathers) { + this.weathers = weathers; + } + + public Clouds getClouds() { + return clouds; + } + + public void setClouds(Clouds clouds) { + this.clouds = clouds; + } + + public Wind getWind() { + return wind; + } + + public void setWind(Wind wind) { + this.wind = wind; + } + + public Snow getSnow() { + return snow; + } + + public void setSnow(Snow snow) { + this.snow = snow; + } + + public Rain getRain() { + return rain; + } + + public void setRain(Rain rain) { + this.rain = rain; + } + + public ForecastSystemInfo getSystemInfo() { + return systemInfo; + } + + public void setSystemInfo(ForecastSystemInfo systemInfo) { + this.systemInfo = systemInfo; + } + + public String getDt_txt() { + return dt_txt; + } + + public void setDt_txt(String dt_txt) { + this.dt_txt = dt_txt; + } + + @Override + public String toString() { + return "\nForecastInfo{" + + "dataCalculationTime=" + new Date(dataCalculationTime * 1000) + + ", mainInfo=" + mainInfo + + ", weathers=" + weathers + + ", clouds=" + clouds + + ", wind=" + wind + + ", snow=" + snow + + ", rain=" + rain + + ", systemInfo=" + systemInfo + + ", dt_text='" + dt_txt + '\'' + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ForecastInfo that = (ForecastInfo) o; + return dataCalculationTime == that.dataCalculationTime && + Objects.equals(mainInfo, that.mainInfo) && + Objects.equals(weathers, that.weathers) && + Objects.equals(clouds, that.clouds) && + Objects.equals(wind, that.wind) && + Objects.equals(snow, that.snow) && + Objects.equals(rain, that.rain) && + Objects.equals(systemInfo, that.systemInfo) && + Objects.equals(dt_txt, that.dt_txt); + } + + @Override + public int hashCode() { + + return Objects.hash(dataCalculationTime, mainInfo, weathers, clouds, wind, snow, rain, systemInfo, dt_txt); + } +} diff --git a/src/main/java/by/prominence/openweather/api/model/forecast/ForecastResponse.java b/src/main/java/by/prominence/openweather/api/model/forecast/ForecastResponse.java new file mode 100644 index 0000000..3b200ed --- /dev/null +++ b/src/main/java/by/prominence/openweather/api/model/forecast/ForecastResponse.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2018 Alexey Zinchenko + * + * 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 by.prominence.openweather.api.model.forecast; + +import by.prominence.openweather.api.model.OpenWeatherResponse; +import com.alibaba.fastjson.annotation.JSONField; + +import java.util.List; +import java.util.Objects; + +public class ForecastResponse implements OpenWeatherResponse { + + @JSONField(name = "cod") + private short responseCode; + + private double message; + + // Number of lines returned by this API call + private short cnt; + + @JSONField(name = "list") + private List forecasts; + + private City city; + + public short getResponseCode() { + return responseCode; + } + + public void setResponseCode(short responseCode) { + this.responseCode = responseCode; + } + + public double getMessage() { + return message; + } + + public void setMessage(double message) { + this.message = message; + } + + public short getCnt() { + return cnt; + } + + public void setCnt(short cnt) { + this.cnt = cnt; + } + + public List getForecasts() { + return forecasts; + } + + public void setForecasts(List forecasts) { + this.forecasts = forecasts; + } + + public City getCity() { + return city; + } + + public void setCity(City city) { + this.city = city; + } + + @Override + public String toString() { + return "ForecastResponse{" + + "responseCode=" + responseCode + + ", message=" + message + + ", cnt=" + cnt + + ", forecasts=" + forecasts + + ", city=" + city + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ForecastResponse that = (ForecastResponse) o; + return responseCode == that.responseCode && + Double.compare(that.message, message) == 0 && + cnt == that.cnt && + Objects.equals(forecasts, that.forecasts) && + Objects.equals(city, that.city); + } + + @Override + public int hashCode() { + + return Objects.hash(responseCode, message, cnt, forecasts, city); + } +} diff --git a/src/main/java/by/prominence/openweather/api/model/forecast/ForecastSystemInfo.java b/src/main/java/by/prominence/openweather/api/model/forecast/ForecastSystemInfo.java new file mode 100644 index 0000000..40a8d1e --- /dev/null +++ b/src/main/java/by/prominence/openweather/api/model/forecast/ForecastSystemInfo.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2018 Alexey Zinchenko + * + * 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 by.prominence.openweather.api.model.forecast; + +import java.util.Objects; + +public class ForecastSystemInfo { + + private String pod; + + public String getPod() { + return pod; + } + + public void setPod(String pod) { + this.pod = pod; + } + + @Override + public String toString() { + return "ForecastSystemInfo{" + + "pod='" + pod + '\'' + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ForecastSystemInfo that = (ForecastSystemInfo) o; + return Objects.equals(pod, that.pod); + } + + @Override + public int hashCode() { + + return Objects.hash(pod); + } +} diff --git a/src/main/java/by/prominence/openweather/api/model/forecast/MainInfo.java b/src/main/java/by/prominence/openweather/api/model/forecast/MainInfo.java new file mode 100644 index 0000000..88e7dbc --- /dev/null +++ b/src/main/java/by/prominence/openweather/api/model/forecast/MainInfo.java @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2018 Alexey Zinchenko + * + * 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 by.prominence.openweather.api.model.forecast; + +import com.alibaba.fastjson.annotation.JSONField; + +import java.util.Objects; + +public class MainInfo { + + @JSONField(name = "temp") + // Temperature. Unit Default: Kelvin, Metric: Celsius, Imperial: Fahrenheit. + private float temperature; + + @JSONField(name = "temp_min") + // Minimum temperature at the moment of calculation. This is deviation from 'temp' that is possible for large cities and + // megalopolises geographically expanded (use these parameter optionally). Unit Default: Kelvin, Metric: Celsius, Imperial: Fahrenheit. + private float minimumTemperature; + + @JSONField(name = "temp_max") + // Maximum temperature at the moment of calculation. This is deviation from 'temp' that is possible for large cities and + // megalopolises geographically expanded (use these parameter optionally). Unit Default: Kelvin, Metric: Celsius, Imperial: Fahrenheit. + private float maximumTemperature; + + // Atmospheric pressure on the sea level by default, hPa + private float pressure; + + @JSONField(name = "sea_level") + // Atmospheric pressure on the sea level, hPa + private float seaLevelPressure; + + @JSONField(name = "grnd_level") + // Atmospheric pressure on the ground level, hPa + private float groundLevelPressure; + + // Humidity, % + private byte humidity; + + @JSONField(name = "temp_kf") + // Internal parameter + private float temperatureCoefficient; + + public float getTemperature() { + return temperature; + } + + public void setTemperature(float temperature) { + this.temperature = temperature; + } + + public float getMinimumTemperature() { + return minimumTemperature; + } + + public void setMinimumTemperature(float minimumTemperature) { + this.minimumTemperature = minimumTemperature; + } + + public float getMaximumTemperature() { + return maximumTemperature; + } + + public void setMaximumTemperature(float maximumTemperature) { + this.maximumTemperature = maximumTemperature; + } + + public float getPressure() { + return pressure; + } + + public void setPressure(float pressure) { + this.pressure = pressure; + } + + public float getSeaLevelPressure() { + return seaLevelPressure; + } + + public void setSeaLevelPressure(float seaLevelPressure) { + this.seaLevelPressure = seaLevelPressure; + } + + public float getGroundLevelPressure() { + return groundLevelPressure; + } + + public void setGroundLevelPressure(float groundLevelPressure) { + this.groundLevelPressure = groundLevelPressure; + } + + public byte getHumidity() { + return humidity; + } + + public void setHumidity(byte humidity) { + this.humidity = humidity; + } + + public float getTemperatureCoefficient() { + return temperatureCoefficient; + } + + public void setTemperatureCoefficient(float temperatureCoefficient) { + this.temperatureCoefficient = temperatureCoefficient; + } + + @Override + public String toString() { + return "MainInfo{" + + "temperature=" + temperature + + ", minimumTemperature=" + minimumTemperature + + ", maximumTemperature=" + maximumTemperature + + ", pressure=" + pressure + + ", seaLevelPressure=" + seaLevelPressure + + ", groundLevelPressure=" + groundLevelPressure + + ", humidity=" + humidity + "%" + + ", temperatureCoefficient=" + temperatureCoefficient + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + MainInfo mainInfo = (MainInfo) o; + return Float.compare(mainInfo.temperature, temperature) == 0 && + Float.compare(mainInfo.minimumTemperature, minimumTemperature) == 0 && + Float.compare(mainInfo.maximumTemperature, maximumTemperature) == 0 && + Float.compare(mainInfo.pressure, pressure) == 0 && + Float.compare(mainInfo.seaLevelPressure, seaLevelPressure) == 0 && + Float.compare(mainInfo.groundLevelPressure, groundLevelPressure) == 0 && + humidity == mainInfo.humidity && + Float.compare(mainInfo.temperatureCoefficient, temperatureCoefficient) == 0; + } + + @Override + public int hashCode() { + + return Objects.hash(temperature, minimumTemperature, maximumTemperature, pressure, seaLevelPressure, groundLevelPressure, humidity, temperatureCoefficient); + } +} diff --git a/src/main/java/by/prominence/openweather/api/model/WeatherInfo.java b/src/main/java/by/prominence/openweather/api/model/weather/WeatherInfo.java similarity index 98% rename from src/main/java/by/prominence/openweather/api/model/WeatherInfo.java rename to src/main/java/by/prominence/openweather/api/model/weather/WeatherInfo.java index 90342a0..564727d 100644 --- a/src/main/java/by/prominence/openweather/api/model/WeatherInfo.java +++ b/src/main/java/by/prominence/openweather/api/model/weather/WeatherInfo.java @@ -20,7 +20,7 @@ * SOFTWARE. */ -package by.prominence.openweather.api.model; +package by.prominence.openweather.api.model.weather; import com.alibaba.fastjson.annotation.JSONField; diff --git a/src/main/java/by/prominence/openweather/api/model/WeatherResponse.java b/src/main/java/by/prominence/openweather/api/model/weather/WeatherResponse.java similarity index 96% rename from src/main/java/by/prominence/openweather/api/model/WeatherResponse.java rename to src/main/java/by/prominence/openweather/api/model/weather/WeatherResponse.java index e2d9979..e8b04ec 100644 --- a/src/main/java/by/prominence/openweather/api/model/WeatherResponse.java +++ b/src/main/java/by/prominence/openweather/api/model/weather/WeatherResponse.java @@ -20,14 +20,15 @@ * SOFTWARE. */ -package by.prominence.openweather.api.model; +package by.prominence.openweather.api.model.weather; +import by.prominence.openweather.api.model.*; import com.alibaba.fastjson.annotation.JSONField; import java.util.Date; import java.util.List; -public class WeatherResponse { +public class WeatherResponse implements OpenWeatherResponse { @JSONField(name = "id") private long cityId; diff --git a/src/main/java/by/prominence/openweather/api/model/WeatherSystemInfo.java b/src/main/java/by/prominence/openweather/api/model/weather/WeatherSystemInfo.java similarity index 98% rename from src/main/java/by/prominence/openweather/api/model/WeatherSystemInfo.java rename to src/main/java/by/prominence/openweather/api/model/weather/WeatherSystemInfo.java index 883fa6a..83690de 100644 --- a/src/main/java/by/prominence/openweather/api/model/WeatherSystemInfo.java +++ b/src/main/java/by/prominence/openweather/api/model/weather/WeatherSystemInfo.java @@ -20,7 +20,7 @@ * SOFTWARE. */ -package by.prominence.openweather.api.model; +package by.prominence.openweather.api.model.weather; import com.alibaba.fastjson.annotation.JSONField; diff --git a/src/main/java/by/prominence/openweather/api/provider/DefaultWeatherProvider.java b/src/main/java/by/prominence/openweather/api/provider/AbstractOpenWeatherProvider.java similarity index 57% rename from src/main/java/by/prominence/openweather/api/provider/DefaultWeatherProvider.java rename to src/main/java/by/prominence/openweather/api/provider/AbstractOpenWeatherProvider.java index 8b632c0..5d65867 100644 --- a/src/main/java/by/prominence/openweather/api/provider/DefaultWeatherProvider.java +++ b/src/main/java/by/prominence/openweather/api/provider/AbstractOpenWeatherProvider.java @@ -22,10 +22,11 @@ package by.prominence.openweather.api.provider; +import by.prominence.openweather.api.constants.System; import by.prominence.openweather.api.exception.DataNotFoundException; import by.prominence.openweather.api.exception.InvalidAuthTokenException; import by.prominence.openweather.api.model.Coordinates; -import by.prominence.openweather.api.model.WeatherResponse; +import by.prominence.openweather.api.model.OpenWeatherResponse; import by.prominence.openweather.api.utils.JsonUtils; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; @@ -33,60 +34,60 @@ import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.HttpClientBuilder; import java.io.IOException; +import java.lang.reflect.ParameterizedType; -public class DefaultWeatherProvider implements WeatherProvider { +public abstract class AbstractOpenWeatherProvider implements OpenWeatherProvider { - private static final String OPEN_WEATHER_API_VERSION = "2.5"; - private static final String OPEN_WEATHER_API_URL = "http://api.openweathermap.org/data/" + OPEN_WEATHER_API_VERSION + "/weather"; + protected final String authToken; - private final String authToken; + protected String language; + protected String unit; + protected String accuracy; + private Class type; - private String language; - private String unit; - private String accuracy; - - public DefaultWeatherProvider(String authToken) { + public AbstractOpenWeatherProvider(String authToken) { this.authToken = authToken; + type = (Class)((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0]; } - public WeatherProvider setLanguage(String language) { + public OpenWeatherProvider setLanguage(String language) { this.language = language; return this; } - public WeatherProvider setUnit(String unit) { + public OpenWeatherProvider setUnit(String unit) { this.unit = unit; return this; } - public WeatherProvider setAccuracy(String accuracy) { + public OpenWeatherProvider setAccuracy(String accuracy) { this.accuracy = accuracy; return this; } - public WeatherResponse getByCityId(String id) throws InvalidAuthTokenException, DataNotFoundException { + public T getByCityId(String id) throws InvalidAuthTokenException, DataNotFoundException { return executeRequest("?id=" + id); } - public WeatherResponse getByCityName(String name) throws InvalidAuthTokenException, DataNotFoundException { + public T getByCityName(String name) throws InvalidAuthTokenException, DataNotFoundException { return executeRequest("?q=" + name); } - public WeatherResponse getByCoordinates(double latitude, double longitude) throws InvalidAuthTokenException, DataNotFoundException { + public T getByCoordinates(double latitude, double longitude) throws InvalidAuthTokenException, DataNotFoundException { return executeRequest("?lat=" + latitude + "&lon=" + longitude); } - public WeatherResponse getByCoordinates(Coordinates coordinates) throws InvalidAuthTokenException, DataNotFoundException { + public T getByCoordinates(Coordinates coordinates) throws InvalidAuthTokenException, DataNotFoundException { return getByCoordinates(coordinates.getLatitude(), coordinates.getLongitude()); } - public WeatherResponse getByZIPCode(String zipCode, String countryCode) throws InvalidAuthTokenException, DataNotFoundException { + public T getByZIPCode(String zipCode, String countryCode) throws InvalidAuthTokenException, DataNotFoundException { return executeRequest("?zip=" + zipCode + "," + countryCode); } - private WeatherResponse executeRequest(String parameterString) throws InvalidAuthTokenException, DataNotFoundException { + protected T executeRequest(String parameterString) throws InvalidAuthTokenException, DataNotFoundException { - String url = OPEN_WEATHER_API_URL + parameterString + "&appid=" + authToken; + String url = getRequestUrl() + parameterString + "&appid=" + authToken; if (language != null) { url += "&lang=" + language; @@ -102,32 +103,40 @@ public class DefaultWeatherProvider implements WeatherProvider { HttpClient httpClient = HttpClientBuilder.create().build(); HttpGet request = new HttpGet(url); - HttpResponse response = null; + HttpResponse httpResponse = null; try { - response = httpClient.execute(request); + httpResponse = httpClient.execute(request); } catch (IOException e) { e.printStackTrace(); } - WeatherResponse weatherResponse = null; - if (response != null) { + T openWeatherResponse = null; + if (httpResponse != null) { try { - weatherResponse = (WeatherResponse)JsonUtils.parseJson(response.getEntity().getContent(), WeatherResponse.class); + openWeatherResponse = type.cast(JsonUtils.parseJson(httpResponse.getEntity().getContent(), type)); - if (weatherResponse.getResponseCode() == 401) { + if (openWeatherResponse.getResponseCode() == 401) { throw new InvalidAuthTokenException(); } - if (weatherResponse.getResponseCode() == 404) { + if (openWeatherResponse.getResponseCode() == 404) { throw new DataNotFoundException(); } } catch (IOException e) { e.printStackTrace(); + } catch (ClassCastException cce) { + cce.printStackTrace(); } } - return weatherResponse; + return openWeatherResponse; } + + private String getRequestUrl() { + return System.OPEN_WEATHER_API_URL + getRequestType(); + } + + protected abstract String getRequestType(); } diff --git a/src/main/java/by/prominence/openweather/api/provider/ForecastProvider.java b/src/main/java/by/prominence/openweather/api/provider/ForecastProvider.java new file mode 100644 index 0000000..be80329 --- /dev/null +++ b/src/main/java/by/prominence/openweather/api/provider/ForecastProvider.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018 Alexey Zinchenko + * + * 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 by.prominence.openweather.api.provider; + +import by.prominence.openweather.api.model.forecast.ForecastResponse; + +public class ForecastProvider extends AbstractOpenWeatherProvider { + + public ForecastProvider(String authToken) { + super(authToken); + } + + protected String getRequestType() { + return "forecast"; + } +} diff --git a/src/main/java/by/prominence/openweather/api/provider/OpenWeatherProvider.java b/src/main/java/by/prominence/openweather/api/provider/OpenWeatherProvider.java new file mode 100644 index 0000000..b43a565 --- /dev/null +++ b/src/main/java/by/prominence/openweather/api/provider/OpenWeatherProvider.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2018 Alexey Zinchenko + * + * 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 by.prominence.openweather.api.provider; + +import by.prominence.openweather.api.exception.DataNotFoundException; +import by.prominence.openweather.api.exception.InvalidAuthTokenException; +import by.prominence.openweather.api.model.Coordinates; +import by.prominence.openweather.api.model.OpenWeatherResponse; + +public interface OpenWeatherProvider { + + OpenWeatherResponse getByCityId(String id) throws InvalidAuthTokenException, DataNotFoundException; + OpenWeatherResponse getByCityName(String name) throws InvalidAuthTokenException, DataNotFoundException; + OpenWeatherResponse getByCoordinates(double latitude, double longitude) throws InvalidAuthTokenException, DataNotFoundException; + OpenWeatherResponse getByCoordinates(Coordinates coordinates) throws InvalidAuthTokenException, DataNotFoundException; + OpenWeatherResponse getByZIPCode(String zipCode, String countryCode) throws InvalidAuthTokenException, DataNotFoundException; + + OpenWeatherProvider setLanguage(String language); + OpenWeatherProvider setUnit(String unit); + OpenWeatherProvider setAccuracy(String accuracy); + +} diff --git a/src/main/java/by/prominence/openweather/api/provider/WeatherProvider.java b/src/main/java/by/prominence/openweather/api/provider/WeatherProvider.java index 876eea8..56aa8d3 100644 --- a/src/main/java/by/prominence/openweather/api/provider/WeatherProvider.java +++ b/src/main/java/by/prominence/openweather/api/provider/WeatherProvider.java @@ -22,21 +22,15 @@ package by.prominence.openweather.api.provider; -import by.prominence.openweather.api.exception.DataNotFoundException; -import by.prominence.openweather.api.exception.InvalidAuthTokenException; -import by.prominence.openweather.api.model.Coordinates; -import by.prominence.openweather.api.model.WeatherResponse; +import by.prominence.openweather.api.model.weather.WeatherResponse; -public interface WeatherProvider { +public class WeatherProvider extends AbstractOpenWeatherProvider { - public WeatherResponse getByCityId(String id) throws InvalidAuthTokenException, DataNotFoundException; - public WeatherResponse getByCityName(String name) throws InvalidAuthTokenException, DataNotFoundException; - public WeatherResponse getByCoordinates(double latitude, double longitude) throws InvalidAuthTokenException, DataNotFoundException; - public WeatherResponse getByCoordinates(Coordinates coordinates) throws InvalidAuthTokenException, DataNotFoundException; - public WeatherResponse getByZIPCode(String zipCode, String countryCode) throws InvalidAuthTokenException, DataNotFoundException; - - public WeatherProvider setLanguage(String language); - public WeatherProvider setUnit(String unit); - public WeatherProvider setAccuracy(String accuracy); + public WeatherProvider(String authToken) { + super(authToken); + } + protected String getRequestType() { + return "weather"; + } }