Added new draft current weather retrieving implementation.

This commit is contained in:
2019-06-13 23:48:05 +03:00
parent 44da350e3c
commit aed72a5ab5
69 changed files with 2761 additions and 2655 deletions
@@ -1,107 +0,0 @@
/*
* 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 com.github.prominence.openweathermap.api;
import com.github.prominence.openweathermap.api.constants.TimeFrame;
import com.github.prominence.openweathermap.api.model.response.AirPollution;
import com.github.prominence.openweathermap.api.model.Coordinates;
import com.github.prominence.openweathermap.api.utils.TimeFrameUtils;
import com.github.prominence.openweathermap.api.utils.JSONUtils;
import com.github.prominence.openweathermap.api.utils.RequestUtils;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
public class AirPollutionRequester extends AuthenticationTokenBasedRequester {
private Coordinates coordinates;
private TimeFrame timeFrame;
private Date date;
AirPollutionRequester(String authToken, float latitude, float longitude, Date date, TimeFrame timeFrame) {
super(authToken);
this.coordinates = new Coordinates(latitude, longitude);
this.date = date;
this.timeFrame = timeFrame;
}
public AirPollutionRequester setCoordinates(Coordinates coordinates) {
this.coordinates = coordinates;
return this;
}
public AirPollutionRequester setCoordinates(float latitude, float longitude) {
this.coordinates = new Coordinates(latitude, longitude);
return this;
}
public AirPollutionRequester setTimeFrame(TimeFrame timeFrame) {
this.timeFrame = timeFrame;
return this;
}
public AirPollutionRequester setDate(Date date) {
this.date = date;
return this;
}
public AirPollution retrieve() {
if (coordinates == null || timeFrame == null || date == null) {
throw new IllegalArgumentException("Coordinates, date or time frame weren't set.");
}
String requestParameters = String.format("%s,%s/%s.json", coordinates.getLatitude(), coordinates.getLongitude(), TimeFrameUtils.formatDate(date, timeFrame));
AirPollution airPollution = null;
// currently only CO
try (InputStream response = executeRequest("pollution/v1/co/", requestParameters)) {
airPollution = (AirPollution) JSONUtils.parseJSON(response, AirPollution.class);
} catch (IOException ex) {
ex.printStackTrace();
}
return airPollution;
}
private InputStream executeRequest(String requestType, String requestSpecificParameters) {
String url = OPEN_WEATHER_BASE_URL + requestType +
requestSpecificParameters +
"?appid=" +
authToken;
InputStream getRequest = null;
try {
getRequest = RequestUtils.executeGetRequest(new URL(url));
} catch (MalformedURLException e) {
e.printStackTrace();
}
return getRequest;
}
}
@@ -1,115 +0,0 @@
/*
* 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 com.github.prominence.openweathermap.api;
import com.github.prominence.openweathermap.api.constants.Unit;
import com.github.prominence.openweathermap.api.model.Coordinates;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
abstract class BasicRequester<T> extends AuthenticationTokenBasedRequester {
protected String language;
protected String unitSystem = Unit.STANDARD_SYSTEM;
protected String accuracy;
protected BasicRequester(String authToken) {
super(authToken);
}
public T getByCityId(String id) {
return executeRequest("?id=" + id);
}
public T getByCityName(String name) {
return executeRequest("?q=" + name);
}
public T getByCoordinates(double latitude, double longitude) {
return executeRequest("?lat=" + latitude + "&lon=" + longitude);
}
public T getByCoordinates(Coordinates coordinates) {
return getByCoordinates(coordinates.getLatitude(), coordinates.getLongitude());
}
public T getByZIPCode(String zipCode, String countryCode) {
return executeRequest("?zip=" + zipCode + "," + countryCode);
}
protected URL buildURL(String requestSpecificParameters) {
StringBuilder urlBuilder = new StringBuilder(OPEN_WEATHER_API_URL);
urlBuilder.append(getRequestType());
urlBuilder.append(requestSpecificParameters);
urlBuilder.append("&appid=");
urlBuilder.append(authToken);
if (language != null) {
urlBuilder.append("&lang=");
urlBuilder.append(language);
}
if (!Unit.STANDARD_SYSTEM.equals(unitSystem)) {
urlBuilder.append("&units=");
urlBuilder.append(unitSystem);
}
if (accuracy != null) {
urlBuilder.append("&type=");
urlBuilder.append(accuracy);
}
Map<String, String> additionalParameters = getAdditionalParameters();
if (additionalParameters != null) {
additionalParameters.forEach((key, value) -> {
urlBuilder.append("&");
urlBuilder.append(key);
urlBuilder.append("=");
urlBuilder.append(value);
});
}
URL url = null;
try {
url = new URL(urlBuilder.toString());
} catch (MalformedURLException e) {
e.printStackTrace();
}
return url;
}
protected Map<String, String> getAdditionalParameters() {
return null;
}
protected abstract String getRequestType();
protected abstract T executeRequest(String requestSpecificParameters);
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 Alexey Zinchenko
* Copyright (c) 2019 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
@@ -20,13 +20,11 @@
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model;
package com.github.prominence.openweathermap.api;
public interface OpenWeatherResponse {
public interface CurrentWeatherRequestTerminator<T, S> extends RequestTerminator<T, S> {
String getCityName();
long getCityId();
String getCountry();
Coordinates getCoordinates();
short getResponseCode();
S asXML();
S asHTML();
}
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api;
public interface CurrentWeatherRequester {
SingleLocationWeatherRequester single();
MultipleLocationsWeatherRequester multiple();
}
@@ -1,85 +0,0 @@
/*
* 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 com.github.prominence.openweathermap.api;
import com.github.prominence.openweathermap.api.constants.Unit;
import com.github.prominence.openweathermap.api.model.response.DailyForecast;
import com.github.prominence.openweathermap.api.utils.JSONUtils;
import com.github.prominence.openweathermap.api.utils.RequestUtils;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
public class DailyForecastRequester extends BasicRequester<DailyForecast> {
int amountOfDays = -1;
protected DailyForecastRequester(String authToken) {
super(authToken);
}
public DailyForecastRequester setAmountOfDays(int amountOfDays) {
this.amountOfDays = amountOfDays;
return this;
}
@Override
protected String getRequestType() {
return "forecast/daily";
}
@Override
protected Map<String, String> getAdditionalParameters() {
Map<String, String> additionalParameters = null;
if (amountOfDays != -1) {
additionalParameters = new HashMap<>();
additionalParameters.put("cnt", String.valueOf(amountOfDays));
}
return additionalParameters;
}
@Override
protected DailyForecast executeRequest(String requestSpecificParameters) {
DailyForecast forecastResponse = null;
try {
InputStream requestResult = RequestUtils.executeGetRequest(buildURL(requestSpecificParameters));
forecastResponse = (DailyForecast) JSONUtils.parseJSON(requestResult, DailyForecast.class);
char temperatureUnit = Unit.getTemperatureUnit(unitSystem);
String windUnit = Unit.getWindUnit(unitSystem);
forecastResponse.getForecasts().forEach(forecastInfo -> {
forecastInfo.setWindUnit(windUnit);
forecastInfo.getTemperature().setTemperatureUnit(temperatureUnit);
});
} catch (IOException ex) {
ex.printStackTrace();
}
return forecastResponse;
}
}
@@ -1,80 +0,0 @@
/*
* 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 com.github.prominence.openweathermap.api;
import com.github.prominence.openweathermap.api.constants.Unit;
import com.github.prominence.openweathermap.api.model.response.HourlyForecast;
import com.github.prominence.openweathermap.api.utils.JSONUtils;
import com.github.prominence.openweathermap.api.utils.RequestUtils;
import java.io.IOException;
import java.io.InputStream;
public class HourlyForecastRequester extends BasicRequester<HourlyForecast> {
HourlyForecastRequester(String authToken) {
super(authToken);
}
public HourlyForecastRequester setLanguage(String language) {
this.language = language;
return this;
}
public HourlyForecastRequester setUnitSystem(String unitSystem) {
this.unitSystem = unitSystem;
return this;
}
public HourlyForecastRequester setAccuracy(String accuracy) {
this.accuracy = accuracy;
return this;
}
protected String getRequestType() {
return "forecast";
}
protected HourlyForecast executeRequest(String requestSpecificParameters) {
HourlyForecast forecastResponse = null;
try {
InputStream requestResult = RequestUtils.executeGetRequest(buildURL(requestSpecificParameters));
forecastResponse = (HourlyForecast) JSONUtils.parseJSON(requestResult, HourlyForecast.class);
char temperatureUnit = Unit.getTemperatureUnit(unitSystem);
String windUnit = Unit.getWindUnit(unitSystem);
forecastResponse.getForecasts().forEach(forecastInfo -> {
forecastInfo.getWind().setUnit(windUnit);
forecastInfo.getWeatherInfo().setTemperatureUnit(temperatureUnit);
});
} catch (IOException ex) {
ex.printStackTrace();
}
return forecastResponse;
}
}
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api;
import com.github.prominence.openweathermap.api.model.Coordinate;
import com.github.prominence.openweathermap.api.model.CoordinateRectangle;
public interface MultipleLocationsWeatherRequester {
MultipleResultCurrentWeatherRequestCustomizer byRectangle(CoordinateRectangle rectangle, int zoom);
MultipleResultCurrentWeatherRequestCustomizer byRectangle(CoordinateRectangle rectangle, int zoom, boolean useServerClustering);
MultipleResultCurrentWeatherRequestCustomizer byCitiesInCycle(Coordinate point, int citiesCount);
MultipleResultCurrentWeatherRequestCustomizer byCitiesInCycle(Coordinate point, int citiesCount, boolean useServerClustering);
}
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api;
import com.github.prominence.openweathermap.api.model.Weather;
import java.util.List;
import java.util.concurrent.CompletableFuture;
public interface MultipleResultCurrentWeatherAsyncRequestTerminator extends CurrentWeatherRequestTerminator<CompletableFuture<List<Weather>>, CompletableFuture<String>> {
}
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api;
public interface MultipleResultCurrentWeatherRequestCustomizer extends RequestCustomizer<MultipleResultCurrentWeatherRequestCustomizer> {
MultipleResultCurrentWeatherRequestTerminator retrieve();
MultipleResultCurrentWeatherAsyncRequestTerminator retrieveAsync();
}
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api;
import com.github.prominence.openweathermap.api.model.Weather;
import java.util.List;
public interface MultipleResultCurrentWeatherRequestTerminator extends CurrentWeatherRequestTerminator<List<Weather>, String> {
}
@@ -1,65 +0,0 @@
/*
* 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 com.github.prominence.openweathermap.api;
import com.github.prominence.openweathermap.api.constants.TimeFrame;
import com.github.prominence.openweathermap.api.model.Coordinates;
import java.util.Date;
public class OpenWeatherMapManager {
private String authToken;
public OpenWeatherMapManager(String token) {
this.authToken = token;
}
public WeatherRequester getWeatherRequester() {
return new WeatherRequester(authToken);
}
public HourlyForecastRequester getHourlyForecastRequester() {
return new HourlyForecastRequester(authToken);
}
public DailyForecastRequester getDailyForecastRequester() {
return new DailyForecastRequester(authToken);
}
public UltravioletIndexRequester getUltravioletIndexRequester(float latitude, float longitude) {
return new UltravioletIndexRequester(authToken, latitude, longitude);
}
public UltravioletIndexRequester getUltravioletIndexRequester(Coordinates coordinates) {
return new UltravioletIndexRequester(authToken, coordinates.getLatitude(), coordinates.getLongitude());
}
public AirPollutionRequester getAirPollutionRequester(float latitude, float longitude, Date date, TimeFrame timeFrame) {
return new AirPollutionRequester(authToken, latitude, longitude, date, timeFrame);
}
public AirPollutionRequester getAirPollutionRequester(Coordinates coordinates, Date date, TimeFrame timeFrame) {
return new AirPollutionRequester(authToken, coordinates.getLatitude(), coordinates.getLongitude(), date, timeFrame);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 Alexey Zinchenko
* Copyright (c) 2019 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
@@ -22,16 +22,15 @@
package com.github.prominence.openweathermap.api;
abstract class AuthenticationTokenBasedRequester {
import com.github.prominence.openweathermap.api.enums.Accuracy;
import com.github.prominence.openweathermap.api.enums.Language;
import com.github.prominence.openweathermap.api.enums.Unit;
protected static final String OPEN_WEATHER_API_VERSION = "2.5";
protected static final String OPEN_WEATHER_BASE_URL = "http://api.openweathermap.org/";
protected static final String OPEN_WEATHER_API_URL = OPEN_WEATHER_BASE_URL + "data/" + OPEN_WEATHER_API_VERSION + "/";
public interface RequestCustomizer<T extends RequestCustomizer<?>> {
protected String authToken;
T accuracy(Accuracy accuracy);
protected AuthenticationTokenBasedRequester(String authToken) {
this.authToken = authToken;
}
T language(Language language);
T unit(Unit unit);
}
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api;
public interface RequestTerminator<T, S> {
T asJava();
S asJSON();
}
@@ -0,0 +1,32 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api;
import java.util.List;
public interface ResponseMapper<T> {
T getSingle(String json);
List<T> getList(String json);
}
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api;
import com.github.prominence.openweathermap.api.model.Coordinate;
public interface SingleLocationWeatherRequester {
SingleResultCurrentWeatherRequestCustomizer byCityName(String cityName);
SingleResultCurrentWeatherRequestCustomizer byCityName(String cityName, String countryCode);
SingleResultCurrentWeatherRequestCustomizer byCityId(long cityId);
SingleResultCurrentWeatherRequestCustomizer byCoordinate(Coordinate coordinate);
SingleResultCurrentWeatherRequestCustomizer byZipCodeAndCountry(String zipCode, String countryCode);
}
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api;
import com.github.prominence.openweathermap.api.model.Weather;
import java.util.concurrent.CompletableFuture;
public interface SingleResultCurrentWeatherAsyncRequestTerminator extends CurrentWeatherRequestTerminator<CompletableFuture<Weather>, CompletableFuture<String>> {
}
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api;
public interface SingleResultCurrentWeatherRequestCustomizer extends RequestCustomizer<SingleResultCurrentWeatherRequestCustomizer> {
SingleResultCurrentWeatherRequestTerminator retrieve();
SingleResultCurrentWeatherAsyncRequestTerminator retrieveAsync();
}
@@ -0,0 +1,28 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api;
import com.github.prominence.openweathermap.api.model.Weather;
public interface SingleResultCurrentWeatherRequestTerminator extends CurrentWeatherRequestTerminator<Weather, String> {
}
@@ -1,119 +0,0 @@
/*
* 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 com.github.prominence.openweathermap.api;
import com.alibaba.fastjson.TypeReference;
import com.github.prominence.openweathermap.api.model.response.UltravioletIndex;
import com.github.prominence.openweathermap.api.model.Coordinates;
import com.github.prominence.openweathermap.api.utils.JSONUtils;
import com.github.prominence.openweathermap.api.utils.RequestUtils;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
import java.util.List;
public class UltravioletIndexRequester extends AuthenticationTokenBasedRequester {
private Coordinates coordinates;
UltravioletIndexRequester(String authToken, float latitude, float longitude) {
super(authToken);
this.coordinates = new Coordinates(latitude, longitude);
}
public UltravioletIndexRequester setCoordinates(Coordinates coordinates) {
this.coordinates = coordinates;
return this;
}
public UltravioletIndexRequester setCoordinates(float latitude, float longitude) {
this.coordinates = new Coordinates(latitude, longitude);
return this;
}
public UltravioletIndex getCurrentUVIndex() {
String requestParameters = String.format("lat=%f&lon=%f", coordinates.getLatitude(), coordinates.getLongitude());
return getSingleObject(requestParameters);
}
public List<UltravioletIndex> getUVIndexForecast(int amountOfDays) {
String requestParameters = String.format("lat=%f&lon=%f&cnt=%d", coordinates.getLatitude(), coordinates.getLongitude(), amountOfDays);
return getListOfObjects(requestParameters);
}
public List<UltravioletIndex> getUVIndexByPeriod(Date from, Date to) {
String requestParameters = String.format("lat=%f&lon=%f&start=%d&end=%d", coordinates.getLatitude(), coordinates.getLongitude(), from.getTime() / 1000, to.getTime() / 1000);
return getListOfObjects(requestParameters);
}
private UltravioletIndex getSingleObject(String requestParameters) {
UltravioletIndex ultravioletIndex = null;
try (InputStream response = executeRequest("uvi", requestParameters)) {
ultravioletIndex = (UltravioletIndex) JSONUtils.parseJSON(response, UltravioletIndex.class);
} catch (IOException ex) {
ex.printStackTrace();
}
return ultravioletIndex;
}
private List<UltravioletIndex> getListOfObjects(String requestParameters) {
List<UltravioletIndex> ultravioletIndex = null;
TypeReference<List<UltravioletIndex>> typeRef = new TypeReference<List<UltravioletIndex>>() {
};
try (InputStream response = executeRequest("uvi/forecast", requestParameters)) {
ultravioletIndex = (List<UltravioletIndex>) JSONUtils.parseJSON(response, typeRef);
} catch (IOException ex) {
ex.printStackTrace();
}
return ultravioletIndex;
}
private InputStream executeRequest(String requestType, String requestSpecificParameters) {
StringBuilder urlBuilder = new StringBuilder(OPEN_WEATHER_API_URL);
urlBuilder.append(requestType);
urlBuilder.append('?');
urlBuilder.append(requestSpecificParameters);
urlBuilder.append("&appid=");
urlBuilder.append(authToken);
InputStream getRequest = null;
try {
getRequest = RequestUtils.executeGetRequest(new URL(urlBuilder.toString()));
} catch (MalformedURLException e) {
e.printStackTrace();
}
return getRequest;
}
}
@@ -1,75 +0,0 @@
/*
* 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 com.github.prominence.openweathermap.api;
import com.github.prominence.openweathermap.api.constants.Unit;
import com.github.prominence.openweathermap.api.model.response.Weather;
import com.github.prominence.openweathermap.api.utils.JSONUtils;
import com.github.prominence.openweathermap.api.utils.RequestUtils;
import java.io.IOException;
import java.io.InputStream;
public class WeatherRequester extends BasicRequester<Weather> {
WeatherRequester(String authToken) {
super(authToken);
}
public WeatherRequester setLanguage(String language) {
this.language = language;
return this;
}
public WeatherRequester setUnitSystem(String unitSystem) {
this.unitSystem = unitSystem;
return this;
}
public WeatherRequester setAccuracy(String accuracy) {
this.accuracy = accuracy;
return this;
}
protected String getRequestType() {
return "weather";
}
protected Weather executeRequest(String requestSpecificParameters) {
Weather weather = null;
try {
InputStream requestResult = RequestUtils.executeGetRequest(buildURL(requestSpecificParameters));
weather = (Weather) JSONUtils.parseJSON(requestResult, Weather.class);
weather.getWind().setUnit(Unit.getWindUnit(unitSystem));
weather.getWeatherInfo().setTemperatureUnit(Unit.getTemperatureUnit(unitSystem));
} catch (IOException ex) {
ex.printStackTrace();
}
return weather;
}
}
@@ -1,63 +0,0 @@
/*
* 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 com.github.prominence.openweathermap.api.constants;
public final class Language {
private Language() {}
public static final String ARABIC = "ar";
public static final String BULGARIAN = "bg";
public static final String CATALAN = "ca";
public static final String CZECH = "cz";
public static final String GERMAN = "de";
public static final String GREEK = "el";
public static final String ENGLISH = "en";
public static final String PERSIAN = "fa";
public static final String FINNISH = "fi";
public static final String FRENCH = "fr";
public static final String GALICIAN = "gl";
public static final String CROATIAN = "hr";
public static final String HUNGARIAN = "hu";
public static final String ITALIAN = "it";
public static final String JAPANESE = "ja";
public static final String KOREAN = "kr";
public static final String LATVIAN = "la";
public static final String LITHUANIAN = "lt";
public static final String MACEDONIAN = "mk";
public static final String DUTCH = "nl";
public static final String POLISH = "pl";
public static final String PORTUGUESE = "pt";
public static final String ROMANIAN ="ro";
public static final String RUSSIAN = "ru";
public static final String SWEDISH = "se";
public static final String SLOVAK = "sk";
public static final String SLOVENIAN = "sl";
public static final String SPANISH = "en";
public static final String TURKISH = "tr";
public static final String UKRANIAN = "uk";
public static final String VIETNAMESE = "vi";
public static final String CHINESE_SIMPLIFIED = "zh_cn";
public static final String CHINESE_TRADITIONAL = "zh_tw";
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 Alexey Zinchenko
* Copyright (c) 2019 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
@@ -20,13 +20,19 @@
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.constants;
package com.github.prominence.openweathermap.api.enums;
public final class Accuracy {
public enum Accuracy {
LIKE("like"),
ACCURATE("accurate");
private Accuracy() {}
private final String value;
public static final String LIKE = "like";
public static final String ACCURATE = "accurate";
Accuracy(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
@@ -0,0 +1,70 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api.enums;
public enum Language {
ARABIC("ar"),
BULGARIAN("bg"),
CATALAN("ca"),
CZECH("cz"),
GERMAN("de"),
GREEK("el"),
ENGLISH("en"),
PERSIAN("fa"),
FINNISH("fi"),
FRENCH("fr"),
GALICIAN("gl"),
CROATIAN("hr"),
HUNGARIAN("hu"),
ITALIAN("it"),
JAPANESE("ja"),
KOREAN("kr"),
LATVIAN("la"),
LITHUANIAN("lt"),
MACEDONIAN("mk"),
DUTCH("nl"),
POLISH("pl"),
PORTUGUESE("pt"),
ROMANIAN ("ro"),
RUSSIAN("ru"),
SWEDISH("se"),
SLOVAK("sk"),
SLOVENIAN("sl"),
SPANISH("en"),
TURKISH("tr"),
UKRANIAN("uk"),
VIETNAMESE("vi"),
CHINESE_SIMPLIFIED("zh_cn"),
CHINESE_TRADITIONAL("zh_tw");
private final String value;
Language(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 Alexey Zinchenko
* Copyright (c) 2019 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
@@ -20,32 +20,23 @@
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model;
package com.github.prominence.openweathermap.api.enums;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
public enum ResponseType {
@EqualsAndHashCode
@AllArgsConstructor
public class Coordinates {
JAVA_OBJECT("java)"),
JSON("json"),
XML("xml"),
HTML("html"),
RAW("raw");
@JSONField(name = "lat")
// City geo location, latitude. Valid range: [-90, 90]
@Getter
@Setter
private float latitude;
private final String value;
@JSONField(name = "lon")
// City geo location, longitude. Valid range: [-180, 180]
@Getter
@Setter
private float longitude;
ResponseType(String value) {
this.value = value;
}
@Override
public String toString() {
return "latitude=" + latitude + ", longitude=" + longitude;
public String getValue() {
return value;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 Alexey Zinchenko
* Copyright (c) 2019 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
@@ -18,10 +18,9 @@
* 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 com.github.prominence.openweathermap.api.constants;
package com.github.prominence.openweathermap.api.enums;
public enum TimeFrame {
YEAR,
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 Alexey Zinchenko
* Copyright (c) 2019 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
@@ -20,17 +20,21 @@
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.constants;
package com.github.prominence.openweathermap.api.enums;
public final class Unit {
public enum Unit {
private Unit() {}
METRIC_SYSTEM("metric"),
IMPERIAL_SYSTEM("imperial"),
STANDARD_SYSTEM("standard");
public static final String METRIC_SYSTEM = "metric";
public static final String IMPERIAL_SYSTEM = "imperial";
public static final String STANDARD_SYSTEM = "standard";
private final String value;
public static String getWindUnit(String type) {
Unit(String value) {
this.value = value;
}
public static String getWindUnit(Unit type) {
switch (type) {
case IMPERIAL_SYSTEM:
return "miles/hour";
@@ -41,16 +45,19 @@ public final class Unit {
}
}
public static char getTemperatureUnit(String type) {
public static String getTemperatureUnit(Unit type) {
switch (type) {
case METRIC_SYSTEM:
return '℃';
return "";
case IMPERIAL_SYSTEM:
return '℉';
return "";
case STANDARD_SYSTEM:
default:
return '';
return "";
}
}
public String getValue() {
return value;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 Alexey Zinchenko
* Copyright (c) 2019 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
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 Alexey Zinchenko
* Copyright (c) 2019 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
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 Alexey Zinchenko
* Copyright (c) 2019 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
@@ -20,48 +20,25 @@
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model.response;
package com.github.prominence.openweathermap.api.impl;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import com.github.prominence.openweathermap.api.CurrentWeatherRequester;
import com.github.prominence.openweathermap.api.MultipleLocationsWeatherRequester;
import com.github.prominence.openweathermap.api.SingleLocationWeatherRequester;
import java.time.Instant;
import java.util.Date;
public class CurrentWeatherRequesterImpl implements CurrentWeatherRequester {
@EqualsAndHashCode
public class UltravioletIndex {
private RequestUrlBuilder urlBuilder = new RequestUrlBuilder("http://api.openweathermap.org/data/2.5/");
@JSONField(name = "lat")
@Getter
@Setter
float latitude;
@JSONField(name = "lon")
@Getter
@Setter
float longitude;
@JSONField(name = "date_iso")
@Getter
@Setter
String dateISO;
@JSONField(name = "date")
@Getter
@Setter
int dateTimestamp;
@Getter
@Setter
float value;
public Date getCalculationDate() {
return Date.from(Instant.ofEpochSecond(dateTimestamp));
CurrentWeatherRequesterImpl(String apiKey) {
urlBuilder.addRequestParameter("appid", apiKey);
}
public String toString() {
return String.format("Date: %s, Ultraviolet value: %f", getCalculationDate(), value);
public SingleLocationWeatherRequester single() {
return new SingleLocationCurrentWeatherRequesterImpl(urlBuilder);
}
public MultipleLocationsWeatherRequester multiple() {
return new MultipleLocationsCurrentWeatherRequesterImpl(urlBuilder);
}
}
@@ -0,0 +1,299 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api.impl;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.prominence.openweathermap.api.ResponseMapper;
import com.github.prominence.openweathermap.api.enums.Unit;
import com.github.prominence.openweathermap.api.model.*;
import java.io.IOException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
import java.util.TimeZone;
/**
* Official API response documentation:
* Parameters:
* --- coord
* |- coord.lon City geo location, longitude
* |- coord.lat City geo location, latitude
* --- weather (more info Weather condition codes)
* |- weather.id Weather condition id
* |- weather.main Group of weather parameters (Rain, Snow, Extreme etc.)
* |- weather.description Weather condition within the group
* |- weather.icon Weather icon id
* --- base Internal parameter
* --- main
* |- main.temp Temperature. Unit Default: Kelvin, Metric: Celsius, Imperial: Fahrenheit.
* |- main.pressure Atmospheric pressure (on the sea level, if there is no sea_level or grnd_level data), hPa
* |- main.humidity Humidity, %
* |- main.temp_min Minimum temperature at the moment. This is deviation from current temp that is possible for large cities and megalopolises geographically expanded (use these parameter optionally). Unit Default: Kelvin, Metric: Celsius, Imperial: Fahrenheit.
* |- main.temp_max Maximum temperature at the moment. This is deviation from current temp that is possible for large cities and megalopolises geographically expanded (use these parameter optionally). Unit Default: Kelvin, Metric: Celsius, Imperial: Fahrenheit.
* |- main.sea_level Atmospheric pressure on the sea level, hPa
* |- main.grnd_level Atmospheric pressure on the ground level, hPa
* --- wind
* |- wind.speed Wind speed. Unit Default: meter/sec, Metric: meter/sec, Imperial: miles/hour.
* |- wind.deg Wind direction, degrees (meteorological)
* --- clouds
* |- clouds.all Cloudiness, %
* --- rain
* |- rain.1h Rain volume for the last 1 hour, mm
* |- rain.3h Rain volume for the last 3 hours, mm
* --- snow
* |- snow.1h Snow volume for the last 1 hour, mm
* |- snow.3h Snow volume for the last 3 hours, mm
* --- dt Time of data calculation, unix, UTC
* --- sys
* |- sys.type Internal parameter
* |- sys.id Internal parameter
* |- sys.message Internal parameter
* |- sys.country Country code (GB, JP etc.)
* |- sys.sunrise Sunrise time, unix, UTC
* |- sys.sunset Sunset time, unix, UTC
* --- id City ID
* --- name City name
* --- cod Internal parameter
*/
public class CurrentWeatherResponseMapper implements ResponseMapper<Weather> {
private Unit unit;
CurrentWeatherResponseMapper(Unit unit) {
this.unit = unit != null ? unit : Unit.STANDARD_SYSTEM;
}
@Override
public Weather getSingle(String json) {
ObjectMapper objectMapper = new ObjectMapper();
Weather weather;
try {
JsonNode root = objectMapper.readTree(json);
weather = getSingle(root);
} catch (IOException e) {
throw new RuntimeException("Cannot parse Weather response");
}
return weather;
}
private Weather getSingle(JsonNode root) {
final Weather weather = new Weather();
JsonNode weatherState = root.get("weather").get(0);
weather.setWeatherState(weatherState.get("main").asText());
weather.setWeatherDescription(weatherState.get("description").asText());
weather.setWeatherIconUrl("http://openweathermap.org/img/w/" + weatherState.get("icon").asText() + ".png");
weather.setTemperature(parseTemperature(root));
weather.setPressure(parsePressure(root));
weather.setHumidity(parseHumidity(root));
weather.setWind(parseWind(root));
weather.setRain(parseRain(root));
weather.setSnow(parseSnow(root));
weather.setClouds(parseClouds(root));
weather.setLocation(parseLocation(root));
final JsonNode dtNode = root.get("dt");
if (dtNode != null) {
weather.setRequestedOn(LocalDateTime.ofInstant(Instant.ofEpochSecond(dtNode.asInt()), TimeZone.getDefault().toZoneId()));
}
return weather;
}
@Override
public List<Weather> getList(String json) {
ObjectMapper objectMapper = new ObjectMapper();
List<Weather> weatherList = new ArrayList<>();
try {
final JsonNode root = objectMapper.readTree(json);
final JsonNode listNode = root.get("list");
listNode.forEach(jsonNode -> weatherList.add(getSingle(jsonNode)));
} catch (IOException e) {
throw new RuntimeException("Cannot parse Weather response");
}
return weatherList;
}
private Temperature parseTemperature(JsonNode root) {
Temperature temperature = new Temperature();
final JsonNode mainNode = root.get("main");
temperature.setValue(mainNode.get("temp").asDouble());
final JsonNode tempMaxNode = mainNode.get("temp_max");
final JsonNode tempMinNode = mainNode.get("temp_min");
if (tempMaxNode != null) {
temperature.setMaxTemperature(tempMaxNode.asDouble());
}
if (tempMinNode != null) {
temperature.setMinTemperature(tempMinNode.asDouble());
}
temperature.setUnit(Unit.getTemperatureUnit(unit));
return temperature;
}
private Pressure parsePressure(JsonNode root) {
Pressure pressure = new Pressure();
final JsonNode mainNode = root.get("main");
pressure.setValue(mainNode.get("pressure").asDouble());
final JsonNode seaLevelNode = mainNode.get("sea_level");
final JsonNode grndLevelNode = mainNode.get("grnd_level");
if (seaLevelNode != null) {
pressure.setSeaLevelValue(seaLevelNode.asDouble());
}
if (grndLevelNode != null) {
pressure.setGroundLevelValue(grndLevelNode.asDouble());
}
return pressure;
}
private Humidity parseHumidity(JsonNode root) {
Humidity humidity = new Humidity();
final JsonNode mainNode = root.get("main");
humidity.setValue(mainNode.get("humidity").asInt());
return humidity;
}
private Wind parseWind(JsonNode root) {
Wind wind = new Wind();
final JsonNode windNode = root.get("wind");
wind.setSpeed(windNode.get("speed").asDouble());
final JsonNode degNode = windNode.get("deg");
if (degNode != null) {
wind.setDegrees(degNode.asDouble());
}
wind.setUnit(Unit.getWindUnit(unit));
return wind;
}
private Rain parseRain(JsonNode root) {
Rain rain = null;
final JsonNode rainNode = root.get("rain");
if (rainNode != null) {
rain = new Rain();
final JsonNode oneHourNode = rainNode.get("1h");
final JsonNode threeHourNode = rainNode.get("3h");
if (oneHourNode != null) {
rain.setOneHourRainLevel(oneHourNode.asDouble());
}
if (threeHourNode != null) {
rain.setThreeHourRainLevel(threeHourNode.asDouble());
}
}
return rain;
}
private Snow parseSnow(JsonNode root) {
Snow snow = null;
final JsonNode snowNode = root.get("snow");
if (snowNode != null) {
snow = new Snow();
final JsonNode oneHourNode = snowNode.get("1h");
final JsonNode threeHourNode = snowNode.get("3h");
if (oneHourNode != null) {
snow.setOneHourSnowLevel(oneHourNode.asDouble());
}
if (threeHourNode != null) {
snow.setThreeHourSnowLevel(threeHourNode.asDouble());
}
}
return snow;
}
private Clouds parseClouds(JsonNode root) {
Clouds clouds = new Clouds();
final JsonNode cloudsNode = root.get("clouds");
final JsonNode allValueNode = cloudsNode.get("all");
if (allValueNode != null) {
clouds.setValue((byte) allValueNode.asInt());
}
return clouds;
}
private Location parseLocation(JsonNode root) {
Location location = new Location();
location.setName(root.get("name").asText());
location.setId(root.get("id").asInt());
final JsonNode timezoneNode = root.get("timezone");
if (timezoneNode != null) {
location.setZoneOffset(ZoneOffset.ofTotalSeconds(timezoneNode.asInt()));
}
final JsonNode sysNode = root.get("sys");
if (sysNode != null) {
final JsonNode countryNode = sysNode.get("country");
if (countryNode != null) {
location.setCountryCode(countryNode.asText());
}
final JsonNode sunriseNode = sysNode.get("sunrise");
final JsonNode sunsetNode = sysNode.get("sunset");
if (sunriseNode != null) {
location.setSunrise(LocalDateTime.ofInstant(Instant.ofEpochSecond(sunriseNode.asInt()), TimeZone.getDefault().toZoneId()));
}
if (sunsetNode != null) {
location.setSunset(LocalDateTime.ofInstant(Instant.ofEpochSecond(sunsetNode.asInt()), TimeZone.getDefault().toZoneId()));
}
}
final JsonNode coordNode = root.get("coord");
if (coordNode != null) {
JsonNode latitudeNode = coordNode.get("lat");
if (latitudeNode == null) {
latitudeNode = coordNode.get("Lat"); // in multiple request
}
JsonNode longitudeNode = coordNode.get("lon");
if (longitudeNode == null) {
longitudeNode = coordNode.get("Lon"); // in multiple request
}
if (latitudeNode != null && longitudeNode != null) {
location.setCoordinate(new Coordinate(latitudeNode.asDouble(), longitudeNode.asDouble()));
}
}
return location;
}
}
@@ -0,0 +1,76 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api.impl;
import com.github.prominence.openweathermap.api.MultipleLocationsWeatherRequester;
import com.github.prominence.openweathermap.api.MultipleResultCurrentWeatherRequestCustomizer;
import com.github.prominence.openweathermap.api.model.Coordinate;
import com.github.prominence.openweathermap.api.model.CoordinateRectangle;
public class MultipleLocationsCurrentWeatherRequesterImpl implements MultipleLocationsWeatherRequester {
private RequestUrlBuilder urlBuilder;
MultipleLocationsCurrentWeatherRequesterImpl(RequestUrlBuilder urlBuilder) {
this.urlBuilder = urlBuilder;
}
@Override
public MultipleResultCurrentWeatherRequestCustomizer byRectangle(CoordinateRectangle rectangle, int zoom) {
String coordinates = rectangle.getValue() + "," + zoom;
urlBuilder.append("box/city");
urlBuilder.addRequestParameter("bbox", coordinates);
return new MultipleResultCurrentWeatherRequestCustomizerImpl(urlBuilder);
}
@Override
public MultipleResultCurrentWeatherRequestCustomizer byRectangle(CoordinateRectangle rectangle, int zoom, boolean useServerClustering) {
String coordinates = rectangle.getValue() + "," + zoom;
urlBuilder.append("box/city");
urlBuilder.addRequestParameter("bbox", coordinates);
urlBuilder.addRequestParameter("cluster", useServerClustering ? "yes" : "no");
return new MultipleResultCurrentWeatherRequestCustomizerImpl(urlBuilder);
}
@Override
public MultipleResultCurrentWeatherRequestCustomizer byCitiesInCycle(Coordinate point, int citiesCount) {
urlBuilder.append("find");
urlBuilder.addRequestParameter("lat", Double.toString(point.getLatitude()));
urlBuilder.addRequestParameter("lon", Double.toString(point.getLongitude()));
urlBuilder.addRequestParameter("cnt", Integer.toString(citiesCount));
return new MultipleResultCurrentWeatherRequestCustomizerImpl(urlBuilder);
}
@Override
public MultipleResultCurrentWeatherRequestCustomizer byCitiesInCycle(Coordinate point, int citiesCount, boolean useServerClustering) {
urlBuilder.append("find");
urlBuilder.addRequestParameter("lat", Double.toString(point.getLatitude()));
urlBuilder.addRequestParameter("lon", Double.toString(point.getLongitude()));
urlBuilder.addRequestParameter("cnt", Integer.toString(citiesCount));
urlBuilder.addRequestParameter("cluster", useServerClustering ? "yes" : "no");
return new MultipleResultCurrentWeatherRequestCustomizerImpl(urlBuilder);
}
}
@@ -0,0 +1,68 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api.impl;
import com.github.prominence.openweathermap.api.MultipleResultCurrentWeatherAsyncRequestTerminator;
import com.github.prominence.openweathermap.api.enums.Unit;
import com.github.prominence.openweathermap.api.model.Weather;
import com.github.prominence.openweathermap.api.utils.RequestUtils;
import java.util.List;
import java.util.concurrent.CompletableFuture;
public class MultipleResultCurrentWeatherAsyncRequestTerminatorImpl implements MultipleResultCurrentWeatherAsyncRequestTerminator {
private RequestUrlBuilder urlBuilder;
private Unit unit;
MultipleResultCurrentWeatherAsyncRequestTerminatorImpl(RequestUrlBuilder urlBuilder, Unit unit) {
this.urlBuilder = urlBuilder;
this.unit = unit;
}
@Override
public CompletableFuture<List<Weather>> asJava() {
return CompletableFuture.supplyAsync(() -> new CurrentWeatherResponseMapper(unit).getList(getRawResponse()));
}
@Override
public CompletableFuture<String> asJSON() {
return CompletableFuture.supplyAsync(this::getRawResponse);
}
@Override
public CompletableFuture<String> asXML() {
urlBuilder.addRequestParameter("mode", "xml");
return CompletableFuture.supplyAsync(this::getRawResponse);
}
@Override
public CompletableFuture<String> asHTML() {
urlBuilder.addRequestParameter("mode", "html");
return CompletableFuture.supplyAsync(this::getRawResponse);
}
private String getRawResponse() {
return RequestUtils.getRawResponse(urlBuilder.buildUrl());
}
}
@@ -0,0 +1,85 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api.impl;
import com.github.prominence.openweathermap.api.MultipleResultCurrentWeatherAsyncRequestTerminator;
import com.github.prominence.openweathermap.api.MultipleResultCurrentWeatherRequestCustomizer;
import com.github.prominence.openweathermap.api.MultipleResultCurrentWeatherRequestTerminator;
import com.github.prominence.openweathermap.api.enums.Accuracy;
import com.github.prominence.openweathermap.api.enums.Language;
import com.github.prominence.openweathermap.api.enums.Unit;
public class MultipleResultCurrentWeatherRequestCustomizerImpl implements MultipleResultCurrentWeatherRequestCustomizer {
private RequestUrlBuilder urlBuilder;
private Accuracy accuracy;
private Language language;
private Unit unit;
MultipleResultCurrentWeatherRequestCustomizerImpl(RequestUrlBuilder urlBuilder) {
this.urlBuilder = urlBuilder;
}
@Override
public MultipleResultCurrentWeatherRequestTerminator retrieve() {
applyCustomization();
return new MultipleResultCurrentWeatherRequestTerminatorImpl(urlBuilder, unit);
}
@Override
public MultipleResultCurrentWeatherAsyncRequestTerminator retrieveAsync() {
applyCustomization();
return new MultipleResultCurrentWeatherAsyncRequestTerminatorImpl(urlBuilder, unit);
}
@Override
public MultipleResultCurrentWeatherRequestCustomizer accuracy(Accuracy accuracy) {
this.accuracy = accuracy;
return this;
}
@Override
public MultipleResultCurrentWeatherRequestCustomizer language(Language language) {
this.language = language;
return this;
}
@Override
public MultipleResultCurrentWeatherRequestCustomizer unit(Unit unit) {
this.unit = unit;
return this;
}
private void applyCustomization() {
if (accuracy != null) {
urlBuilder.addRequestParameter("type", accuracy.getValue());
}
if (language != null) {
urlBuilder.addRequestParameter("lang", language.getValue());
}
if (unit != null && unit != Unit.STANDARD_SYSTEM) {
urlBuilder.addRequestParameter("units", unit.getValue());
}
}
}
@@ -0,0 +1,68 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api.impl;
import com.github.prominence.openweathermap.api.MultipleResultCurrentWeatherRequestTerminator;
import com.github.prominence.openweathermap.api.enums.Unit;
import com.github.prominence.openweathermap.api.model.Weather;
import com.github.prominence.openweathermap.api.utils.RequestUtils;
import java.io.InputStream;
import java.util.List;
public class MultipleResultCurrentWeatherRequestTerminatorImpl implements MultipleResultCurrentWeatherRequestTerminator {
private RequestUrlBuilder urlBuilder;
private Unit unit;
MultipleResultCurrentWeatherRequestTerminatorImpl(RequestUrlBuilder urlBuilder, Unit unit) {
this.urlBuilder = urlBuilder;
this.unit = unit;
}
@Override
public List<Weather> asJava() {
return new CurrentWeatherResponseMapper(unit).getList(getRawResponse());
}
@Override
public String asJSON() {
return getRawResponse();
}
@Override
public String asXML() {
urlBuilder.addRequestParameter("mode", "xml");
return getRawResponse();
}
@Override
public String asHTML() {
urlBuilder.addRequestParameter("mode", "html");
return getRawResponse();
}
private String getRawResponse() {
return RequestUtils.getRawResponse(urlBuilder.buildUrl());
}
}
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api.impl;
public class OpenWeatherMapClient {
private final String apiKey;
public OpenWeatherMapClient(String apiKey) {
this.apiKey = apiKey;
}
public CurrentWeatherRequesterImpl currentWeather() {
return new CurrentWeatherRequesterImpl(apiKey);
}
}
@@ -20,32 +20,36 @@
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.test;
package com.github.prominence.openweathermap.api.impl;
import com.github.prominence.openweathermap.api.AirPollutionRequester;
import com.github.prominence.openweathermap.api.constants.TimeFrame;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.Date;
public class RequestUrlBuilder {
public class AirPollutionRequestedIntegrationTest extends ApiTest {
private StringBuilder builder = new StringBuilder();
private Map<String, Object> requestParameters = new HashMap<>();
private static AirPollutionRequester airPollutionRequester;
@BeforeClass
public static void setup() {
airPollutionRequester = getManager().getAirPollutionRequester(0f, 10f, new Date(116, 11, 25), TimeFrame.DAY);
public RequestUrlBuilder(String baseUrl) {
builder.append(baseUrl);
}
@Test
public void whenRequestAirPollutionState_thenReturnNotNull() {
assert airPollutionRequester.retrieve() != null;
void append(String value) {
builder.append(value);
}
@Test(expected = IllegalArgumentException.class)
public void whenRequestAirPollutionStateWithoutAnyParam_thenThrowAnException() {
AirPollutionRequester requester = getManager().getAirPollutionRequester(0f, 10f, null, TimeFrame.DAY);
requester.retrieve();
public void addRequestParameter(String key, Object value) {
requestParameters.put(key, value);
}
String buildUrl() {
final String joinedParameters = requestParameters.entrySet().stream()
.map(entry -> entry.getKey() + "=" + entry.getValue())
.collect(Collectors.joining("&"));
builder.append('?');
builder.append(joinedParameters);
System.out.println(builder.toString());
return builder.toString();
}
}
@@ -0,0 +1,62 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api.impl;
import com.github.prominence.openweathermap.api.SingleLocationWeatherRequester;
import com.github.prominence.openweathermap.api.model.Coordinate;
public class SingleLocationCurrentWeatherRequesterImpl implements SingleLocationWeatherRequester {
private RequestUrlBuilder urlBuilder;
SingleLocationCurrentWeatherRequesterImpl(RequestUrlBuilder urlBuilder) {
this.urlBuilder = urlBuilder;
urlBuilder.append("weather");
}
public SingleResultCurrentWeatherRequestCustomizerImpl byCityName(String cityName) {
urlBuilder.addRequestParameter("q", cityName);
return new SingleResultCurrentWeatherRequestCustomizerImpl(urlBuilder);
}
public SingleResultCurrentWeatherRequestCustomizerImpl byCityName(String cityName, String countryCode) {
urlBuilder.addRequestParameter("q", cityName + "," + countryCode);
return new SingleResultCurrentWeatherRequestCustomizerImpl(urlBuilder);
}
public SingleResultCurrentWeatherRequestCustomizerImpl byCityId(long cityId) {
urlBuilder.addRequestParameter("id", cityId);
return new SingleResultCurrentWeatherRequestCustomizerImpl(urlBuilder);
}
public SingleResultCurrentWeatherRequestCustomizerImpl byCoordinate(Coordinate coordinate) {
urlBuilder.addRequestParameter("lat", String.valueOf(coordinate.getLatitude()));
urlBuilder.addRequestParameter("lon", String.valueOf(coordinate.getLongitude()));
return new SingleResultCurrentWeatherRequestCustomizerImpl(urlBuilder);
}
public SingleResultCurrentWeatherRequestCustomizerImpl byZipCodeAndCountry(String zipCode, String countryCode) {
urlBuilder.addRequestParameter("zip", zipCode + "," + countryCode);
return new SingleResultCurrentWeatherRequestCustomizerImpl(urlBuilder);
}
}
@@ -0,0 +1,67 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api.impl;
import com.github.prominence.openweathermap.api.SingleResultCurrentWeatherAsyncRequestTerminator;
import com.github.prominence.openweathermap.api.enums.Unit;
import com.github.prominence.openweathermap.api.model.Weather;
import com.github.prominence.openweathermap.api.utils.RequestUtils;
import java.util.concurrent.CompletableFuture;
public class SingleResultCurrentWeatherAsyncRequestTerminatorImpl implements SingleResultCurrentWeatherAsyncRequestTerminator {
private RequestUrlBuilder urlBuilder;
private Unit unit;
SingleResultCurrentWeatherAsyncRequestTerminatorImpl(RequestUrlBuilder urlBuilder, Unit unit) {
this.urlBuilder = urlBuilder;
this.unit = unit;
}
@Override
public CompletableFuture<Weather> asJava() {
return CompletableFuture.supplyAsync(() -> new CurrentWeatherResponseMapper(unit).getSingle(getRawResponse()));
}
@Override
public CompletableFuture<String> asJSON() {
return CompletableFuture.supplyAsync(this::getRawResponse);
}
@Override
public CompletableFuture<String> asXML() {
urlBuilder.addRequestParameter("mode", "xml");
return CompletableFuture.supplyAsync(this::getRawResponse);
}
@Override
public CompletableFuture<String> asHTML() {
urlBuilder.addRequestParameter("mode", "html");
return CompletableFuture.supplyAsync(this::getRawResponse);
}
private String getRawResponse() {
return RequestUtils.getRawResponse(urlBuilder.buildUrl());
}
}
@@ -0,0 +1,85 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api.impl;
import com.github.prominence.openweathermap.api.SingleResultCurrentWeatherAsyncRequestTerminator;
import com.github.prominence.openweathermap.api.SingleResultCurrentWeatherRequestCustomizer;
import com.github.prominence.openweathermap.api.SingleResultCurrentWeatherRequestTerminator;
import com.github.prominence.openweathermap.api.enums.Accuracy;
import com.github.prominence.openweathermap.api.enums.Language;
import com.github.prominence.openweathermap.api.enums.Unit;
public class SingleResultCurrentWeatherRequestCustomizerImpl implements SingleResultCurrentWeatherRequestCustomizer {
private RequestUrlBuilder urlBuilder;
private Accuracy accuracy;
private Language language;
private Unit unit;
SingleResultCurrentWeatherRequestCustomizerImpl(RequestUrlBuilder urlBuilder) {
this.urlBuilder = urlBuilder;
}
@Override
public SingleResultCurrentWeatherRequestTerminator retrieve() {
applyCustomization();
return new SingleResultCurrentWeatherRequestTerminatorImpl(urlBuilder, unit);
}
@Override
public SingleResultCurrentWeatherAsyncRequestTerminator retrieveAsync() {
applyCustomization();
return new SingleResultCurrentWeatherAsyncRequestTerminatorImpl(urlBuilder, unit);
}
@Override
public SingleResultCurrentWeatherRequestCustomizer accuracy(Accuracy accuracy) {
this.accuracy = accuracy;
return this;
}
@Override
public SingleResultCurrentWeatherRequestCustomizer language(Language language) {
this.language = language;
return this;
}
@Override
public SingleResultCurrentWeatherRequestCustomizer unit(Unit unit) {
this.unit = unit;
return this;
}
private void applyCustomization() {
if (accuracy != null) {
urlBuilder.addRequestParameter("type", accuracy.getValue());
}
if (language != null) {
urlBuilder.addRequestParameter("lang", language.getValue());
}
if (unit != null && unit != Unit.STANDARD_SYSTEM) {
urlBuilder.addRequestParameter("units", unit.getValue());
}
}
}
@@ -0,0 +1,67 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api.impl;
import com.github.prominence.openweathermap.api.SingleResultCurrentWeatherRequestTerminator;
import com.github.prominence.openweathermap.api.enums.Unit;
import com.github.prominence.openweathermap.api.model.Weather;
import com.github.prominence.openweathermap.api.utils.RequestUtils;
import java.io.InputStream;
public class SingleResultCurrentWeatherRequestTerminatorImpl implements SingleResultCurrentWeatherRequestTerminator {
private RequestUrlBuilder urlBuilder;
private Unit unit;
SingleResultCurrentWeatherRequestTerminatorImpl(RequestUrlBuilder urlBuilder, Unit unit) {
this.urlBuilder = urlBuilder;
this.unit = unit;
}
@Override
public Weather asJava() {
return new CurrentWeatherResponseMapper(unit).getSingle(asJSON());
}
@Override
public String asJSON() {
return getRawResponse();
}
@Override
public String asXML() {
urlBuilder.addRequestParameter("mode", "xml");
return getRawResponse();
}
@Override
public String asHTML() {
urlBuilder.addRequestParameter("mode", "html");
return getRawResponse();
}
private String getRawResponse() {
return RequestUtils.getRawResponse(urlBuilder.buildUrl());
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 Alexey Zinchenko
* Copyright (c) 2019 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
@@ -22,22 +22,46 @@
package com.github.prominence.openweathermap.api.model;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import java.util.Objects;
@EqualsAndHashCode
public class Clouds {
@JSONField(name = "all")
// Cloudiness, %
@Getter
@Setter
private byte cloudiness;
private byte value;
public Clouds() {
}
public Clouds(byte value) {
this.value = value;
}
public byte getValue() {
return value;
}
public void setValue(byte value) {
this.value = value;
}
public String getUnit() {
return "%";
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Clouds)) return false;
Clouds clouds = (Clouds) o;
return value == clouds.value;
}
@Override
public int hashCode() {
return Objects.hash(value);
}
@Override
public String toString() {
return "Cloudiness: " + cloudiness + "%";
return "Clouds: " + value + getUnit();
}
}
@@ -0,0 +1,86 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api.model;
import java.util.Objects;
public class Coordinate {
private double latitude;
private double longitude;
public Coordinate(double latitude, double longitude) {
this.latitude = latitude;
this.longitude = longitude;
}
public void setLatitude(double latitude) {
if (latitude < -90 || latitude > 90) {
throw new IllegalArgumentException("Latitude value must be in the next range: [-90.0; 90.0].");
}
this.latitude = latitude;
}
public void setLongitude(double longitude) {
if (longitude < -180 || longitude > 180) {
throw new IllegalArgumentException("Longitude value must be in the next range: [-180.0; 180.0].");
}
this.longitude = longitude;
}
public double getLatitude() {
return latitude;
}
public double getLongitude() {
return longitude;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Coordinate)) return false;
Coordinate that = (Coordinate) o;
return Double.compare(that.latitude, latitude) == 0 &&
Double.compare(that.longitude, longitude) == 0;
}
@Override
public int hashCode() {
return Objects.hash(latitude, longitude);
}
@Override
public String toString() {
return formatAsDegree(latitude) +
", " + formatAsDegree(longitude);
}
private String formatAsDegree(double value) {
int degrees = (int) value;
double secondsDouble = value % 1 * 60;
int minutes = (int) secondsDouble;
int seconds = (int) (secondsDouble % 1 * 60);
return String.format("%s° %s %s″", degrees, minutes, seconds);
}
}
@@ -0,0 +1,81 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api.model;
import java.util.Objects;
public class CoordinateRectangle {
private double longitudeLeft;
private double latitudeBottom;
private double longitudeRight;
private double latitudeTop;
public CoordinateRectangle(double longitudeLeft, double latitudeBottom, double longitudeRight, double latitudeTop) {
this.longitudeLeft = longitudeLeft;
this.latitudeBottom = latitudeBottom;
this.longitudeRight = longitudeRight;
this.latitudeTop = latitudeTop;
}
public double getLongitudeLeft() {
return longitudeLeft;
}
public double getLatitudeBottom() {
return latitudeBottom;
}
public double getLongitudeRight() {
return longitudeRight;
}
public double getLatitudeTop() {
return latitudeTop;
}
public String getValue() {
return longitudeLeft + "," + latitudeBottom + "," + longitudeRight + "," + latitudeTop;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof CoordinateRectangle)) return false;
CoordinateRectangle rectangle = (CoordinateRectangle) o;
return Double.compare(rectangle.longitudeLeft, longitudeLeft) == 0 &&
Double.compare(rectangle.latitudeBottom, latitudeBottom) == 0 &&
Double.compare(rectangle.longitudeRight, longitudeRight) == 0 &&
Double.compare(rectangle.latitudeTop, latitudeTop) == 0;
}
@Override
public int hashCode() {
return Objects.hash(longitudeLeft, latitudeBottom, longitudeRight, latitudeTop);
}
@Override
public String toString() {
return "Rectangle: " + getValue();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 Alexey Zinchenko
* Copyright (c) 2019 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
@@ -22,37 +22,46 @@
package com.github.prominence.openweathermap.api.model;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import java.util.Objects;
@EqualsAndHashCode
public class CityInfo {
public class Humidity {
// City ID
@Getter
@Setter
private long id;
private int value;
// City name
@Getter
@Setter
private String name;
public Humidity() {
}
@JSONField(name = "coord")
@Getter
@Setter
private Coordinates coordinates;
public Humidity(byte value) {
this.value = value;
}
// Country code (GB, JP etc.)
@Getter
@Setter
private String country;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public String getUnit() {
return "%";
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Humidity)) return false;
Humidity humidity = (Humidity) o;
return value == humidity.value;
}
@Override
public int hashCode() {
return Objects.hash(value);
}
@Override
public String toString() {
return "City: " + name + "(" + id + "). Coordinates: " + coordinates + '\n' + "Country: " + country;
return "Humidity: " + value + getUnit();
}
}
@@ -0,0 +1,124 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api.model;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Objects;
public class Location {
private String countryCode;
private String name;
private Integer id;
private LocalDateTime sunrise;
private LocalDateTime sunset;
private ZoneOffset zoneOffset;
private Coordinate coordinate;
public String getCountryCode() {
return countryCode;
}
public void setCountryCode(String countryCode) {
this.countryCode = countryCode;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public LocalDateTime getSunrise() {
return sunrise;
}
public void setSunrise(LocalDateTime sunrise) {
this.sunrise = sunrise;
}
public LocalDateTime getSunset() {
return sunset;
}
public void setSunset(LocalDateTime sunset) {
this.sunset = sunset;
}
public ZoneOffset getZoneOffset() {
return zoneOffset;
}
public void setZoneOffset(ZoneOffset zoneOffset) {
this.zoneOffset = zoneOffset;
}
public Coordinate getCoordinate() {
return coordinate;
}
public void setCoordinate(Coordinate coordinate) {
this.coordinate = coordinate;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Location)) return false;
Location location = (Location) o;
return Objects.equals(countryCode, location.countryCode) &&
Objects.equals(name, location.name) &&
Objects.equals(id, location.id) &&
Objects.equals(sunrise, location.sunrise) &&
Objects.equals(sunset, location.sunset) &&
Objects.equals(zoneOffset, location.zoneOffset) &&
Objects.equals(coordinate, location.coordinate);
}
@Override
public int hashCode() {
return Objects.hash(countryCode, name, id, sunrise, sunset, zoneOffset, coordinate);
}
@Override
public String toString() {
String result = coordinate != null ? (coordinate.toString() + ", ") : "";
return result +
"Country code: '" + countryCode + '\'' +
", Name: '" + name + '\'' +
", ID: " + id;
}
}
@@ -0,0 +1,88 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api.model;
import java.util.Objects;
public class Pressure {
private double value;
private double seaLevelValue;
private double groundLevelValue;
public Pressure() {
}
public Pressure(double value) {
this.value = value;
}
public double getValue() {
return value;
}
public void setValue(double value) {
this.value = value;
}
public double getSeaLevelValue() {
return seaLevelValue;
}
public void setSeaLevelValue(double seaLevelValue) {
this.seaLevelValue = seaLevelValue;
}
public double getGroundLevelValue() {
return groundLevelValue;
}
public void setGroundLevelValue(double groundLevelValue) {
this.groundLevelValue = groundLevelValue;
}
public String getUnit() {
return "hPa";
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Pressure)) return false;
Pressure pressure = (Pressure) o;
return Double.compare(pressure.value, value) == 0 &&
Double.compare(pressure.seaLevelValue, seaLevelValue) == 0 &&
Double.compare(pressure.groundLevelValue, groundLevelValue) == 0;
}
@Override
public int hashCode() {
return Objects.hash(value, seaLevelValue, groundLevelValue);
}
@Override
public String toString() {
return "Pressure: " + value + ' ' + getUnit();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 Alexey Zinchenko
* Copyright (c) 2019 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
@@ -22,26 +22,58 @@
package com.github.prominence.openweathermap.api.model;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import java.util.Objects;
@EqualsAndHashCode
public class Rain {
@JSONField(name = "3h")
// Rain volume for the last 3 hours
@Getter
@Setter
private byte rainVolumeLast3Hrs;
private double oneHourRainLevel;
private double threeHourRainLevel;
public Rain() {
}
public Rain(double oneHourRainLevel, double threeHourRainLevel) {
this.oneHourRainLevel = oneHourRainLevel;
this.threeHourRainLevel = threeHourRainLevel;
}
public double getOneHourRainLevel() {
return oneHourRainLevel;
}
public void setOneHourRainLevel(double oneHourRainLevel) {
this.oneHourRainLevel = oneHourRainLevel;
}
public double getThreeHourRainLevel() {
return threeHourRainLevel;
}
public void setThreeHourRainLevel(double threeHourRainLevel) {
this.threeHourRainLevel = threeHourRainLevel;
}
public String getUnit() {
return "mm";
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Rain)) return false;
Rain rain = (Rain) o;
return Double.compare(rain.oneHourRainLevel, oneHourRainLevel) == 0 &&
Double.compare(rain.threeHourRainLevel, threeHourRainLevel) == 0;
}
@Override
public int hashCode() {
return Objects.hash(oneHourRainLevel, threeHourRainLevel);
}
@Override
public String toString() {
return "Rain(last 3 hrs): " + rainVolumeLast3Hrs + ' ' + getUnit();
return "1 last hour rain level: " + oneHourRainLevel + + ' ' + getUnit() +
", 3 last hours rain level: " + threeHourRainLevel + ' ' + getUnit();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 Alexey Zinchenko
* Copyright (c) 2019 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
@@ -22,26 +22,59 @@
package com.github.prominence.openweathermap.api.model;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import java.util.Objects;
@EqualsAndHashCode
public class Snow {
@JSONField(name = "all")
// Snow volume for the last 3 hours
@Getter
@Setter
private byte snowVolumeLast3Hrs;
private double oneHourSnowLevel;
private double threeHourSnowLevel;
public Snow() {
}
public Snow(double oneHourSnowLevel, double threeHourSnowLevel) {
this.oneHourSnowLevel = oneHourSnowLevel;
this.threeHourSnowLevel = threeHourSnowLevel;
}
public double getOneHourSnowLevel() {
return oneHourSnowLevel;
}
public void setOneHourSnowLevel(double oneHourSnowLevel) {
this.oneHourSnowLevel = oneHourSnowLevel;
}
public double getThreeHourSnowLevel() {
return threeHourSnowLevel;
}
public void setThreeHourSnowLevel(double threeHourSnowLevel) {
this.threeHourSnowLevel = threeHourSnowLevel;
}
public String getUnit() {
return "mm";
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Snow)) return false;
Snow snow = (Snow) o;
return Double.compare(snow.oneHourSnowLevel, oneHourSnowLevel) == 0 &&
Double.compare(snow.threeHourSnowLevel, threeHourSnowLevel) == 0;
}
@Override
public int hashCode() {
return Objects.hash(oneHourSnowLevel, threeHourSnowLevel);
}
@Override
public String toString() {
return "Snow(last 3 hrs): " + snowVolumeLast3Hrs + ' ' + getUnit();
return "1 last hour snow level: " + oneHourSnowLevel + ' ' + getUnit() +
", 3 last hours snow level: " + threeHourSnowLevel + ' ' + getUnit();
}
}
@@ -0,0 +1,88 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api.model;
import java.util.Objects;
public class Temperature {
private double value;
private double maxTemperature;
private double minTemperature;
private String unit;
public double getValue() {
return value;
}
public void setValue(double value) {
this.value = value;
}
public double getMaxTemperature() {
return maxTemperature;
}
public void setMaxTemperature(double maxTemperature) {
this.maxTemperature = maxTemperature;
}
public double getMinTemperature() {
return minTemperature;
}
public void setMinTemperature(double minTemperature) {
this.minTemperature = minTemperature;
}
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Temperature)) return false;
Temperature that = (Temperature) o;
return Double.compare(that.value, value) == 0 &&
Double.compare(that.maxTemperature, maxTemperature) == 0 &&
Double.compare(that.minTemperature, minTemperature) == 0 &&
Objects.equals(unit, that.unit);
}
@Override
public int hashCode() {
return Objects.hash(value, maxTemperature, minTemperature, unit);
}
@Override
public String toString() {
return "Temperature: " + value + ' ' + unit +
", Maximum value: " + maxTemperature + ' ' + unit +
", Minimum value: " + minTemperature + ' ' + unit;
}
}
@@ -0,0 +1,183 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api.model;
import java.time.LocalDateTime;
import java.util.Objects;
public class Weather {
private String weatherState;
private String weatherDescription;
private String weatherIconUrl;
private LocalDateTime requestedOn;
private Temperature temperature;
private Pressure pressure;
private Humidity humidity;
private Wind wind;
private Rain rain;
private Snow snow;
private Clouds clouds;
private Location location;
public String getWeatherState() {
return weatherState;
}
public void setWeatherState(String weatherState) {
this.weatherState = weatherState;
}
public String getWeatherDescription() {
return weatherDescription;
}
public void setWeatherDescription(String weatherDescription) {
this.weatherDescription = weatherDescription;
}
public String getWeatherIconUrl() {
return weatherIconUrl;
}
public void setWeatherIconUrl(String weatherIconUrl) {
this.weatherIconUrl = weatherIconUrl;
}
public LocalDateTime getRequestedOn() {
return requestedOn;
}
public void setRequestedOn(LocalDateTime requestedOn) {
this.requestedOn = requestedOn;
}
public Temperature getTemperature() {
return temperature;
}
public void setTemperature(Temperature temperature) {
this.temperature = temperature;
}
public Pressure getPressure() {
return pressure;
}
public void setPressure(Pressure pressure) {
this.pressure = pressure;
}
public Humidity getHumidity() {
return humidity;
}
public void setHumidity(Humidity humidity) {
this.humidity = humidity;
}
public Wind getWind() {
return wind;
}
public void setWind(Wind wind) {
this.wind = wind;
}
public Rain getRain() {
return rain;
}
public void setRain(Rain rain) {
this.rain = rain;
}
public Snow getSnow() {
return snow;
}
public void setSnow(Snow snow) {
this.snow = snow;
}
public Clouds getClouds() {
return clouds;
}
public void setClouds(Clouds clouds) {
this.clouds = clouds;
}
public Location getLocation() {
return location;
}
public void setLocation(Location location) {
this.location = location;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Weather)) return false;
Weather weather = (Weather) o;
return Objects.equals(weatherState, weather.weatherState) &&
Objects.equals(weatherDescription, weather.weatherDescription) &&
Objects.equals(weatherIconUrl, weather.weatherIconUrl) &&
Objects.equals(requestedOn, weather.requestedOn) &&
Objects.equals(temperature, weather.temperature) &&
Objects.equals(pressure, weather.pressure) &&
Objects.equals(humidity, weather.humidity) &&
Objects.equals(wind, weather.wind) &&
Objects.equals(rain, weather.rain) &&
Objects.equals(snow, weather.snow) &&
Objects.equals(clouds, weather.clouds) &&
Objects.equals(location, weather.location);
}
@Override
public int hashCode() {
return Objects.hash(weatherState, weatherDescription, weatherIconUrl, requestedOn, temperature, pressure, humidity, wind, rain, snow, clouds, location);
}
@Override
public String toString() {
final String countryCode = location.getCountryCode();
String resultString = "Location: " +
location.getName() + (countryCode != null ? ('(' + countryCode + ")") : "") +
", Weather: " + weatherDescription +
", " + temperature.getValue() + ' ' + temperature.getUnit() +
", " + pressure.getValue() + ' ' + pressure.getUnit() +
", " + clouds.toString();
if (rain != null) {
resultString += (", Rain: " + rain.getOneHourRainLevel() + ' ' + rain.getUnit());
}
if (snow != null) {
resultString += (", Snow: " + snow.getOneHourSnowLevel() + ' ' + snow.getUnit());
}
return resultString;
}
}
@@ -1,74 +0,0 @@
/*
* 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 com.github.prominence.openweathermap.api.model;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import java.net.MalformedURLException;
import java.net.URL;
@EqualsAndHashCode
public class WeatherState {
@JSONField(name = "id")
// Weather condition id
@Getter
@Setter
long conditionId;
@JSONField(name = "main")
// Group of weather parameters (Rain, Snow, Extreme etc.)
@Getter
@Setter
String weatherGroup;
@JSONField(name = "description")
// Weather condition within the group
@Getter
@Setter
String description;
@JSONField(name = "icon")
// Weather icon id
@Getter
@Setter
String iconId;
public URL getWeatherIconUrl() {
URL iconUrl = null;
try {
iconUrl = new URL("http://openweathermap.org/img/w/" + iconId + ".png");
} catch (MalformedURLException e) {
e.printStackTrace();
}
return iconUrl;
}
@Override
public String toString() {
return "Weather: " + description;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 Alexey Zinchenko
* Copyright (c) 2019 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
@@ -22,32 +22,56 @@
package com.github.prominence.openweathermap.api.model;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import java.util.Objects;
@EqualsAndHashCode
public class Wind {
@JSONField(name = "speed")
// Wind speed. Unit Default: meter/sec, Metric: meter/sec, Imperial: miles/hour.
@Getter
@Setter
private float speed;
@Getter
@Setter
private double speed;
private double degrees;
private String unit;
@JSONField(name = "deg")
// Wind direction, degrees (meteorological)
@Getter
@Setter
private short degrees;
public double getSpeed() {
return speed;
}
public void setSpeed(double speed) {
this.speed = speed;
}
public double getDegrees() {
return degrees;
}
public void setDegrees(double degrees) {
this.degrees = degrees;
}
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Wind)) return false;
Wind wind = (Wind) o;
return Double.compare(wind.speed, speed) == 0 &&
Double.compare(wind.degrees, degrees) == 0 &&
Objects.equals(unit, wind.unit);
}
@Override
public int hashCode() {
return Objects.hash(speed, degrees, unit);
}
@Override
public String toString() {
return "Wind: " + speed + ' ' + unit + ", " + degrees + " degrees";
return "Wind speed: " + speed + " " + unit +
", degrees: " + degrees;
}
}
@@ -1,105 +0,0 @@
/*
* 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 com.github.prominence.openweathermap.api.model.response;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
@EqualsAndHashCode
public class AirPollution {
@Getter
@Setter
private String time;
@Getter
@Setter
@JSONField(name = "location")
private Coordinates coordinates;
@JSONField(name = "data")
@Getter
@Setter
private List<AirPollutionInfo> airPollutionInfo;
public Date getCalculationDate() {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
try {
return format.parse(time);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
@Override
public String toString() {
return "AirPollution[Date: " + getCalculationDate() + "; Coordinates: " + coordinates + "]" + "\n" + airPollutionInfo;
}
@EqualsAndHashCode
public static class AirPollutionInfo {
@Getter
@Setter
private float precision;
@Getter
@Setter
private short pressure;
@Getter
@Setter
private float value;
@Override
public String toString() {
return "Value: " + value;
}
}
@EqualsAndHashCode
public static class Coordinates {
@Getter
@Setter
private float latitude;
@Getter
@Setter
private float longitude;
@Override
public String toString() {
return "latitude=" + latitude + ", longitude=" + longitude;
}
}
}
@@ -1,256 +0,0 @@
/*
* 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 com.github.prominence.openweathermap.api.model.response;
import com.alibaba.fastjson.annotation.JSONField;
import com.github.prominence.openweathermap.api.model.CityInfo;
import com.github.prominence.openweathermap.api.model.Coordinates;
import com.github.prominence.openweathermap.api.model.OpenWeatherResponse;
import com.github.prominence.openweathermap.api.model.WeatherState;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import java.time.Instant;
import java.util.Date;
import java.util.List;
@EqualsAndHashCode
public class DailyForecast implements OpenWeatherResponse {
@JSONField(name = "city")
@Getter
@Setter
private CityInfo cityInfo;
// Internal parameter
@Getter
@Setter
private String cod;
// Internal parameter
@Getter
@Setter
private double message;
// Number of lines returned by this API call
@Getter
@Setter
private byte cnt;
@JSONField(name = "list")
@Getter
@Setter
private List<Forecast> forecasts;
public String getCityName() {
return cityInfo.getName();
}
public long getCityId() {
return cityInfo.getId();
}
public String getCountry() {
return cityInfo.getCountry();
}
public Coordinates getCoordinates() {
return cityInfo.getCoordinates();
}
public short getResponseCode() {
return Short.parseShort(cod);
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(cityInfo);
builder.append("\nForecasts: ");
forecasts.forEach(forecast -> {
builder.append("\n\t");
builder.append(forecast);
});
return builder.toString();
}
@EqualsAndHashCode
public static class Forecast {
@JSONField(name = "dt")
// Time of data calculation, unix, UTC
@Getter
@Setter
private long dataCalculationTime;
@JSONField(name = "temp")
@Getter
@Setter
private Temperature temperature;
@Getter
@Setter
private float pressure;
@Getter
@Setter
private byte humidity;
@JSONField(name = "weather")
@Getter
@Setter
private List<WeatherState> weatherStates;
@JSONField(name = "speed")
@Getter
@Setter
private float windSpeed;
@JSONField(name = "deg")
// Wind direction, degrees (meteorological)
@Getter
@Setter
private short windDegrees;
@Getter
@Setter
private String windUnit;
@JSONField(name = "clouds")
@Getter
@Setter
private byte cloudiness;
public String getPressureUnit() {
return "hPa";
}
public Date getDataCalculationDate() {
return Date.from(Instant.ofEpochSecond(dataCalculationTime));
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(temperature);
builder.append(", Pressure: ");
builder.append(pressure);
builder.append(' ');
builder.append(getPressureUnit());
builder.append("; Humidity: ");
builder.append(humidity);
builder.append("%; Weather: ");
if (weatherStates.size() == 1) {
builder.append(weatherStates.get(0));
} else {
builder.append(weatherStates);
}
builder.append("; Wind: ");
builder.append(windSpeed);
builder.append(' ');
builder.append(windUnit);
builder.append(", ");
builder.append(windDegrees);
builder.append(" degrees; Cloudiness: ");
builder.append(cloudiness);
builder.append('%');
return builder.toString();
}
@EqualsAndHashCode
public static class Temperature {
@JSONField(name = "day")
@Getter
@Setter
private float dayTemperature;
@JSONField(name = "min")
@Getter
@Setter
private float minTemperature;
@JSONField(name = "max")
@Getter
@Setter
private float maxTemperature;
@JSONField(name = "night")
@Getter
@Setter
private float nightTemperature;
@JSONField(name = "eve")
@Getter
@Setter
private float eveningTemperature;
@JSONField(name = "morn")
@Getter
@Setter
private float morningTemperature;
@Getter
@Setter
private char temperatureUnit;
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Temperature: [");
builder.append("Day temperature: ");
builder.append(dayTemperature);
builder.append(' ');
builder.append(getTemperatureUnit());
builder.append("; Night temperature: ");
builder.append(nightTemperature);
builder.append(' ');
builder.append(getTemperatureUnit());
builder.append("; Morning temperature: ");
builder.append(morningTemperature);
builder.append(' ');
builder.append(getTemperatureUnit());
builder.append("; Evening temperature: ");
builder.append(eveningTemperature);
builder.append(' ');
builder.append(getTemperatureUnit());
builder.append("; Minimum temperature: ");
builder.append(minTemperature);
builder.append(' ');
builder.append(getTemperatureUnit());
builder.append("; Maximum temperature: ");
builder.append(maxTemperature);
builder.append(' ');
builder.append(getTemperatureUnit());
builder.append("]");
return builder.toString();
}
}
}
}
@@ -1,318 +0,0 @@
/*
* 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 com.github.prominence.openweathermap.api.model.response;
import com.alibaba.fastjson.annotation.JSONField;
import com.github.prominence.openweathermap.api.model.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
@EqualsAndHashCode
public class HourlyForecast implements OpenWeatherResponse {
@JSONField(name = "cod")
@Getter
@Setter
private short responseCode;
@Getter
@Setter
private double message;
// Number of lines returned by this API call
@Getter
@Setter
private short cnt;
@JSONField(name = "list")
@Getter
@Setter
private List<Forecast> forecasts;
@JSONField(name = "city")
@Getter
@Setter
private CityInfo cityInfo;
public String getCityName() {
return cityInfo.getName();
}
public long getCityId() {
return cityInfo.getId();
}
public String getCountry() {
return cityInfo.getCountry();
}
public Coordinates getCoordinates() {
return cityInfo.getCoordinates();
}
public float getAverageTemperature() {
return (float)forecasts.stream().mapToDouble(forecast -> forecast.weatherInfo.temperature).average().orElse(0f);
}
public float getMinimumTemperature() {
return (float)forecasts.stream().mapToDouble(forecast -> forecast.weatherInfo.temperature).min().orElse(0f);
}
public float getMaximumTemperature() {
return (float)forecasts.stream().mapToDouble(forecast -> forecast.weatherInfo.temperature).max().orElse(0f);
}
public Forecast getByMinimumTemperature() {
return forecasts.stream().min(Comparator.comparing(forecast -> forecast.weatherInfo.minimumTemperature)).orElse(null);
}
public Forecast getByMaximumTemperature() {
return forecasts.stream().max(Comparator.comparing(forecast -> forecast.weatherInfo.maximumTemperature)).orElse(null);
}
public float getAveragePressure() {
return (float)forecasts.stream().mapToDouble(forecast -> forecast.weatherInfo.pressure).average().orElse(0f);
}
public float getMinimumPressure() {
return (float)forecasts.stream().mapToDouble(forecast -> forecast.weatherInfo.pressure).min().orElse(0f);
}
public float getMaximumPressure() {
return (float)forecasts.stream().mapToDouble(forecast -> forecast.weatherInfo.pressure).max().orElse(0f);
}
public Forecast getByMinimumPressure() {
return forecasts.stream().min(Comparator.comparing(forecast -> forecast.weatherInfo.pressure)).orElse(null);
}
public Forecast getByMaximumPressure() {
return forecasts.stream().max(Comparator.comparing(forecast -> forecast.weatherInfo.pressure)).orElse(null);
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(cityInfo);
builder.append("\nForecasts: ");
forecasts.forEach(forecast -> {
builder.append("\n\t");
builder.append(forecast);
});
return builder.toString();
}
@EqualsAndHashCode
public static class Forecast {
@JSONField(name = "dt")
// Time of data calculation, unix, UTC
@Getter
@Setter
private long dataCalculationTime;
@JSONField(name = "main")
@Getter
@Setter
private WeatherInfo weatherInfo;
@JSONField(name = "weather")
@Getter
@Setter
private List<WeatherState> weatherStates;
@Getter
@Setter
private Clouds clouds;
@Getter
@Setter
private Wind wind;
@Getter
@Setter
private Snow snow;
@Getter
@Setter
private Rain rain;
@JSONField(name = "sys")
@Getter
@Setter
private ForecastSystemInfo systemInfo;
// Data/time of calculation, UTC
@Getter
@Setter
private String dt_txt;
public Date getDataCalculationDate() {
return new Date(dataCalculationTime * 1000);
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Time: ");
builder.append(new Date(dataCalculationTime * 1000));
builder.append("; ");
if (weatherStates.size() == 1) {
builder.append(weatherStates.get(0));
} else {
builder.append(weatherStates);
}
builder.append("; ");
builder.append(weatherInfo);
if (clouds != null) {
builder.append("; ");
builder.append(clouds);
}
if (wind != null) {
builder.append("; ");
builder.append(wind);
}
if (snow != null) {
builder.append("; ");
builder.append(snow);
}
if (rain != null) {
builder.append("; ");
builder.append(rain);
}
return builder.toString();
}
@Data
public static class ForecastSystemInfo {
private String pod;
}
@EqualsAndHashCode
public static class WeatherInfo {
@JSONField(name = "temp")
// Temperature. Unit Default: Kelvin, Metric: Celsius, Imperial: Fahrenheit.
@Getter
@Setter
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.
@Getter
@Setter
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.
@Getter
@Setter
private float maximumTemperature;
// Atmospheric pressure on the sea level by default, hPa
@Getter
@Setter
private float pressure;
@JSONField(name = "sea_level")
// Atmospheric pressure on the sea level, hPa
@Getter
@Setter
private float seaLevelPressure;
@JSONField(name = "grnd_level")
// Atmospheric pressure on the ground level, hPa
@Getter
@Setter
private float groundLevelPressure;
// Humidity, %
@Getter
@Setter
private byte humidity;
@JSONField(name = "temp_kf")
// Internal parameter
@Getter
@Setter
private float temperatureCoefficient;
@Getter
@Setter
private char temperatureUnit;
public String getPressureUnit() {
return "hPa";
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Temperature: ");
builder.append(temperature);
builder.append(' ');
builder.append(temperatureUnit);
builder.append("; Minimum temperature: ");
builder.append(minimumTemperature);
builder.append(' ');
builder.append(temperatureUnit);
builder.append("; Maximum temperature: ");
builder.append(maximumTemperature);
builder.append(' ');
builder.append(temperatureUnit);
builder.append("; Pressure: ");
builder.append(pressure);
builder.append(' ');
builder.append(getPressureUnit());
if (seaLevelPressure > 0) {
builder.append("; Sea-level pressure: ");
builder.append(seaLevelPressure);
builder.append(' ');
builder.append(getPressureUnit());
}
if (groundLevelPressure > 0) {
builder.append("; Ground-level pressure: ");
builder.append(groundLevelPressure);
builder.append(' ');
builder.append(getPressureUnit());
}
builder.append("; Humidity: ");
builder.append(humidity);
builder.append('%');
return builder.toString();
}
}
}
}
@@ -1,332 +0,0 @@
/*
* 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 com.github.prominence.openweathermap.api.model.response;
import com.alibaba.fastjson.annotation.JSONField;
import com.github.prominence.openweathermap.api.model.*;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
import java.util.List;
@EqualsAndHashCode
public class Weather implements OpenWeatherResponse {
@JSONField(name = "id")
@Getter
@Setter
private long cityId;
@JSONField(name = "name")
@Getter
@Setter
private String cityName;
@JSONField(name = "coord")
@Getter
@Setter
private Coordinates coordinates;
@JSONField(name = "weather")
@Getter
@Setter
private List<WeatherState> weatherStates;
@Getter
@Setter
private String base;
@JSONField(name = "main")
@Getter
@Setter
private WeatherInfo weatherInfo;
@Getter
@Setter
private Wind wind;
@Getter
@Setter
private Clouds clouds;
@Getter
@Setter
private Rain rain;
@Getter
@Setter
private Snow snow;
@JSONField(name = "dt")
@Getter
@Setter
private long dataCalculationTime;
@JSONField(name = "sys")
@Getter
@Setter
private WeatherSystemInfo weatherSystemInfo;
@JSONField(name = "cod")
@Getter
@Setter
private short responseCode;
public String getCountry() {
return weatherSystemInfo.country;
}
public String getWeatherDescription() {
if (weatherStates != null && weatherStates.size() > 0) {
return weatherStates.get(0).getDescription();
}
return null;
}
public Date getDataCalculationDate() {
return new Date(dataCalculationTime * 1000);
}
public float getTemperature() {
return weatherInfo.temperature;
}
public char getTemperatureUnit() {
return weatherInfo.temperatureUnit;
}
public short getPressure() {
return weatherInfo.pressure;
}
public String getPressureUnit() {
return weatherInfo.getPressureUnit();
}
public byte getHumidityPercentage() {
return weatherInfo.humidity;
}
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("City: ");
stringBuilder.append(cityName);
stringBuilder.append('(');
stringBuilder.append(cityId);
stringBuilder.append("); Coordinates: ");
stringBuilder.append(coordinates);
stringBuilder.append('\n');
stringBuilder.append(weatherSystemInfo);
stringBuilder.append('\n');
if (weatherStates.size() == 1) {
stringBuilder.append(weatherStates.get(0));
} else {
stringBuilder.append(weatherStates);
}
stringBuilder.append('\n');
stringBuilder.append(weatherInfo);
stringBuilder.append('\n');
stringBuilder.append(wind);
stringBuilder.append('\n');
stringBuilder.append(clouds);
stringBuilder.append('\n');
if (rain != null) {
stringBuilder.append(rain);
stringBuilder.append('\n');
}
if (snow != null) {
stringBuilder.append(snow);
stringBuilder.append('\n');
}
stringBuilder.append("Data calculation time: ");
stringBuilder.append(getDataCalculationDate());
return stringBuilder.toString();
}
@EqualsAndHashCode
public static class WeatherInfo {
@JSONField(name = "temp")
// Temperature. Unit Default: Kelvin, Metric: Celsius, Imperial: Fahrenheit.
@Getter
@Setter
private float temperature;
@JSONField(name = "pressure")
// Atmospheric pressure (on the sea level, if there is no sea_level or grnd_level data), hPa
@Getter
@Setter
private short pressure;
@JSONField(name = "humidity")
// Humidity, %
@Getter
@Setter
private byte humidity;
@JSONField(name = "temp_min")
// Minimum temperature at the moment. This is deviation from current temp that is possible for large cities
// and megalopolises geographically expanded (use these parameter optionally). Unit Default: Kelvin, Metric: Celsius, Imperial: Fahrenheit.
@Getter
@Setter
private float minimumTemperature;
@JSONField(name = "temp_max")
// Maximum temperature at the moment. This is deviation from current temp that is possible for large cities
// and megalopolises geographically expanded (use these parameter optionally). Unit Default: Kelvin, Metric: Celsius, Imperial: Fahrenheit.
@Getter
@Setter
private float maximumTemperature;
@JSONField(name = "sea_level")
// Atmospheric pressure on the sea level, hPa
@Getter
@Setter
private short seaLevelPressure;
@JSONField(name = "grnd_level")
// Atmospheric pressure on the ground level, hPa
@Getter
@Setter
private short groundLevelPressure;
@Getter
@Setter
private char temperatureUnit;
public String getPressureUnit() {
return "hPa";
}
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("Temperature: ");
stringBuilder.append(temperature);
stringBuilder.append(' ');
stringBuilder.append(temperatureUnit);
stringBuilder.append("; Minimum temparature: ");
stringBuilder.append(minimumTemperature);
stringBuilder.append(' ');
stringBuilder.append(temperatureUnit);
stringBuilder.append("; Maximum temperature: ");
stringBuilder.append(maximumTemperature);
stringBuilder.append(' ');
stringBuilder.append(temperatureUnit);
stringBuilder.append('\n');
stringBuilder.append("Humidity: ");
stringBuilder.append(humidity);
stringBuilder.append("%");
stringBuilder.append('\n');
stringBuilder.append("Pressure: ");
stringBuilder.append(pressure);
stringBuilder.append(' ');
stringBuilder.append(getPressureUnit());
if (seaLevelPressure > 0) {
stringBuilder.append("; Sea-level pressure: ");
stringBuilder.append(seaLevelPressure);
stringBuilder.append(' ');
stringBuilder.append(getPressureUnit());
}
if (groundLevelPressure > 0) {
stringBuilder.append("; Ground-level pressure: ");
stringBuilder.append(groundLevelPressure);
stringBuilder.append(' ');
stringBuilder.append(getPressureUnit());
}
return stringBuilder.toString();
}
}
public static class WeatherSystemInfo {
@JSONField(name = "type")
// Internal parameter
@Getter
@Setter
private short type;
@JSONField(name = "id")
// Internal parameter
@Getter
@Setter
private long id;
@JSONField(name = "message")
// Internal parameter
@Getter
@Setter
private double message;
@JSONField(name = "country")
// Country code (GB, JP etc.)
@Getter
@Setter
private String country;
@JSONField(name = "sunrise")
// Sunrise time, unix, UTC
@Getter
@Setter
private long sunriseTimestamp;
@JSONField(name = "sunset")
// Sunset time, unix, UTC
@Getter
@Setter
private long sunsetTimestamp;
public Date getSunriseDate() {
return new Date(sunriseTimestamp * 1000);
}
public Date getSunsetDate() {
return new Date(sunsetTimestamp * 1000);
}
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
if (country != null) {
stringBuilder.append("Country: ");
stringBuilder.append(country);
stringBuilder.append('\n');
}
if (sunriseTimestamp > 0) {
stringBuilder.append("Sunrise: ");
stringBuilder.append(getSunriseDate());
stringBuilder.append('\n');
}
if (sunsetTimestamp > 0) {
stringBuilder.append("Sunset: ");
stringBuilder.append(getSunsetDate());
}
return stringBuilder.toString();
}
}
}
@@ -1,58 +0,0 @@
/*
* 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 com.github.prominence.openweathermap.api.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public final class JSONUtils {
private JSONUtils() {}
public static Object parseJSON(InputStream inputStream, Class clazz) throws IOException {
return JSON.parseObject(getStringFromStream(inputStream), clazz);
}
public static Object parseJSON(InputStream inputStream, TypeReference typeReference) throws IOException {
return JSON.parseObject(getStringFromStream(inputStream), typeReference);
}
private static String getStringFromStream(InputStream inputStream) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
reader.close();
return result.toString();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 Alexey Zinchenko
* Copyright (c) 2019 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
@@ -25,9 +25,12 @@ package com.github.prominence.openweathermap.api.utils;
import com.github.prominence.openweathermap.api.exception.DataNotFoundException;
import com.github.prominence.openweathermap.api.exception.InvalidAuthTokenException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public final class RequestUtils {
@@ -35,7 +38,7 @@ public final class RequestUtils {
private RequestUtils() {
}
public static InputStream executeGetRequest(URL requestUrl) {
private static InputStream executeGetRequest(URL requestUrl) {
InputStream resultStream = null;
try {
@@ -59,4 +62,32 @@ public final class RequestUtils {
return resultStream;
}
public static InputStream executeGetRequest(String requestUrl) {
try {
return executeGetRequest(new URL(requestUrl));
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
}
}
public static String getRawResponse(String url) {
return getRawResponse(executeGetRequest(url));
}
private static String getRawResponse(InputStream inputStream) {
StringBuilder result = new StringBuilder();
try(BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
} catch (Exception ex) {
ex.printStackTrace();
}
return result.toString();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 Alexey Zinchenko
* Copyright (c) 2019 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
@@ -18,12 +18,11 @@
* 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 com.github.prominence.openweathermap.api.utils;
import com.github.prominence.openweathermap.api.constants.TimeFrame;
import com.github.prominence.openweathermap.api.enums.TimeFrame;
import java.text.SimpleDateFormat;
import java.util.Date;
@@ -22,20 +22,20 @@
package com.github.prominence.openweathermap.api.test;
import com.github.prominence.openweathermap.api.OpenWeatherMapManager;
import com.github.prominence.openweathermap.api.impl.OpenWeatherMapClient;
import org.junit.BeforeClass;
public class ApiTest {
private static OpenWeatherMapManager manager;
private static OpenWeatherMapClient manager;
@BeforeClass
public static void retrieveApiKey() {
String apiKey = System.getenv("OPENWEATHER_API_KEY");
manager = new OpenWeatherMapManager(apiKey);
manager = new OpenWeatherMapClient(apiKey);
}
protected static OpenWeatherMapManager getManager() {
protected static OpenWeatherMapClient getClient() {
return manager;
}
}
@@ -0,0 +1,332 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api.test;
import com.github.prominence.openweathermap.api.enums.Accuracy;
import com.github.prominence.openweathermap.api.enums.Language;
import com.github.prominence.openweathermap.api.enums.Unit;
import com.github.prominence.openweathermap.api.model.Coordinate;
import com.github.prominence.openweathermap.api.model.CoordinateRectangle;
import com.github.prominence.openweathermap.api.model.Weather;
import org.junit.Test;
import java.util.List;
import java.util.concurrent.CompletableFuture;
public class CurrentWeatherIntegrationTest extends ApiTest {
@Test
public void whenGetSingleCurrentWeatherByCoordinateRequestAsJava_thenReturnNotNull() {
final Weather weather = getClient()
.currentWeather()
.single()
.byCoordinate(new Coordinate(5, 5))
.accuracy(Accuracy.ACCURATE)
.language(Language.ROMANIAN)
.unit(Unit.METRIC_SYSTEM)
.retrieve()
.asJava();
assert weather != null;
System.out.println(weather);
}
@Test
public void whenGetSingleCurrentWeatherByCityIdRequestAsJava_thenReturnNotNull() {
final Weather weather = getClient()
.currentWeather()
.single()
.byCityId(350001514)
.language(Language.GERMAN)
.unit(Unit.IMPERIAL_SYSTEM)
.retrieve()
.asJava();
assert weather != null;
System.out.println(weather);
}
@Test
public void whenGetSingleCurrentWeatherByCityNameRequestAsJava_thenReturnNotNull() {
final Weather weather = getClient()
.currentWeather()
.single()
.byCityName("Minsk")
.language(Language.RUSSIAN)
.unit(Unit.METRIC_SYSTEM)
.retrieve()
.asJava();
assert weather != null;
System.out.println(weather);
}
@Test
public void whenGetSingleCurrentWeatherByCityNameAndCountryCodeRequestAsJava_thenReturnNotNull() {
final Weather weather = getClient()
.currentWeather()
.single()
.byCityName("Moscow", "ru")
.language(Language.RUSSIAN)
.unit(Unit.METRIC_SYSTEM)
.retrieve()
.asJava();
assert weather != null;
System.out.println(weather);
}
@Test
public void whenGetSingleCurrentWeatherByZipCodeAndCountryRequestAsJava_thenReturnNotNull() {
final Weather weather = getClient()
.currentWeather()
.single()
.byZipCodeAndCountry("220015", "by")
.language(Language.RUSSIAN)
.unit(Unit.METRIC_SYSTEM)
.retrieve()
.asJava();
assert weather != null;
System.out.println(weather);
}
@Test
public void whenGetAnySingleCurrentRequestWeatherAsJson_thenReturnNotNull() {
final String weatherJson = getClient()
.currentWeather()
.single()
.byZipCodeAndCountry("220015", "by")
.language(Language.RUSSIAN)
.unit(Unit.METRIC_SYSTEM)
.retrieve()
.asJSON();
assert weatherJson != null;
System.out.println(weatherJson);
}
@Test
public void whenGetAnySingleCurrentRequestWeatherAsXml_thenReturnNotNull() {
final String weatherXml = getClient()
.currentWeather()
.single()
.byZipCodeAndCountry("220015", "by")
.language(Language.RUSSIAN)
.unit(Unit.METRIC_SYSTEM)
.retrieve()
.asXML();
assert weatherXml != null;
System.out.println(weatherXml);
}
@Test
public void whenGetAnySingleCurrentWeatherRequestAsHtml_thenReturnNotNull() {
final String weatherHtml = getClient()
.currentWeather()
.single()
.byZipCodeAndCountry("220015", "by")
.language(Language.RUSSIAN)
.unit(Unit.METRIC_SYSTEM)
.retrieve()
.asHTML();
assert weatherHtml != null;
System.out.println(weatherHtml);
}
@Test
public void whenGetAnySingleCurrentWeatherAsyncRequestAsXml_thenReturnNotNull() {
final CompletableFuture<String> weatherXmlFuture = getClient()
.currentWeather()
.single()
.byZipCodeAndCountry("220015", "by")
.language(Language.RUSSIAN)
.unit(Unit.METRIC_SYSTEM)
.retrieveAsync()
.asXML();
assert weatherXmlFuture != null;
weatherXmlFuture.thenAccept(System.out::println);
}
@Test
public void whenGetAnySingleCurrentWeatherAsyncRequestAsJava_thenReturnNotNull() {
final CompletableFuture<Weather> weatherFuture = getClient()
.currentWeather()
.single()
.byZipCodeAndCountry("220015", "by")
.language(Language.RUSSIAN)
.unit(Unit.METRIC_SYSTEM)
.retrieveAsync()
.asJava();
assert weatherFuture != null;
weatherFuture.thenAccept(System.out::println);
}
@Test
public void whenGetMultipleCurrentWeatherByCoordinateRequestAsJava_thenReturnNotNull() {
final List<Weather> weatherList = getClient()
.currentWeather()
.multiple()
.byRectangle(new CoordinateRectangle(12, 32, 15, 37), 10)
.accuracy(Accuracy.ACCURATE)
.language(Language.ROMANIAN)
.unit(Unit.METRIC_SYSTEM)
.retrieve()
.asJava();
assert weatherList != null;
assert weatherList.size() > 0;
System.out.println(weatherList);
}
@Test
public void whenGetMultipleCurrentWeatherByCoordinateAndServerClusteringRequestAsJava_thenReturnNotNull() {
final List<Weather> weatherList = getClient()
.currentWeather()
.multiple()
.byRectangle(new CoordinateRectangle(12, 32, 15, 37), 10, true)
.accuracy(Accuracy.ACCURATE)
.language(Language.ROMANIAN)
.unit(Unit.METRIC_SYSTEM)
.retrieve()
.asJava();
assert weatherList != null;
assert weatherList.size() > 0;
System.out.println(weatherList);
}
@Test
public void whenGetMultipleCurrentWeatherByCitiesInCycleRequestAsJava_thenReturnNotNull() {
final List<Weather> weatherList = getClient()
.currentWeather()
.multiple()
.byCitiesInCycle(new Coordinate(55.5, 37.5), 10)
.language(Language.GERMAN)
.unit(Unit.IMPERIAL_SYSTEM)
.retrieve()
.asJava();
assert weatherList != null;
assert weatherList.size() > 0;
System.out.println(weatherList);
}
@Test
public void whenGetMultipleCurrentWeatherByCitiesInCycleAndServerClusteringRequestAsJava_thenReturnNotNull() {
final List<Weather> weatherList = getClient()
.currentWeather()
.multiple()
.byCitiesInCycle(new Coordinate(55.5, 37.5), 10, true)
.language(Language.GERMAN)
.unit(Unit.IMPERIAL_SYSTEM)
.retrieve()
.asJava();
assert weatherList != null;
assert weatherList.size() > 0;
System.out.println(weatherList);
}
@Test
public void whenGetMultipleCurrentWeatherByCitiesInCycleRequestAsJson_thenReturnNotNull() {
final String weather = getClient()
.currentWeather()
.multiple()
.byCitiesInCycle(new Coordinate(55.5, 37.5), 10)
.language(Language.GERMAN)
.unit(Unit.IMPERIAL_SYSTEM)
.retrieve()
.asJSON();
assert weather != null;
System.out.println(weather);
}
@Test
public void whenGetMultipleCurrentWeatherByCitiesInCycleRequestAsXml_thenReturnNotNull() {
final String weather = getClient()
.currentWeather()
.multiple()
.byCitiesInCycle(new Coordinate(55.5, 37.5), 10)
.language(Language.GERMAN)
.unit(Unit.IMPERIAL_SYSTEM)
.retrieve()
.asXML();
assert weather != null;
System.out.println(weather);
}
@Test
public void whenGetMultipleCurrentWeatherByCitiesInCycleRequestAsHtml_thenReturnNotNull() {
final String weather = getClient()
.currentWeather()
.multiple()
.byCitiesInCycle(new Coordinate(55.5, 37.5), 10)
.language(Language.GERMAN)
.unit(Unit.IMPERIAL_SYSTEM)
.retrieve()
.asHTML();
assert weather != null;
System.out.println(weather);
}
@Test
public void whenGetMultipleCurrentWeatherByCoordinateAndServerClusteringAsyncRequestAsJava_thenReturnNotNull() {
final CompletableFuture<List<Weather>> weatherListFuture = getClient()
.currentWeather()
.multiple()
.byCitiesInCycle(new Coordinate(55.5, 37.5), 10, true)
.language(Language.GERMAN)
.unit(Unit.IMPERIAL_SYSTEM)
.retrieveAsync()
.asJava();
assert weatherListFuture != null;
weatherListFuture.thenAccept(result -> {
assert result.size() > 0;
System.out.println(result);
});
}
@Test
public void whenGetMultipleCurrentWeatherByCoordinateAndServerClusteringAsyncRequestAsXml_thenReturnNotNull() {
final CompletableFuture<String> weatherFuture = getClient()
.currentWeather()
.multiple()
.byCitiesInCycle(new Coordinate(55.5, 37.5), 10, true)
.language(Language.GERMAN)
.unit(Unit.IMPERIAL_SYSTEM)
.retrieveAsync()
.asXML();
assert weatherFuture != null;
weatherFuture.thenAccept(System.out::println);
}
}
@@ -1,101 +0,0 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api.test;
import com.github.prominence.openweathermap.api.HourlyForecastRequester;
import com.github.prominence.openweathermap.api.exception.DataNotFoundException;
import com.github.prominence.openweathermap.api.model.Coordinates;
import org.junit.BeforeClass;
import org.junit.Test;
public class HourlyForecastRequesterIntegrationTest extends ApiTest {
private static HourlyForecastRequester hourlyForecastRequester;
@BeforeClass
public static void setup() {
hourlyForecastRequester = getManager().getHourlyForecastRequester();
}
@Test
public void whenRequestForecastForMinskByCity() {
assert hourlyForecastRequester.getByCityName("Minsk") != null;
}
@Test(expected = DataNotFoundException.class)
public void whenRequestForecastByWrongCity_thenThrowAnException() {
hourlyForecastRequester.getByCityId("IncorrectCity");
}
@Test
public void whenRequestForecastForMinskById_thenReturnNotNull() {
assert hourlyForecastRequester.getByCityId("625144") != null;
}
@Test(expected = DataNotFoundException.class)
public void whenRequestForecastByWrongId_thenThrowAnException() {
hourlyForecastRequester.getByCityId("IncorrectId");
}
@Test
public void whenRequestForecastByCoordinates_thenReturnNotNull() {
// given
float latitude = 53.9f;
float longitude = 27.56667f;
Coordinates coordinates = new Coordinates(latitude, longitude);
// expected
assert hourlyForecastRequester.getByCoordinates(coordinates) != null;
assert hourlyForecastRequester.getByCoordinates(latitude, longitude) != null;
}
@Test(expected = NullPointerException.class) // not good, will be reimplemented in further versions
public void whenRequestByNullCoordinates_thenThrowAnException() {
hourlyForecastRequester.getByCoordinates(null);
}
@Test(expected = DataNotFoundException.class)
public void whenRequestForecastByWrongCoordinates_thenThrowAnException() {
hourlyForecastRequester.getByCoordinates(91f, 180f);
}
@Test
public void whenRequestForecastByMaxCoordinates_thenReturnNotNull() {
assert hourlyForecastRequester.getByCoordinates(90f, 180f) != null;
}
@Test
public void whenRequestForecastByMinCoordinates_thenReturnNotNull() {
assert hourlyForecastRequester.getByCoordinates(-90f, -180f) != null;
}
@Test
public void whenRequestForecastByZipCode_thenReturnNotNull() {
assert hourlyForecastRequester.getByZIPCode("220015", "BY") != null;
}
@Test(expected = DataNotFoundException.class)
public void whenRequestForecastByWrongZipCode_thenThrowAnException() {
hourlyForecastRequester.getByZIPCode("wrongZipCode", "BY");
}
}
@@ -1,76 +0,0 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api.test;
import com.github.prominence.openweathermap.api.UltravioletIndexRequester;
import com.github.prominence.openweathermap.api.exception.DataNotFoundException;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.Date;
public class UltravioletIndexRequestedIntegrationTest extends ApiTest {
private static UltravioletIndexRequester minskUltravioletIndexRequester;
@BeforeClass
public static void setup() {
minskUltravioletIndexRequester = getManager().getUltravioletIndexRequester(53.9f, 27.56667f);
}
@Test
public void whenRequestUVI_thenReturnNotNull() {
assert minskUltravioletIndexRequester.getCurrentUVIndex() != null;
}
@Test
public void whenRequestUVIForecastFor5Days_thenReturnNotNull() {
assert minskUltravioletIndexRequester.getUVIndexForecast(5) != null;
}
@Test(expected = DataNotFoundException.class)
public void whenRequestUVIForecastForWrongAmountOfDays_thenThrowAnException() {
minskUltravioletIndexRequester.getUVIndexForecast(-2);
}
@Test(expected = DataNotFoundException.class)
public void whenRequestUVIForecastForLargeAmountOfDays_thenThrowAnException() {
assert minskUltravioletIndexRequester.getUVIndexForecast(10000) != null;
}
@Test // check it later
public void whenRequestUVIForPeriod_thenReturnNotNull() {
assert minskUltravioletIndexRequester.getUVIndexByPeriod(new Date(), new Date()) != null;
}
@Test(expected = NullPointerException.class) // not good, will be reimplemented in further versions
public void whenRequestUVIForNullPeriod_thenThrowAnException() {
minskUltravioletIndexRequester.getUVIndexByPeriod(null, null);
}
@Test(expected = NullPointerException.class) // not good, will be reimplemented in further versions
public void whenRequestUVIForNullCoordinates_thenThrowAnException() {
UltravioletIndexRequester requester = getManager().getUltravioletIndexRequester(null);
requester.getCurrentUVIndex();
}
}
@@ -1,101 +0,0 @@
/*
* Copyright (c) 2019 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 com.github.prominence.openweathermap.api.test;
import com.github.prominence.openweathermap.api.WeatherRequester;
import com.github.prominence.openweathermap.api.exception.DataNotFoundException;
import com.github.prominence.openweathermap.api.model.Coordinates;
import org.junit.BeforeClass;
import org.junit.Test;
public class WeatherRequestIntegrationTest extends ApiTest {
private static WeatherRequester weatherRequester;
@BeforeClass
public static void setup() {
weatherRequester = getManager().getWeatherRequester();
}
@Test
public void whenRequestWeatherForMinskByName_thenReturnNotNull() {
assert weatherRequester.getByCityName("Minsk") != null;
}
@Test(expected = DataNotFoundException.class)
public void whenRequestWeatherByWrongCity_thenThrowAnException() {
weatherRequester.getByCityId("IncorrectCity");
}
@Test
public void whenRequestWeatherForMinskById_thenReturnNotNull() {
assert weatherRequester.getByCityId("625144") != null;
}
@Test(expected = DataNotFoundException.class)
public void whenRequestWeatherByWrongId_thenThrowAnException() {
weatherRequester.getByCityId("IncorrectId");
}
@Test
public void whenRequestWeatherByCoordinates_thenReturnNotNull() {
// given
float latitude = 53.9f;
float longitude = 27.56667f;
Coordinates coordinates = new Coordinates(latitude, longitude);
// expected
assert weatherRequester.getByCoordinates(coordinates) != null;
assert weatherRequester.getByCoordinates(latitude, longitude) != null;
}
@Test(expected = NullPointerException.class) // not good, will be reimplemented in further versions
public void whenRequestByNullCoordinates_thenThrowAnException() {
weatherRequester.getByCoordinates(null);
}
@Test(expected = DataNotFoundException.class)
public void whenRequestWeatherByWrongCoordinates_thenThrowAnException() {
weatherRequester.getByCoordinates(91f, 180f);
}
@Test
public void whenRequestWeatherByMaxCoordinates_thenReturnNotNull() {
assert weatherRequester.getByCoordinates(90f, 180f) != null;
}
@Test
public void whenRequestWeatherByMinCoordinates_thenReturnNotNull() {
assert weatherRequester.getByCoordinates(-90f, -180f) != null;
}
@Test
public void whenRequestWeatherByZipCode_thenReturnNotNull() {
assert weatherRequester.getByZIPCode("220015", "BY") != null;
}
@Test(expected = DataNotFoundException.class)
public void whenRequestWeatherByWrongZipCode_thenThrowAnException() {
weatherRequester.getByZIPCode("wrongZipCode", "BY");
}
}