diff --git a/.gitignore b/.gitignore index 47bfbba..a4776fb 100644 --- a/.gitignore +++ b/.gitignore @@ -21,5 +21,4 @@ hs_err_pid* *.iml .idea/ -target/ -**/ApplicationTest.java \ No newline at end of file +target/ \ No newline at end of file diff --git a/LICENSE b/LICENSE index 709c923..8ed4b26 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -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 diff --git a/README.md b/README.md index 483dc3c..be11f99 100644 --- a/README.md +++ b/README.md @@ -21,12 +21,26 @@ Global changes in API and more functionality. ``` +New experimental version: +```xml + + com.github.prominence + openweathermap-api + 2.0-SNAPSHOT + +``` + ### Gradle coordinates: ```groovy compile('com.github.prominence:openweathermap-api:1.2') ``` +New experimental version: +```groovy +compile('com.github.prominence:openweathermap-api:2.0-SNAPSHOT') +``` + ### Documentation * [OpenWeatherMap Java API - 1.0](docs/Release_1.0.md) * [OpenWeatherMap Java API - 1.1](docs/Release_1.1.md) diff --git a/docs/SNAPSHOT.md b/docs/SNAPSHOT.md index cc033a4..ae3756c 100644 --- a/docs/SNAPSHOT.md +++ b/docs/SNAPSHOT.md @@ -1,335 +1,119 @@ ### Implemented features: * Current weather data -* 5 day / 3 hour forecast -* 16 day / daily forecast -* UV Index -* Air Pollution - ### Maven coordinates: ```xml com.github.prominence openweathermap-api - 1.1-SNAPSHOT + 2.0-SNAPSHOT ``` ### Gradle coordinates: ```groovy -compile('com.github.prominence:openweathermap-api:1.1-SNAPSHOT') +compile('com.github.prominence:openweathermap-api:2.0-SNAPSHOT') ``` ### How to use: Firstly, you need to create the instance of `OpenWeatherMapManager` class: ```java -OpenWeatherMapManager openWeatherManager = new OpenWeatherMapManager(API_TOKEN); +OpenWeatherMapClient openWeatherClient = new OpenWeatherMapClient(API_TOKEN); ``` where `API_TOKEN` is your token([you can get it here](https://home.openweathermap.org/api_keys)) as `String`. -Currently available methods: -* `getWeatherRequester()` -* `getHourlyForecastRequester()` -* `getDailyForecastRequester()` -* `getUltravioletIndexRequester()` - #### Current weather data -First step is retrieving `WeatherRequester` instance: +Current weather request chain structure: ```java -OpenWeatherMapManager openWeatherManager = new OpenWeatherMapManager(API_TOKEN); -WeatherRequester weatherRequester = openWeatherManager.getWeatherRequester(); +openWeatherClient + .currentWeather() + .() + . + . + ... + . + .() + .as(Java|JSON|XML|HTML)(); ``` -after you are able to set preferable options(via chain methods) and execute appropriate request: -``` -Weather weatherResponse = weatherRequester - .setLanguage(Language.ENGLISH) - .setUnitSystem(Unit.METRIC_SYSTEM) - .setAccuracy(Accuracy.ACCURATE) - .getByCityName("Minsk"); -``` -*Language*, *UnitSystem* and *Accuracy* settings will be described below. -Available requests: -* `getByCityId(String cityId)` -* `getByCityName(String cityName)` -* `getByCoordinates(double latitude, double longitude)` -* `getByCoordinates(Coordinates coordinates)` -* `getByZIPCode(String zipCode, String countryCode)` +Available methods for location selection for **single** result request: +* `byCityName(String cityName)` +* `byCityName(String cityName, String countryCode)` +* `byCityId(long cityId)` +* `byCoordinate(Coordinate coordinate)` +* `byZipCodeAndCountry(String zipCode, String countryCode)` + +Available methods for location selection for **multiple** result request: +* `byRectangle(CoordinateRectangle rectangle, int zoom)` +* `byRectangle(CoordinateRectangle rectangle, int zoom, boolean useServerClustering)` +* `byCitiesInCycle(Coordinate point, int citiesCount)` +* `byCitiesInCycle(Coordinate point, int citiesCount, boolean useServerClustering)` + +Single location request examples: +```java +final Weather weather = openWeatherClient + .currentWeather() + .single() + .byCoordinate(new Coordinate(5, 5)) + .accuracy(Accuracy.ACCURATE) + .language(Language.ROMANIAN) + .unit(Unit.METRIC_SYSTEM) + .retrieve() + .asJava(); + +final CompletableFuture weatherXmlFuture = openWeatherClient + .currentWeather() + .single() + .byZipCodeAndCountry("220015", "by") + .language(Language.RUSSIAN) + .unit(Unit.METRIC_SYSTEM) + .retrieveAsync() + .asXML(); +``` + +Multiple locations request examples: +```java +final String weatherListJson = openWeatherClient + .currentWeather() + .multiple() + .byRectangle(new CoordinateRectangle(12, 32, 15, 37), 10, true) + .accuracy(Accuracy.ACCURATE) + .language(Language.ROMANIAN) + .unit(Unit.METRIC_SYSTEM) + .retrieve() + .asJSON(); + +final CompletableFuture> weatherListFuture = openWeatherClient + .currentWeather() + .multiple() + .byCitiesInCycle(new Coordinate(55.5, 37.5), 10, true) + .unit(Unit.IMPERIAL_SYSTEM) + .retrieveAsync() + .asJava(); +``` `Weather`'s useful public methods(setters are not listed): -| Method | Description | -|---------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `getCityId()` | Returns city ID. Example: `625144` for Minsk. | -| `getCityName()` | Returns city name. Example: `Minsk`. | -| `getCoordinates()` | Returns `Coordinates` instance that contains *latitude* and *longitude* information. | -| `getWeatherStates()` | Returns list of `WeatherState` instances with the only `getDescription` useful method. | -| `getBase()` | Returns `String` with some internal information. Example: `cmc stations` - from official documentation. | -| `getWeatherInfo()` | Returns `Weather.WeatherInfo` instance that contains information about temperature, pressure and humidity. | -| `getWind()` | Returns `Wind` instance that contains information about speed and degree. | -| `getClouds()` | Returns `Clouds` instance that contains *cloudiness* percentage information. | -| `getRain()` | Returns `Rain` instance that contains information about rain volume for the last 3 hours. | -| `getSnow()` | Returns `Snow` instance that contains information about snow volume for the last 3 hours. | -| `getDataCalculationTime()`| Returns `long` value that represents data calculation timestamp. | -| `getWeatherSystemInfo()` | Returns `Weather.WeatherSystemInfo` instance that contains internal information. There is also an information about country, sunrise and sunset time. | -| `getResponseCode()` | Returns OpenWeatherMap response code. Internal information. | -| `getCountry()` | An alias for `getWeatherSystemInfo().getCountry()`. | -| `getWeatherDescription()` | An alias for `getWeatherStates.get(0).getDescription()`. | -| `getDataCalculationDate()`| Returns data calculation time in `Date` representation. | -| `getTemperature()` | An alias for `getWeatherInfo().getTemperature()`. | -| `getTemperatureUnit()` | An alias for `getWeatherInfo().getTemperatureUnit()`. | -| `getPressure()` | An alias for `getWeatherInfo().getPressure()`. | -| `getPressureUnit()` | An alias for `getWeatherInfo().getPressureUnit()`. | -| `getHumidityPercentage()` | An alias for `getWeatherInfo().getHumidity()`. | -| `toString()` | Returns pretty string for the whole available weather information. | +| Method | Description | +|---------------------------|-------------------------------------------------------------------------------------------------------------------------------------| +| `getWeatherState()` | Returns weather identifier. Example: `Clouds`, `Clear`. | +| `getWeatherDescription()` | Returns weather description. Example: `clear sky`. | +| `getWeatherIconUrl()` | Returns weather icon url. | +| `getRequestedOn()` | Returns `LocalDateTime` instance which represents date when request was made. | +| `getTemperature()` | Returns `Temperature` instance with temperature and max/min values. | +| `getPressure()` | Returns `Pressure` instance that contains information about pressure and(not always) pressure on ground/sea level. | +| `getHumidity()` | Returns `Humidity` instance that contains information about humidity. | +| `getWind()` | Returns `Wind` instance that contains *humidity* percentage information. | +| `getRain()` | Returns `Rain` instance that contains information about rain level for the last 1 and 3 hours. | +| `getSnow()` | Returns `Snow` instance that contains information about snow level for the last 1 and 3 hours. | +| `getClouds()` | Returns `Clouds` instance that contains *cloudiness* percentage information. | +| `getLocation()` | Returns `Location` instance that contains location information: coordinate, name and etc. | `toString()` output example: ``` -City: Minsk(625144). Coordinates: latitude=53.9, longitude=27.56 -Country: BY -Sunrise: Sun Jul 15 04:58:27 MSK 2018 -Sunset: Sun Jul 15 21:32:19 MSK 2018 -Weather: light intensity shower rain -Temperature: 17.0 ℃. Minimum temparature: 17.0 ℃. Maximum temperature: 17.0 ℃ -Humidity: 93% -Pressure: 1008 hPa -Wind: 2.0 meter/sec, 20 degrees -Cloudiness: 75% -Data calculation time: Mon Jul 16 00:00:00 MSK 2018 -``` - -#### 5 day / 3 hour forecast -First step is retrieving `HourlyForecastRequester` instance: -```java -OpenWeatherMapManager openWeatherManager = new OpenWeatherMapManager(API_TOKEN); -HourlyForecastRequester forecastRequester = openWeatherManager.getHourlyForecastRequester(); -``` -after you are able to set preferable options(via chain methods) and execute appropriate request: -``` -HourlyForecast forecastResponse = forecastRequester - .setLanguage(Language.ENGLISH) - .setUnitSystem(Unit.METRIC_SYSTEM) - .setAccuracy(Accuracy.ACCURATE) - .getByCityName("Pruzhany"); -``` -*Language*, *UnitSystem* and *Accuracy* settings will be described below. - -Available requests: -* `getByCityId(String cityId)` -* `getByCityName(String cityName)` -* `getByCoordinates(double latitude, double longitude)` -* `getByCoordinates(Coordinates coordinates)` -* `getByZIPCode(String zipCode, String countryCode)` - -`HourlyForecast`'s useful public methods(setters are not listed): - -| Method | Description | -|-----------------------------|--------------------------------------------------------------------------------------------| -| `getCityId()` | Returns city ID. Example: `625144` for Minsk. | -| `getCityName()` | Returns city name. Example: `Minsk`. | -| `getCoordinates()` | Returns `Coordinates` instance that contains *latitude* and *longitude* information. | -| `getCityInfo()` | Returns `CityInfo` instance that contains information about city. | -| `getResponseCode()` | Returns OpenWeatherMap response code. Internal information. | -| `getCountry()` | An alias for `getCityInfo().getCountry()`. | -| `getForecasts()` | Returns `List` collection with all forecast information. | -| `getAverageTemperature()` | Returns average temperature from forecasts. | -| `getMinimumTemperature()` | Returns minimum temperature from forecasts. | -| `getMaximumTemperature()` | Returns maximum temperature from forecasts. | -| `getByMinimumTemperature()` | Returns `HourlyForecast.Forecast` for the time where temperature is minimal. | -| `getByMaximumTemperature()` | Returns `HourlyForecast.Forecast` for the time where temperature is maximal. | -| `getAveragePressure()` | Returns average pressure from forecasts. | -| `getMinimumPressure()` | Returns minimum pressure from forecasts. | -| `getMaximumPressure()` | Returns maximum pressure from forecasts. | -| `getByMinimumPressure()` | Returns `HourlyForecast.Forecast` for the time where pressure is minimal. | -| `getByMaximumPressure()` | Returns `HourlyForecast.Forecast` for the time where pressure is maximal. | -| `toString()` | Returns pretty string for the whole available forecast information. | - -`toString()` output example: -``` -City: Pruzhany(622997). Coordinates: latitude=52.5582, longitude=24.4567 -Country: BY -Forecasts: - Time: Tue Jul 17 00:00:00 MSK 2018. Weather: light rain. Temperature: 16.24 ℃. Minimum temperature: 16.24 ℃. Maximum temperature: 17.36 ℃. Pressure: 997.38 hPa. Sea-level pressure: 1018.59 hPa. Ground-level pressure: 997.38 hPa. Humidity: 99%. Cloudiness: 80%. Wind: 2.85 meter/sec, 324 degrees. Rain(last 3 hrs): 0 mm - Time: Tue Jul 17 03:00:00 MSK 2018. Weather: moderate rain. Temperature: 16.0 ℃. Minimum temperature: 16.0 ℃. Maximum temperature: 16.83 ℃. Pressure: 996.88 hPa. Sea-level pressure: 1017.86 hPa. Ground-level pressure: 996.88 hPa. Humidity: 99%. Cloudiness: 80%. Wind: 1.86 meter/sec, 349 degrees. Rain(last 3 hrs): 3 mm - Time: Tue Jul 17 06:00:00 MSK 2018. Weather: light rain. Temperature: 15.76 ℃. Minimum temperature: 15.76 ℃. Maximum temperature: 16.31 ℃. Pressure: 996.7 hPa. Sea-level pressure: 1017.72 hPa. Ground-level pressure: 996.7 hPa. Humidity: 94%. Cloudiness: 76%. Wind: 1.62 meter/sec, 113 degrees. Rain(last 3 hrs): 0 mm - Time: Tue Jul 17 09:00:00 MSK 2018. Weather: light rain. Temperature: 18.23 ℃. Minimum temperature: 18.23 ℃. Maximum temperature: 18.51 ℃. Pressure: 997.17 hPa. Sea-level pressure: 1018.18 hPa. Ground-level pressure: 997.17 hPa. Humidity: 100%. Cloudiness: 76%. Wind: 2.11 meter/sec, 107 degrees. Rain(last 3 hrs): 0 mm - Time: Tue Jul 17 12:00:00 MSK 2018. Weather: light rain. Temperature: 21.0 ℃. Minimum temperature: 21.0 ℃. Maximum temperature: 21.0 ℃. Pressure: 997.6 hPa. Sea-level pressure: 1018.5 hPa. Ground-level pressure: 997.6 hPa. Humidity: 100%. Cloudiness: 68%. Wind: 2.51 meter/sec, 82 degrees. Rain(last 3 hrs): 0 mm - Time: Tue Jul 17 15:00:00 MSK 2018. Weather: light rain. Temperature: 21.78 ℃. Minimum temperature: 21.78 ℃. Maximum temperature: 21.78 ℃. Pressure: 997.73 hPa. Sea-level pressure: 1018.66 hPa. Ground-level pressure: 997.73 hPa. Humidity: 92%. Cloudiness: 88%. Wind: 4.05 meter/sec, 78 degrees. Rain(last 3 hrs): 0 mm - Time: Tue Jul 17 18:00:00 MSK 2018. Weather: light rain. Temperature: 22.9 ℃. Minimum temperature: 22.9 ℃. Maximum temperature: 22.9 ℃. Pressure: 997.66 hPa. Sea-level pressure: 1018.55 hPa. Ground-level pressure: 997.66 hPa. Humidity: 93%. Cloudiness: 68%. Wind: 3.06 meter/sec, 67 degrees. Rain(last 3 hrs): 0 mm - Time: Tue Jul 17 21:00:00 MSK 2018. Weather: light rain. Temperature: 23.04 ℃. Minimum temperature: 23.04 ℃. Maximum temperature: 23.04 ℃. Pressure: 996.89 hPa. Sea-level pressure: 1017.99 hPa. Ground-level pressure: 996.89 hPa. Humidity: 83%. Cloudiness: 88%. Wind: 3.17 meter/sec, 16 degrees. Rain(last 3 hrs): 0 mm - Time: Wed Jul 18 00:00:00 MSK 2018. Weather: moderate rain. Temperature: 18.5 ℃. Minimum temperature: 18.5 ℃. Maximum temperature: 18.5 ℃. Pressure: 997.33 hPa. Sea-level pressure: 1018.34 hPa. Ground-level pressure: 997.33 hPa. Humidity: 97%. Cloudiness: 44%. Wind: 3.56 meter/sec, 31 degrees. Rain(last 3 hrs): 7 mm - Time: Wed Jul 18 03:00:00 MSK 2018. Weather: few clouds. Temperature: 18.57 ℃. Minimum temperature: 18.57 ℃. Maximum temperature: 18.57 ℃. Pressure: 996.91 hPa. Sea-level pressure: 1017.87 hPa. Ground-level pressure: 996.91 hPa. Humidity: 95%. Cloudiness: 24%. Wind: 5.26 meter/sec, 44 degrees. Rain(last 3 hrs): 0 mm - Time: Wed Jul 18 06:00:00 MSK 2018. Weather: few clouds. Temperature: 18.94 ℃. Minimum temperature: 18.94 ℃. Maximum temperature: 18.94 ℃. Pressure: 997.07 hPa. Sea-level pressure: 1018.06 hPa. Ground-level pressure: 997.07 hPa. Humidity: 95%. Cloudiness: 20%. Wind: 4.8 meter/sec, 45 degrees. Rain(last 3 hrs): 0 mm - Time: Wed Jul 18 09:00:00 MSK 2018. Weather: light rain. Temperature: 20.6 ℃. Minimum temperature: 20.6 ℃. Maximum temperature: 20.6 ℃. Pressure: 997.8 hPa. Sea-level pressure: 1018.66 hPa. Ground-level pressure: 997.8 hPa. Humidity: 97%. Cloudiness: 48%. Wind: 5.56 meter/sec, 54 degrees. Rain(last 3 hrs): 0 mm - Time: Wed Jul 18 12:00:00 MSK 2018. Weather: scattered clouds. Temperature: 23.87 ℃. Minimum temperature: 23.87 ℃. Maximum temperature: 23.87 ℃. Pressure: 998.06 hPa. Sea-level pressure: 1019.05 hPa. Ground-level pressure: 998.06 hPa. Humidity: 88%. Cloudiness: 32%. Wind: 5.86 meter/sec, 52 degrees. Rain(last 3 hrs): 0 mm - Time: Wed Jul 18 15:00:00 MSK 2018. Weather: scattered clouds. Temperature: 24.67 ℃. Minimum temperature: 24.67 ℃. Maximum temperature: 24.67 ℃. Pressure: 998.51 hPa. Sea-level pressure: 1019.33 hPa. Ground-level pressure: 998.51 hPa. Humidity: 84%. Cloudiness: 36%. Wind: 5.63 meter/sec, 51 degrees. Rain(last 3 hrs): 0 mm - Time: Wed Jul 18 18:00:00 MSK 2018. Weather: scattered clouds. Temperature: 25.15 ℃. Minimum temperature: 25.15 ℃. Maximum temperature: 25.15 ℃. Pressure: 998.79 hPa. Sea-level pressure: 1019.64 hPa. Ground-level pressure: 998.79 hPa. Humidity: 78%. Cloudiness: 44%. Wind: 5.47 meter/sec, 38 degrees. Rain(last 3 hrs): 0 mm - Time: Wed Jul 18 21:00:00 MSK 2018. Weather: scattered clouds. Temperature: 23.23 ℃. Minimum temperature: 23.23 ℃. Maximum temperature: 23.23 ℃. Pressure: 999.08 hPa. Sea-level pressure: 1020.04 hPa. Ground-level pressure: 999.08 hPa. Humidity: 75%. Cloudiness: 48%. Wind: 4.62 meter/sec, 25 degrees. Rain(last 3 hrs): 0 mm - Time: Thu Jul 19 00:00:00 MSK 2018. Weather: scattered clouds. Temperature: 20.79 ℃. Minimum temperature: 20.79 ℃. Maximum temperature: 20.79 ℃. Pressure: 999.67 hPa. Sea-level pressure: 1020.68 hPa. Ground-level pressure: 999.67 hPa. Humidity: 76%. Cloudiness: 48%. Wind: 4.29 meter/sec, 13 degrees. Rain(last 3 hrs): 0 mm - Time: Thu Jul 19 03:00:00 MSK 2018. Weather: scattered clouds. Temperature: 19.45 ℃. Minimum temperature: 19.45 ℃. Maximum temperature: 19.45 ℃. Pressure: 999.95 hPa. Sea-level pressure: 1021.02 hPa. Ground-level pressure: 999.95 hPa. Humidity: 80%. Cloudiness: 48%. Wind: 4.22 meter/sec, 17 degrees. Rain(last 3 hrs): 0 mm - Time: Thu Jul 19 06:00:00 MSK 2018. Weather: light rain. Temperature: 18.9 ℃. Minimum temperature: 18.9 ℃. Maximum temperature: 18.9 ℃. Pressure: 1000.6 hPa. Sea-level pressure: 1021.62 hPa. Ground-level pressure: 1000.6 hPa. Humidity: 83%. Cloudiness: 92%. Wind: 4.43 meter/sec, 10 degrees. Rain(last 3 hrs): 0 mm - Time: Thu Jul 19 09:00:00 MSK 2018. Weather: light rain. Temperature: 21.37 ℃. Minimum temperature: 21.37 ℃. Maximum temperature: 21.37 ℃. Pressure: 1000.95 hPa. Sea-level pressure: 1022.01 hPa. Ground-level pressure: 1000.95 hPa. Humidity: 87%. Cloudiness: 0%. Wind: 4.36 meter/sec, 6 degrees. Rain(last 3 hrs): 0 mm - Time: Thu Jul 19 12:00:00 MSK 2018. Weather: clear sky. Temperature: 23.92 ℃. Minimum temperature: 23.92 ℃. Maximum temperature: 23.92 ℃. Pressure: 1001.5 hPa. Sea-level pressure: 1022.43 hPa. Ground-level pressure: 1001.5 hPa. Humidity: 77%. Cloudiness: 0%. Wind: 5.66 meter/sec, 12 degrees. Rain(last 3 hrs): 0 mm - Time: Thu Jul 19 15:00:00 MSK 2018. Weather: broken clouds. Temperature: 23.7 ℃. Minimum temperature: 23.7 ℃. Maximum temperature: 23.7 ℃. Pressure: 1001.75 hPa. Sea-level pressure: 1022.72 hPa. Ground-level pressure: 1001.75 hPa. Humidity: 72%. Cloudiness: 56%. Wind: 5.87 meter/sec, 349 degrees. Rain(last 3 hrs): 0 mm - Time: Thu Jul 19 18:00:00 MSK 2018. Weather: broken clouds. Temperature: 23.82 ℃. Minimum temperature: 23.82 ℃. Maximum temperature: 23.82 ℃. Pressure: 1001.55 hPa. Sea-level pressure: 1022.59 hPa. Ground-level pressure: 1001.55 hPa. Humidity: 72%. Cloudiness: 68%. Wind: 5.47 meter/sec, 340 degrees. Rain(last 3 hrs): 0 mm - Time: Thu Jul 19 21:00:00 MSK 2018. Weather: broken clouds. Temperature: 22.22 ℃. Minimum temperature: 22.22 ℃. Maximum temperature: 22.22 ℃. Pressure: 1001.82 hPa. Sea-level pressure: 1022.93 hPa. Ground-level pressure: 1001.82 hPa. Humidity: 67%. Cloudiness: 76%. Wind: 4.12 meter/sec, 333 degrees. Rain(last 3 hrs): 0 mm - Time: Fri Jul 20 00:00:00 MSK 2018. Weather: scattered clouds. Temperature: 19.76 ℃. Minimum temperature: 19.76 ℃. Maximum temperature: 19.76 ℃. Pressure: 1001.98 hPa. Sea-level pressure: 1023.13 hPa. Ground-level pressure: 1001.98 hPa. Humidity: 76%. Cloudiness: 32%. Wind: 4.11 meter/sec, 312 degrees. Rain(last 3 hrs): 0 mm - Time: Fri Jul 20 03:00:00 MSK 2018. Weather: clear sky. Temperature: 17.53 ℃. Minimum temperature: 17.53 ℃. Maximum temperature: 17.53 ℃. Pressure: 1001.93 hPa. Sea-level pressure: 1023.13 hPa. Ground-level pressure: 1001.93 hPa. Humidity: 87%. Cloudiness: 8%. Wind: 4.21 meter/sec, 309 degrees. Rain(last 3 hrs): 0 mm - Time: Fri Jul 20 06:00:00 MSK 2018. Weather: scattered clouds. Temperature: 16.83 ℃. Minimum temperature: 16.83 ℃. Maximum temperature: 16.83 ℃. Pressure: 1001.79 hPa. Sea-level pressure: 1022.99 hPa. Ground-level pressure: 1001.79 hPa. Humidity: 91%. Cloudiness: 44%. Wind: 3.65 meter/sec, 312 degrees. Rain(last 3 hrs): 0 mm - Time: Fri Jul 20 09:00:00 MSK 2018. Weather: light rain. Temperature: 19.57 ℃. Minimum temperature: 19.57 ℃. Maximum temperature: 19.57 ℃. Pressure: 1001.34 hPa. Sea-level pressure: 1022.41 hPa. Ground-level pressure: 1001.34 hPa. Humidity: 85%. Cloudiness: 8%. Wind: 4.38 meter/sec, 305 degrees. Rain(last 3 hrs): 0 mm - Time: Fri Jul 20 12:00:00 MSK 2018. Weather: clear sky. Temperature: 23.5 ℃. Minimum temperature: 23.5 ℃. Maximum temperature: 23.5 ℃. Pressure: 1001.0 hPa. Sea-level pressure: 1021.99 hPa. Ground-level pressure: 1001.0 hPa. Humidity: 85%. Cloudiness: 8%. Wind: 5.36 meter/sec, 299 degrees. Rain(last 3 hrs): 0 mm - Time: Fri Jul 20 15:00:00 MSK 2018. Weather: scattered clouds. Temperature: 25.14 ℃. Minimum temperature: 25.14 ℃. Maximum temperature: 25.14 ℃. Pressure: 1000.5 hPa. Sea-level pressure: 1021.51 hPa. Ground-level pressure: 1000.5 hPa. Humidity: 73%. Cloudiness: 32%. Wind: 6.72 meter/sec, 305 degrees. Rain(last 3 hrs): 0 mm - Time: Fri Jul 20 18:00:00 MSK 2018. Weather: overcast clouds. Temperature: 23.56 ℃. Minimum temperature: 23.56 ℃. Maximum temperature: 23.56 ℃. Pressure: 1000.7 hPa. Sea-level pressure: 1021.58 hPa. Ground-level pressure: 1000.7 hPa. Humidity: 66%. Cloudiness: 88%. Wind: 6.57 meter/sec, 317 degrees. Rain(last 3 hrs): 0 mm - Time: Fri Jul 20 21:00:00 MSK 2018. Weather: broken clouds. Temperature: 22.41 ℃. Minimum temperature: 22.41 ℃. Maximum temperature: 22.41 ℃. Pressure: 1000.64 hPa. Sea-level pressure: 1021.67 hPa. Ground-level pressure: 1000.64 hPa. Humidity: 68%. Cloudiness: 64%. Wind: 4.31 meter/sec, 326 degrees. Rain(last 3 hrs): 0 mm - Time: Sat Jul 21 00:00:00 MSK 2018. Weather: broken clouds. Temperature: 20.92 ℃. Minimum temperature: 20.92 ℃. Maximum temperature: 20.92 ℃. Pressure: 1001.06 hPa. Sea-level pressure: 1022.14 hPa. Ground-level pressure: 1001.06 hPa. Humidity: 78%. Cloudiness: 68%. Wind: 3.42 meter/sec, 327 degrees. Rain(last 3 hrs): 0 mm - Time: Sat Jul 21 03:00:00 MSK 2018. Weather: broken clouds. Temperature: 20.28 ℃. Minimum temperature: 20.28 ℃. Maximum temperature: 20.28 ℃. Pressure: 1001.04 hPa. Sea-level pressure: 1022.13 hPa. Ground-level pressure: 1001.04 hPa. Humidity: 78%. Cloudiness: 76%. Wind: 4.27 meter/sec, 312 degrees. Rain(last 3 hrs): 0 mm - Time: Sat Jul 21 06:00:00 MSK 2018. Weather: scattered clouds. Temperature: 19.11 ℃. Minimum temperature: 19.11 ℃. Maximum temperature: 19.11 ℃. Pressure: 1001.13 hPa. Sea-level pressure: 1022.28 hPa. Ground-level pressure: 1001.13 hPa. Humidity: 74%. Cloudiness: 32%. Wind: 4.96 meter/sec, 308 degrees. Rain(last 3 hrs): 0 mm - Time: Sat Jul 21 09:00:00 MSK 2018. Weather: few clouds. Temperature: 20.16 ℃. Minimum temperature: 20.16 ℃. Maximum temperature: 20.16 ℃. Pressure: 1001.43 hPa. Sea-level pressure: 1022.62 hPa. Ground-level pressure: 1001.43 hPa. Humidity: 86%. Cloudiness: 20%. Wind: 5.16 meter/sec, 308 degrees. Rain(last 3 hrs): 0 mm - Time: Sat Jul 21 12:00:00 MSK 2018. Weather: few clouds. Temperature: 22.37 ℃. Minimum temperature: 22.37 ℃. Maximum temperature: 22.37 ℃. Pressure: 1001.53 hPa. Sea-level pressure: 1022.62 hPa. Ground-level pressure: 1001.53 hPa. Humidity: 88%. Cloudiness: 20%. Wind: 5.56 meter/sec, 307 degrees. Rain(last 3 hrs): 0 mm - Time: Sat Jul 21 15:00:00 MSK 2018. Weather: scattered clouds. Temperature: 22.85 ℃. Minimum temperature: 22.85 ℃. Maximum temperature: 22.85 ℃. Pressure: 1001.63 hPa. Sea-level pressure: 1022.65 hPa. Ground-level pressure: 1001.63 hPa. Humidity: 81%. Cloudiness: 44%. Wind: 5.46 meter/sec, 314 degrees. Rain(last 3 hrs): 0 mm - Time: Sat Jul 21 18:00:00 MSK 2018. Weather: scattered clouds. Temperature: 23.79 ℃. Minimum temperature: 23.79 ℃. Maximum temperature: 23.79 ℃. Pressure: 1001.53 hPa. Sea-level pressure: 1022.53 hPa. Ground-level pressure: 1001.53 hPa. Humidity: 72%. Cloudiness: 32%. Wind: 5.56 meter/sec, 313 degrees. Rain(last 3 hrs): 0 mm - Time: Sat Jul 21 21:00:00 MSK 2018. Weather: scattered clouds. Temperature: 22.56 ℃. Minimum temperature: 22.56 ℃. Maximum temperature: 22.56 ℃. Pressure: 1001.72 hPa. Sea-level pressure: 1022.7 hPa. Ground-level pressure: 1001.72 hPa. Humidity: 66%. Cloudiness: 48%. Wind: 3.96 meter/sec, 312 degrees. Rain(last 3 hrs): 0 mm -``` - -`HourlyForecast.Forecast`'s useful public methods(setters are not listed): - -| Method | Description | -|-----------------------------|------------------------------------------------------------------------------------------------------------------| -| `getDataCalculationTime()` | Returns `long` value that represents data calculation timestamp. | -| `getDataCalculationDate()` | Returns data calculation time in `Date` representation. | -| `getWeatherInfo()` | Returns `HourlyForecast.WeatherInfo` instance that contains information about temperature, pressure and humidity.| -| `getWeatherStates()` | Returns list of `WeatherState` instances with the only `getDescription` useful method. | -| `getClouds()` | Returns `Clouds` instance that contains *cloudiness* percentage information. | -| `getWind()` | Returns `Wind` instance that contains information about speed and degree. | -| `getSnow()` | Returns `Snow` instance that contains information about snow volume for the last 3 hours. | -| `getRain()` | Returns `Rain` instance that contains information about rain volume for the last 3 hours. | -| `getSystemInfo()` | Returns `HourlyForecast.ForecastSystemInfo` instance with internal information. | -| `getDt_txt()` | Returns `String` value that represents data calculation time. | -| `toString()` | Returns pretty string for the whole available forecast information. | - -#### 16 day / daily forecast -First step is retrieving `DailyForecastRequester` instance: -```java -OpenWeatherMapManager openWeatherManager = new OpenWeatherMapManager(API_TOKEN); -DailyForecastRequester forecastRequester = openWeatherManager.getDailyForecastRequester(); -``` -after you are able to set preferable options(via chain methods) and execute appropriate request: -``` -DailyForecast forecastResponse = forecastRequester - .setLanguage(Language.ENGLISH) - .setUnitSystem(Unit.METRIC_SYSTEM) - .setAccuracy(Accuracy.ACCURATE) - .getByCityName("Pruzhany"); -``` -*Language*, *UnitSystem* and *Accuracy* settings will be described below. - -Available requests: -* `getByCityId(String cityId)` -* `getByCityName(String cityName)` -* `getByCoordinates(double latitude, double longitude)` -* `getByCoordinates(Coordinates coordinates)` -* `getByZIPCode(String zipCode, String countryCode)` - -`DailyForecast`'s useful public methods(setters are not listed): - -| Method | Description | -|-----------------------------|--------------------------------------------------------------------------------------------| -| `getCityId()` | Returns city ID. Example: `625144` for Minsk. | -| `getCityName()` | Returns city name. Example: `Minsk`. | -| `getCoordinates()` | Returns `Coordinates` instance that contains *latitude* and *longitude* information. | -| `getCityInfo()` | Returns `CityInfo` instance that contains information about city. | -| `getResponseCode()` | Returns OpenWeatherMap response code. Internal information. | -| `getCountry()` | An alias for `getCityInfo().getCountry()`. | -| `getForecasts()` | Returns `List` collection with all forecast information. | -| `toString()` | Returns pretty string for the whole available forecast information. | - -`DailyForecast.Forecast`'s useful public methods(setters are not listed): - -| Method | Description | -|-----------------------------|------------------------------------------------------------------------------------------------------------------| -| `getDataCalculationTime()` | Returns `long` value that represents data calculation timestamp. | -| `getDataCalculationDate()` | Returns data calculation time in `Date` representation. | -| `getTemperature()` | Returns `DailyForecast.Forecast.Temperature` instance that contains information about temperature(avg, min, max).| -| `getWeatherStates()` | Returns list of `WeatherState` instances with the only `getDescription` useful method. | -| `getCloudiness()` | Returns *cloudiness* percentage information. | -| `getHumidity()` | Returns *humidity* percentage information. | -| `getWindSpeed()` | Returns wind's speed. | -| `getWindDegrees()` | Returns wind's degree. | -| `getWindUnit()` | Returns wind's unit. | -| `getPressure()` | Returns pressure value. | -| `getPressureUnit()` | Returns pressure's unit. | -| `toString()` | Returns pretty string for the whole available forecast information. | - -#### UV Index - -First step is retrieving `UltravioletIndexRequester` instance: -```java -OpenWeatherMapManager openWeatherMapManager = new OpenWeatherMapManager(API_TOKEN); -UltravioletIndexRequester requester = openWeatherMapManager.getUltravioletIndexRequester(); -``` -after you need to set coordinates and execute appropriate request: -``` -DailyForecast forecastResponse = forecastRequester - .setCoodrinates(55.33f, 24.27f) - .getCurrentUVIndex(); -``` - -Available requests: -* `getCurrentUVIndex()` -* `getUVIndexForecast(int amountOfDays)` -* `getUVIndexByPeriod(Date from, Date to)` - -`UltravioletIndex`'s useful public methods(setters are not listed): - -| Method | Description | -|---------------------------|---------------------------------------------------------------| -| `getLatitude()` | Returns latitude. | -| `getLongitude()` | Returns longitude. | -| `getDateISO()` | Returns ISO date in String representation. | -| `getDateTimestamp()` | Returns date timestamp. | -| `getValue()` | Returns UV value. | -| `getCalculationDate()` | Returns date in Date representation`. | -| `toString()` | Returns pretty string for the whole available UV information. | - -`toString()` output example: -``` -Date: Tue Jul 31 15:00:00 MSK 2018, Ultraviolet value: 6.230000 -``` - -#### Air pollution - -First step is retrieving `AirPollutionRequester` instance: -```java -OpenWeatherMapManager openWeatherMapManager = new OpenWeatherMapManager(API_TOKEN); -AirPollutionRequester requester = openWeatherMapManager.getAirPollutionRequester(); -``` -after you need to set coordinates, time frame, date and execute appropriate request: -``` -DailyForecast forecastResponse = forecastRequester - .setCoordinates(0.0f, 10.0f) - .setTimeFrame(TimeFrame.YEAR) - .setDate(new Date()) - .retrieve(); -``` - -Available requests: -* `retrieve()` - -`AirPollution`'s useful public methods(setters are not listed): - -| Method | Description | -|---------------------------|---------------------------------------------------------------------------| -| `getCoordinates()` | Returns `Coordinates` instance. | -| `getLongitude()` | Returns longitude. | -| `airPollutionInfo()` | Returns list of `AirPollution.AirPollutionInfo` instances. | -| `toString()` | Returns pretty string for the whole available air pollution information. | - -`toString()` output example: -``` -AirPollution[Date: Tue Jul 24 01:04:40 MSK 2018; Coordinates: latitude=0.0, longitude=9.9955] -[Value: 8.0347114E-8, Value: 9.5041536E-8, Value: 7.7667146E-8, Value: 7.251491E-8, Value: 5.899763E-8, Value: 1.9186361E-8, Value: 1.729535E-8, Value: 1.25645805E-8, Value: 3.0852514E-9] +Location: Minsk(BY), Weather: слегка облачно, 20.0 ℃, 1019.0 hPa, Clouds: 40% ``` ### Constants and options @@ -385,5 +169,5 @@ AirPollution[Date: Tue Jul 24 01:04:40 MSK 2018; Coordinates: latitude=0.0, long | Unit.STANDARD_SYSTEM | Kelvin, meter/sec, hPa, mm(rain, snow) | ### Dependencies -* com.alibaba:fastjson:1.2.44 -* org.projectlombok:lombok:1.18.0 (*provided*) \ No newline at end of file +* com.fasterxml.jackson.core:jackson-databind:2.9.9 +* junit:junit:4.12 (*test*) \ No newline at end of file diff --git a/pom.xml b/pom.xml index 2bcfc0b..72bb34c 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.github.prominence openweathermap-api - 1.2 + 2.0-SNAPSHOT jar Java OpenWeatherMap API @@ -132,16 +132,9 @@ - com.alibaba - fastjson - 1.2.44 - - - - org.projectlombok - lombok - 1.18.0 - provided + com.fasterxml.jackson.core + jackson-databind + 2.9.9 diff --git a/src/main/java/com/github/prominence/openweathermap/api/AirPollutionRequester.java b/src/main/java/com/github/prominence/openweathermap/api/AirPollutionRequester.java deleted file mode 100644 index 8aaea2c..0000000 --- a/src/main/java/com/github/prominence/openweathermap/api/AirPollutionRequester.java +++ /dev/null @@ -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; - } - -} diff --git a/src/main/java/com/github/prominence/openweathermap/api/BasicRequester.java b/src/main/java/com/github/prominence/openweathermap/api/BasicRequester.java deleted file mode 100644 index e8e6437..0000000 --- a/src/main/java/com/github/prominence/openweathermap/api/BasicRequester.java +++ /dev/null @@ -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 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 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 getAdditionalParameters() { - return null; - } - - protected abstract String getRequestType(); - - protected abstract T executeRequest(String requestSpecificParameters); - -} diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/OpenWeatherResponse.java b/src/main/java/com/github/prominence/openweathermap/api/CurrentWeatherRequestTerminator.java similarity index 80% rename from src/main/java/com/github/prominence/openweathermap/api/model/OpenWeatherResponse.java rename to src/main/java/com/github/prominence/openweathermap/api/CurrentWeatherRequestTerminator.java index ce6a60f..11d4339 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/model/OpenWeatherResponse.java +++ b/src/main/java/com/github/prominence/openweathermap/api/CurrentWeatherRequestTerminator.java @@ -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 extends RequestTerminator { - String getCityName(); - long getCityId(); - String getCountry(); - Coordinates getCoordinates(); - short getResponseCode(); + S asXML(); + + S asHTML(); } diff --git a/src/main/java/com/github/prominence/openweathermap/api/CurrentWeatherRequester.java b/src/main/java/com/github/prominence/openweathermap/api/CurrentWeatherRequester.java new file mode 100644 index 0000000..d9f7467 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/CurrentWeatherRequester.java @@ -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(); +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/DailyForecastRequester.java b/src/main/java/com/github/prominence/openweathermap/api/DailyForecastRequester.java deleted file mode 100644 index 27dd954..0000000 --- a/src/main/java/com/github/prominence/openweathermap/api/DailyForecastRequester.java +++ /dev/null @@ -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 { - - 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 getAdditionalParameters() { - Map 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; - } -} diff --git a/src/main/java/com/github/prominence/openweathermap/api/HourlyForecastRequester.java b/src/main/java/com/github/prominence/openweathermap/api/HourlyForecastRequester.java deleted file mode 100644 index 9e3757b..0000000 --- a/src/main/java/com/github/prominence/openweathermap/api/HourlyForecastRequester.java +++ /dev/null @@ -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 { - - 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; - } - -} diff --git a/src/main/java/com/github/prominence/openweathermap/api/MultipleLocationsWeatherRequester.java b/src/main/java/com/github/prominence/openweathermap/api/MultipleLocationsWeatherRequester.java new file mode 100644 index 0000000..5a24828 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/MultipleLocationsWeatherRequester.java @@ -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); + +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/MultipleResultCurrentWeatherAsyncRequestTerminator.java b/src/main/java/com/github/prominence/openweathermap/api/MultipleResultCurrentWeatherAsyncRequestTerminator.java new file mode 100644 index 0000000..35a1d1f --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/MultipleResultCurrentWeatherAsyncRequestTerminator.java @@ -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> { +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/MultipleResultCurrentWeatherRequestCustomizer.java b/src/main/java/com/github/prominence/openweathermap/api/MultipleResultCurrentWeatherRequestCustomizer.java new file mode 100644 index 0000000..5560a73 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/MultipleResultCurrentWeatherRequestCustomizer.java @@ -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 { + + MultipleResultCurrentWeatherRequestTerminator retrieve(); + + MultipleResultCurrentWeatherAsyncRequestTerminator retrieveAsync(); +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/MultipleResultCurrentWeatherRequestTerminator.java b/src/main/java/com/github/prominence/openweathermap/api/MultipleResultCurrentWeatherRequestTerminator.java new file mode 100644 index 0000000..2cc71aa --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/MultipleResultCurrentWeatherRequestTerminator.java @@ -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, String> { +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/OpenWeatherMapManager.java b/src/main/java/com/github/prominence/openweathermap/api/OpenWeatherMapManager.java deleted file mode 100644 index e2fe544..0000000 --- a/src/main/java/com/github/prominence/openweathermap/api/OpenWeatherMapManager.java +++ /dev/null @@ -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); - } -} diff --git a/src/main/java/com/github/prominence/openweathermap/api/AuthenticationTokenBasedRequester.java b/src/main/java/com/github/prominence/openweathermap/api/RequestCustomizer.java similarity index 68% rename from src/main/java/com/github/prominence/openweathermap/api/AuthenticationTokenBasedRequester.java rename to src/main/java/com/github/prominence/openweathermap/api/RequestCustomizer.java index 52e9a13..6e97b59 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/AuthenticationTokenBasedRequester.java +++ b/src/main/java/com/github/prominence/openweathermap/api/RequestCustomizer.java @@ -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> { - protected String authToken; + T accuracy(Accuracy accuracy); - protected AuthenticationTokenBasedRequester(String authToken) { - this.authToken = authToken; - } + T language(Language language); + T unit(Unit unit); } diff --git a/src/main/java/com/github/prominence/openweathermap/api/RequestTerminator.java b/src/main/java/com/github/prominence/openweathermap/api/RequestTerminator.java new file mode 100644 index 0000000..10e91ad --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/RequestTerminator.java @@ -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 asJava(); + + S asJSON(); +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/ResponseMapper.java b/src/main/java/com/github/prominence/openweathermap/api/ResponseMapper.java new file mode 100644 index 0000000..38ce552 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/ResponseMapper.java @@ -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 getSingle(String json); + + List getList(String json); +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/SingleLocationWeatherRequester.java b/src/main/java/com/github/prominence/openweathermap/api/SingleLocationWeatherRequester.java new file mode 100644 index 0000000..15c9666 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/SingleLocationWeatherRequester.java @@ -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); +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/SingleResultCurrentWeatherAsyncRequestTerminator.java b/src/main/java/com/github/prominence/openweathermap/api/SingleResultCurrentWeatherAsyncRequestTerminator.java new file mode 100644 index 0000000..491cb12 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/SingleResultCurrentWeatherAsyncRequestTerminator.java @@ -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> { +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/SingleResultCurrentWeatherRequestCustomizer.java b/src/main/java/com/github/prominence/openweathermap/api/SingleResultCurrentWeatherRequestCustomizer.java new file mode 100644 index 0000000..8e071c1 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/SingleResultCurrentWeatherRequestCustomizer.java @@ -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 { + + SingleResultCurrentWeatherRequestTerminator retrieve(); + + SingleResultCurrentWeatherAsyncRequestTerminator retrieveAsync(); + +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/SingleResultCurrentWeatherRequestTerminator.java b/src/main/java/com/github/prominence/openweathermap/api/SingleResultCurrentWeatherRequestTerminator.java new file mode 100644 index 0000000..ed0ef73 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/SingleResultCurrentWeatherRequestTerminator.java @@ -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 { +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/UltravioletIndexRequester.java b/src/main/java/com/github/prominence/openweathermap/api/UltravioletIndexRequester.java deleted file mode 100644 index bf0fdb6..0000000 --- a/src/main/java/com/github/prominence/openweathermap/api/UltravioletIndexRequester.java +++ /dev/null @@ -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 getUVIndexForecast(int amountOfDays) { - String requestParameters = String.format("lat=%f&lon=%f&cnt=%d", coordinates.getLatitude(), coordinates.getLongitude(), amountOfDays); - return getListOfObjects(requestParameters); - } - - public List 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 getListOfObjects(String requestParameters) { - List ultravioletIndex = null; - - TypeReference> typeRef = new TypeReference>() { - }; - - try (InputStream response = executeRequest("uvi/forecast", requestParameters)) { - ultravioletIndex = (List) 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; - } - -} diff --git a/src/main/java/com/github/prominence/openweathermap/api/WeatherRequester.java b/src/main/java/com/github/prominence/openweathermap/api/WeatherRequester.java deleted file mode 100644 index 6ed4c0c..0000000 --- a/src/main/java/com/github/prominence/openweathermap/api/WeatherRequester.java +++ /dev/null @@ -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 { - - 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; - } - -} diff --git a/src/main/java/com/github/prominence/openweathermap/api/constants/Language.java b/src/main/java/com/github/prominence/openweathermap/api/constants/Language.java deleted file mode 100644 index 756726b..0000000 --- a/src/main/java/com/github/prominence/openweathermap/api/constants/Language.java +++ /dev/null @@ -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"; - -} diff --git a/src/main/java/com/github/prominence/openweathermap/api/constants/Accuracy.java b/src/main/java/com/github/prominence/openweathermap/api/enums/Accuracy.java similarity index 77% rename from src/main/java/com/github/prominence/openweathermap/api/constants/Accuracy.java rename to src/main/java/com/github/prominence/openweathermap/api/enums/Accuracy.java index 435cf0c..f79c8bd 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/constants/Accuracy.java +++ b/src/main/java/com/github/prominence/openweathermap/api/enums/Accuracy.java @@ -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; + } } diff --git a/src/main/java/com/github/prominence/openweathermap/api/enums/Language.java b/src/main/java/com/github/prominence/openweathermap/api/enums/Language.java new file mode 100644 index 0000000..790786a --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/enums/Language.java @@ -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; + } +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/Coordinates.java b/src/main/java/com/github/prominence/openweathermap/api/enums/ResponseType.java similarity index 60% rename from src/main/java/com/github/prominence/openweathermap/api/model/Coordinates.java rename to src/main/java/com/github/prominence/openweathermap/api/enums/ResponseType.java index d4a4f56..c76ae5d 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/model/Coordinates.java +++ b/src/main/java/com/github/prominence/openweathermap/api/enums/ResponseType.java @@ -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; } } diff --git a/src/main/java/com/github/prominence/openweathermap/api/constants/TimeFrame.java b/src/main/java/com/github/prominence/openweathermap/api/enums/TimeFrame.java similarity index 92% rename from src/main/java/com/github/prominence/openweathermap/api/constants/TimeFrame.java rename to src/main/java/com/github/prominence/openweathermap/api/enums/TimeFrame.java index 310fc0d..058ca63 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/constants/TimeFrame.java +++ b/src/main/java/com/github/prominence/openweathermap/api/enums/TimeFrame.java @@ -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, diff --git a/src/main/java/com/github/prominence/openweathermap/api/constants/Unit.java b/src/main/java/com/github/prominence/openweathermap/api/enums/Unit.java similarity index 72% rename from src/main/java/com/github/prominence/openweathermap/api/constants/Unit.java rename to src/main/java/com/github/prominence/openweathermap/api/enums/Unit.java index 594013b..611f4f8 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/constants/Unit.java +++ b/src/main/java/com/github/prominence/openweathermap/api/enums/Unit.java @@ -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 'K'; + return "K"; } } + public String getValue() { + return value; + } } diff --git a/src/main/java/com/github/prominence/openweathermap/api/exception/DataNotFoundException.java b/src/main/java/com/github/prominence/openweathermap/api/exception/DataNotFoundException.java index 54a8b1e..6d5c074 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/exception/DataNotFoundException.java +++ b/src/main/java/com/github/prominence/openweathermap/api/exception/DataNotFoundException.java @@ -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 diff --git a/src/main/java/com/github/prominence/openweathermap/api/exception/InvalidAuthTokenException.java b/src/main/java/com/github/prominence/openweathermap/api/exception/InvalidAuthTokenException.java index b121d24..f578e31 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/exception/InvalidAuthTokenException.java +++ b/src/main/java/com/github/prominence/openweathermap/api/exception/InvalidAuthTokenException.java @@ -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 diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/response/UltravioletIndex.java b/src/main/java/com/github/prominence/openweathermap/api/impl/CurrentWeatherRequesterImpl.java similarity index 54% rename from src/main/java/com/github/prominence/openweathermap/api/model/response/UltravioletIndex.java rename to src/main/java/com/github/prominence/openweathermap/api/impl/CurrentWeatherRequesterImpl.java index d213d37..31ee121 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/model/response/UltravioletIndex.java +++ b/src/main/java/com/github/prominence/openweathermap/api/impl/CurrentWeatherRequesterImpl.java @@ -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); } } diff --git a/src/main/java/com/github/prominence/openweathermap/api/impl/CurrentWeatherResponseMapper.java b/src/main/java/com/github/prominence/openweathermap/api/impl/CurrentWeatherResponseMapper.java new file mode 100644 index 0000000..3da3f3b --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/impl/CurrentWeatherResponseMapper.java @@ -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 { + + 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 getList(String json) { + ObjectMapper objectMapper = new ObjectMapper(); + List 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; + } +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/impl/MultipleLocationsCurrentWeatherRequesterImpl.java b/src/main/java/com/github/prominence/openweathermap/api/impl/MultipleLocationsCurrentWeatherRequesterImpl.java new file mode 100644 index 0000000..011abe6 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/impl/MultipleLocationsCurrentWeatherRequesterImpl.java @@ -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); + } +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/impl/MultipleResultCurrentWeatherAsyncRequestTerminatorImpl.java b/src/main/java/com/github/prominence/openweathermap/api/impl/MultipleResultCurrentWeatherAsyncRequestTerminatorImpl.java new file mode 100644 index 0000000..bbae6a2 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/impl/MultipleResultCurrentWeatherAsyncRequestTerminatorImpl.java @@ -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> asJava() { + return CompletableFuture.supplyAsync(() -> new CurrentWeatherResponseMapper(unit).getList(getRawResponse())); + } + + @Override + public CompletableFuture asJSON() { + return CompletableFuture.supplyAsync(this::getRawResponse); + } + + @Override + public CompletableFuture asXML() { + urlBuilder.addRequestParameter("mode", "xml"); + return CompletableFuture.supplyAsync(this::getRawResponse); + } + + @Override + public CompletableFuture asHTML() { + urlBuilder.addRequestParameter("mode", "html"); + return CompletableFuture.supplyAsync(this::getRawResponse); + } + + private String getRawResponse() { + return RequestUtils.getRawResponse(urlBuilder.buildUrl()); + } +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/impl/MultipleResultCurrentWeatherRequestCustomizerImpl.java b/src/main/java/com/github/prominence/openweathermap/api/impl/MultipleResultCurrentWeatherRequestCustomizerImpl.java new file mode 100644 index 0000000..f229a9a --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/impl/MultipleResultCurrentWeatherRequestCustomizerImpl.java @@ -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()); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/github/prominence/openweathermap/api/impl/MultipleResultCurrentWeatherRequestTerminatorImpl.java b/src/main/java/com/github/prominence/openweathermap/api/impl/MultipleResultCurrentWeatherRequestTerminatorImpl.java new file mode 100644 index 0000000..09ba0a2 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/impl/MultipleResultCurrentWeatherRequestTerminatorImpl.java @@ -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 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()); + } +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/impl/OpenWeatherMapClient.java b/src/main/java/com/github/prominence/openweathermap/api/impl/OpenWeatherMapClient.java new file mode 100644 index 0000000..f33f743 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/impl/OpenWeatherMapClient.java @@ -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); + } +} diff --git a/src/test/java/com/github/prominence/openweathermap/api/test/AirPollutionRequestedIntegrationTest.java b/src/main/java/com/github/prominence/openweathermap/api/impl/RequestUrlBuilder.java similarity index 53% rename from src/test/java/com/github/prominence/openweathermap/api/test/AirPollutionRequestedIntegrationTest.java rename to src/main/java/com/github/prominence/openweathermap/api/impl/RequestUrlBuilder.java index 818b00b..6fac1dd 100644 --- a/src/test/java/com/github/prominence/openweathermap/api/test/AirPollutionRequestedIntegrationTest.java +++ b/src/main/java/com/github/prominence/openweathermap/api/impl/RequestUrlBuilder.java @@ -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 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(); } } diff --git a/src/main/java/com/github/prominence/openweathermap/api/impl/SingleLocationCurrentWeatherRequesterImpl.java b/src/main/java/com/github/prominence/openweathermap/api/impl/SingleLocationCurrentWeatherRequesterImpl.java new file mode 100644 index 0000000..8ff61ba --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/impl/SingleLocationCurrentWeatherRequesterImpl.java @@ -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); + } +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/impl/SingleResultCurrentWeatherAsyncRequestTerminatorImpl.java b/src/main/java/com/github/prominence/openweathermap/api/impl/SingleResultCurrentWeatherAsyncRequestTerminatorImpl.java new file mode 100644 index 0000000..dad66fc --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/impl/SingleResultCurrentWeatherAsyncRequestTerminatorImpl.java @@ -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 asJava() { + return CompletableFuture.supplyAsync(() -> new CurrentWeatherResponseMapper(unit).getSingle(getRawResponse())); + } + + @Override + public CompletableFuture asJSON() { + return CompletableFuture.supplyAsync(this::getRawResponse); + } + + @Override + public CompletableFuture asXML() { + urlBuilder.addRequestParameter("mode", "xml"); + return CompletableFuture.supplyAsync(this::getRawResponse); + } + + @Override + public CompletableFuture asHTML() { + urlBuilder.addRequestParameter("mode", "html"); + return CompletableFuture.supplyAsync(this::getRawResponse); + } + + private String getRawResponse() { + return RequestUtils.getRawResponse(urlBuilder.buildUrl()); + } +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/impl/SingleResultCurrentWeatherRequestCustomizerImpl.java b/src/main/java/com/github/prominence/openweathermap/api/impl/SingleResultCurrentWeatherRequestCustomizerImpl.java new file mode 100644 index 0000000..533af32 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/impl/SingleResultCurrentWeatherRequestCustomizerImpl.java @@ -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()); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/github/prominence/openweathermap/api/impl/SingleResultCurrentWeatherRequestTerminatorImpl.java b/src/main/java/com/github/prominence/openweathermap/api/impl/SingleResultCurrentWeatherRequestTerminatorImpl.java new file mode 100644 index 0000000..ed7306b --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/impl/SingleResultCurrentWeatherRequestTerminatorImpl.java @@ -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()); + } +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/Clouds.java b/src/main/java/com/github/prominence/openweathermap/api/model/Clouds.java index 4088478..9746867 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/model/Clouds.java +++ b/src/main/java/com/github/prominence/openweathermap/api/model/Clouds.java @@ -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(); } } diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/Coordinate.java b/src/main/java/com/github/prominence/openweathermap/api/model/Coordinate.java new file mode 100644 index 0000000..38e01e8 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/model/Coordinate.java @@ -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); + } +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/CoordinateRectangle.java b/src/main/java/com/github/prominence/openweathermap/api/model/CoordinateRectangle.java new file mode 100644 index 0000000..3e80fbb --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/model/CoordinateRectangle.java @@ -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(); + } +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/CityInfo.java b/src/main/java/com/github/prominence/openweathermap/api/model/Humidity.java similarity index 61% rename from src/main/java/com/github/prominence/openweathermap/api/model/CityInfo.java rename to src/main/java/com/github/prominence/openweathermap/api/model/Humidity.java index d2f8e25..3d35092 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/model/CityInfo.java +++ b/src/main/java/com/github/prominence/openweathermap/api/model/Humidity.java @@ -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(); } - } diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/Location.java b/src/main/java/com/github/prominence/openweathermap/api/model/Location.java new file mode 100644 index 0000000..1ae6c3d --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/model/Location.java @@ -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; + } +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/Pressure.java b/src/main/java/com/github/prominence/openweathermap/api/model/Pressure.java new file mode 100644 index 0000000..58af943 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/model/Pressure.java @@ -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(); + } +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/Rain.java b/src/main/java/com/github/prominence/openweathermap/api/model/Rain.java index 242f2f3..740328a 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/model/Rain.java +++ b/src/main/java/com/github/prominence/openweathermap/api/model/Rain.java @@ -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(); } } diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/Snow.java b/src/main/java/com/github/prominence/openweathermap/api/model/Snow.java index e8e7a5b..04b870f 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/model/Snow.java +++ b/src/main/java/com/github/prominence/openweathermap/api/model/Snow.java @@ -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(); } } diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/Temperature.java b/src/main/java/com/github/prominence/openweathermap/api/model/Temperature.java new file mode 100644 index 0000000..b399256 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/model/Temperature.java @@ -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; + } +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/Weather.java b/src/main/java/com/github/prominence/openweathermap/api/model/Weather.java new file mode 100644 index 0000000..6595529 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/model/Weather.java @@ -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; + + } +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/WeatherState.java b/src/main/java/com/github/prominence/openweathermap/api/model/WeatherState.java deleted file mode 100644 index c3f2d7b..0000000 --- a/src/main/java/com/github/prominence/openweathermap/api/model/WeatherState.java +++ /dev/null @@ -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; - } -} diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/Wind.java b/src/main/java/com/github/prominence/openweathermap/api/model/Wind.java index 1f07888..816ba29 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/model/Wind.java +++ b/src/main/java/com/github/prominence/openweathermap/api/model/Wind.java @@ -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; } } diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/response/AirPollution.java b/src/main/java/com/github/prominence/openweathermap/api/model/response/AirPollution.java deleted file mode 100644 index f8150e8..0000000 --- a/src/main/java/com/github/prominence/openweathermap/api/model/response/AirPollution.java +++ /dev/null @@ -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; - - 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; - } - } -} diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/response/DailyForecast.java b/src/main/java/com/github/prominence/openweathermap/api/model/response/DailyForecast.java deleted file mode 100644 index cf107d8..0000000 --- a/src/main/java/com/github/prominence/openweathermap/api/model/response/DailyForecast.java +++ /dev/null @@ -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 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 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(); - } - } - } -} diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/response/HourlyForecast.java b/src/main/java/com/github/prominence/openweathermap/api/model/response/HourlyForecast.java deleted file mode 100644 index 2280ed0..0000000 --- a/src/main/java/com/github/prominence/openweathermap/api/model/response/HourlyForecast.java +++ /dev/null @@ -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 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 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(); - } - } - } - -} diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/response/Weather.java b/src/main/java/com/github/prominence/openweathermap/api/model/response/Weather.java deleted file mode 100644 index 069136b..0000000 --- a/src/main/java/com/github/prominence/openweathermap/api/model/response/Weather.java +++ /dev/null @@ -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 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(); - } - } -} diff --git a/src/main/java/com/github/prominence/openweathermap/api/utils/JSONUtils.java b/src/main/java/com/github/prominence/openweathermap/api/utils/JSONUtils.java deleted file mode 100644 index ebc8abc..0000000 --- a/src/main/java/com/github/prominence/openweathermap/api/utils/JSONUtils.java +++ /dev/null @@ -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(); - } -} diff --git a/src/main/java/com/github/prominence/openweathermap/api/utils/RequestUtils.java b/src/main/java/com/github/prominence/openweathermap/api/utils/RequestUtils.java index b43eb50..f269952 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/utils/RequestUtils.java +++ b/src/main/java/com/github/prominence/openweathermap/api/utils/RequestUtils.java @@ -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(); + } + } diff --git a/src/main/java/com/github/prominence/openweathermap/api/utils/TimeFrameUtils.java b/src/main/java/com/github/prominence/openweathermap/api/utils/TimeFrameUtils.java index e7b9838..8fcb73d 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/utils/TimeFrameUtils.java +++ b/src/main/java/com/github/prominence/openweathermap/api/utils/TimeFrameUtils.java @@ -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; diff --git a/src/test/java/com/github/prominence/openweathermap/api/test/ApiTest.java b/src/test/java/com/github/prominence/openweathermap/api/test/ApiTest.java index a74c14f..b4d4735 100644 --- a/src/test/java/com/github/prominence/openweathermap/api/test/ApiTest.java +++ b/src/test/java/com/github/prominence/openweathermap/api/test/ApiTest.java @@ -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; } } diff --git a/src/test/java/com/github/prominence/openweathermap/api/test/CurrentWeatherIntegrationTest.java b/src/test/java/com/github/prominence/openweathermap/api/test/CurrentWeatherIntegrationTest.java new file mode 100644 index 0000000..269688f --- /dev/null +++ b/src/test/java/com/github/prominence/openweathermap/api/test/CurrentWeatherIntegrationTest.java @@ -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 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 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 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 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 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 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> 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 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); + } +} diff --git a/src/test/java/com/github/prominence/openweathermap/api/test/HourlyForecastRequesterIntegrationTest.java b/src/test/java/com/github/prominence/openweathermap/api/test/HourlyForecastRequesterIntegrationTest.java deleted file mode 100644 index 8ec149b..0000000 --- a/src/test/java/com/github/prominence/openweathermap/api/test/HourlyForecastRequesterIntegrationTest.java +++ /dev/null @@ -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"); - } -} diff --git a/src/test/java/com/github/prominence/openweathermap/api/test/UltravioletIndexRequestedIntegrationTest.java b/src/test/java/com/github/prominence/openweathermap/api/test/UltravioletIndexRequestedIntegrationTest.java deleted file mode 100644 index ca30886..0000000 --- a/src/test/java/com/github/prominence/openweathermap/api/test/UltravioletIndexRequestedIntegrationTest.java +++ /dev/null @@ -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(); - } -} diff --git a/src/test/java/com/github/prominence/openweathermap/api/test/WeatherRequestIntegrationTest.java b/src/test/java/com/github/prominence/openweathermap/api/test/WeatherRequestIntegrationTest.java deleted file mode 100644 index 38f0f87..0000000 --- a/src/test/java/com/github/prominence/openweathermap/api/test/WeatherRequestIntegrationTest.java +++ /dev/null @@ -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"); - } -}