diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000..caceddf --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,67 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ dev ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ dev ] + schedule: + - cron: '27 20 * * 1' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + language: [ 'java' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] + # Learn more: + # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + # â„šī¸ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # âœī¸ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 diff --git a/LICENSE b/LICENSE index 8ed4b26..c9309fc 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 Alexey Zinchenko +Copyright (c) 2021 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 cb9c8d2..dbdc90e 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,23 @@ Java API for OpenWeatherMap services. ### Implemented features: +Free: * Current weather data -* 5 day / 3 hour forecast -* 16 day / daily forecast -* UV Index -* Air pollution(beta) +* 5 day / 3-hour forecast ### Will be implemented later: -Global changes in API and more functionality. + +Free: +* One Call API +* Air pollution +* Geocoding API +* Weather Stations +* Weather Triggers + +Paid: +* Daily Forecast 16 days +* Hourly Forecast 4 days +* probably others... ### Maven coordinates: @@ -17,42 +26,29 @@ Global changes in API and more functionality. com.github.prominence openweathermap-api - 1.2 - -``` - -New experimental version: -```xml - - com.github.prominence - openweathermap-api - 2.0-SNAPSHOT + 2.0.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') +compile('com.github.prominence:openweathermap-api:2.0.0-SNAPSHOT') ``` ### Documentation * [OpenWeatherMap Java API - 1.0](docs/Release_1.0.md) * [OpenWeatherMap Java API - 1.1](docs/Release_1.1.md) * [OpenWeatherMap Java API - 1.2](docs/Release_1.2.md) +* [OpenWeatherMap Java API - 2.0.0](docs/Release_2.0.0.md) * [OpenWeatherMap Java API - SNAPSHOT](docs/SNAPSHOT.md) ### License MIT -[ci-shield]: https://travis-ci.org/Prominence/openweathermap-java-api.svg?branch=master +[ci-shield]: https://travis-ci.org/Prominence/openweathermap-java-api.svg?branch=dev [ci-link]: https://travis-ci.org/Prominence/openweathermap-java-api -[codecov-shield]: https://codecov.io/gh/Prominence/openweathermap-java-api/branch/master/graph/badge.svg +[codecov-shield]: https://codecov.io/gh/Prominence/openweathermap-java-api/branch/dev/graph/badge.svg [codecov-link]: https://codecov.io/gh/Prominence/openweathermap-java-api \ No newline at end of file diff --git a/docs/Release_1.0.md b/docs/Release_1.0.md index 1ac735d..a645dc4 100644 --- a/docs/Release_1.0.md +++ b/docs/Release_1.0.md @@ -62,7 +62,7 @@ Available requests: | `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. | +| `getWeatherInfo()` | Returns `Weather.WeatherInfo` instance that contains information about temperature, atmosphericPressure 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. | @@ -134,11 +134,11 @@ Available requests: | `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. | +| `getAveragePressure()` | Returns average atmosphericPressure from forecasts. | +| `getMinimumPressure()` | Returns minimum atmosphericPressure from forecasts. | +| `getMaximumPressure()` | Returns maximum atmosphericPressure from forecasts. | +| `getByMinimumPressure()` | Returns `HourlyForecast.Forecast` for the time where atmosphericPressure is minimal. | +| `getByMaximumPressure()` | Returns `HourlyForecast.Forecast` for the time where atmosphericPressure is maximal. | | `toString()` | Returns pretty string for the whole available forecast information. | `toString()` output example: @@ -146,46 +146,46 @@ Available requests: 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 + 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 atmosphericPressure: 1018.59 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1017.86 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1017.72 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1018.18 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1018.5 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1018.66 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1018.55 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1017.99 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1018.34 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1017.87 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1018.06 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1018.66 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1019.05 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1019.33 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1019.64 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1020.04 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1020.68 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1021.02 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1021.62 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.01 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.43 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.72 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.59 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.93 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1023.13 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1023.13 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.99 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.41 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1021.99 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1021.51 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1021.58 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1021.67 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.14 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.13 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.28 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.62 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.62 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.65 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.53 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.7 hPa. Ground-level atmosphericPressure: 1001.72 hPa. Humidity: 66%. Cloudiness: 48%. Wind: 3.96 meter/sec, 312 degrees. Rain(last 3 hrs): 0 mm ``` `Forecast`'s useful public methods(setters are not listed): @@ -194,7 +194,7 @@ Forecasts: |-----------------------------|------------------------------------------------------------------------------------------------------------------| | `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.| +| `getWeatherInfo()` | Returns `HourlyForecast.WeatherInfo` instance that contains information about temperature, atmosphericPressure 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. | diff --git a/docs/Release_1.1.md b/docs/Release_1.1.md index 4d1394f..b17edc6 100644 --- a/docs/Release_1.1.md +++ b/docs/Release_1.1.md @@ -68,7 +68,7 @@ Available requests: | `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. | +| `getWeatherInfo()` | Returns `Weather.WeatherInfo` instance that contains information about temperature, atmosphericPressure 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. | @@ -140,11 +140,11 @@ Available requests: | `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. | +| `getAveragePressure()` | Returns average atmosphericPressure from forecasts. | +| `getMinimumPressure()` | Returns minimum atmosphericPressure from forecasts. | +| `getMaximumPressure()` | Returns maximum atmosphericPressure from forecasts. | +| `getByMinimumPressure()` | Returns `HourlyForecast.Forecast` for the time where atmosphericPressure is minimal. | +| `getByMaximumPressure()` | Returns `HourlyForecast.Forecast` for the time where atmosphericPressure is maximal. | | `toString()` | Returns pretty string for the whole available forecast information. | `toString()` output example: @@ -152,46 +152,46 @@ Available requests: 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 + 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 atmosphericPressure: 1018.59 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1017.86 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1017.72 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1018.18 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1018.5 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1018.66 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1018.55 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1017.99 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1018.34 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1017.87 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1018.06 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1018.66 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1019.05 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1019.33 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1019.64 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1020.04 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1020.68 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1021.02 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1021.62 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.01 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.43 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.72 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.59 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.93 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1023.13 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1023.13 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.99 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.41 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1021.99 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1021.51 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1021.58 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1021.67 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.14 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.13 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.28 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.62 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.62 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.65 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.53 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.7 hPa. Ground-level atmosphericPressure: 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): @@ -200,7 +200,7 @@ Forecasts: |-----------------------------|------------------------------------------------------------------------------------------------------------------| | `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.| +| `getWeatherInfo()` | Returns `HourlyForecast.WeatherInfo` instance that contains information about temperature, atmosphericPressure 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. | @@ -259,8 +259,8 @@ Available requests: | `getWindSpeed()` | Returns wind's speed. | | `getWindDegrees()` | Returns wind's degree. | | `getWindUnit()` | Returns wind's unit. | -| `getPressure()` | Returns pressure value. | -| `getPressureUnit()` | Returns pressure's unit. | +| `getPressure()` | Returns atmosphericPressure value. | +| `getPressureUnit()` | Returns atmosphericPressure's unit. | | `toString()` | Returns pretty string for the whole available forecast information. | #### UV Index diff --git a/docs/Release_1.2.md b/docs/Release_1.2.md index cd7a79d..350cd03 100644 --- a/docs/Release_1.2.md +++ b/docs/Release_1.2.md @@ -68,7 +68,7 @@ Available requests: | `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. | +| `getWeatherInfo()` | Returns `Weather.WeatherInfo` instance that contains information about temperature, atmosphericPressure 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. | @@ -140,11 +140,11 @@ Available requests: | `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. | +| `getAveragePressure()` | Returns average atmosphericPressure from forecasts. | +| `getMinimumPressure()` | Returns minimum atmosphericPressure from forecasts. | +| `getMaximumPressure()` | Returns maximum atmosphericPressure from forecasts. | +| `getByMinimumPressure()` | Returns `HourlyForecast.Forecast` for the time where atmosphericPressure is minimal. | +| `getByMaximumPressure()` | Returns `HourlyForecast.Forecast` for the time where atmosphericPressure is maximal. | | `toString()` | Returns pretty string for the whole available forecast information. | `toString()` output example: @@ -152,46 +152,46 @@ Available requests: 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 + 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 atmosphericPressure: 1018.59 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1017.86 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1017.72 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1018.18 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1018.5 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1018.66 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1018.55 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1017.99 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1018.34 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1017.87 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1018.06 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1018.66 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1019.05 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1019.33 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1019.64 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1020.04 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1020.68 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1021.02 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1021.62 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.01 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.43 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.72 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.59 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.93 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1023.13 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1023.13 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.99 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.41 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1021.99 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1021.51 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1021.58 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1021.67 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.14 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.13 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.28 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.62 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.62 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.65 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.53 hPa. Ground-level atmosphericPressure: 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 atmosphericPressure: 1022.7 hPa. Ground-level atmosphericPressure: 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): @@ -200,7 +200,7 @@ Forecasts: |-----------------------------|------------------------------------------------------------------------------------------------------------------| | `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.| +| `getWeatherInfo()` | Returns `HourlyForecast.WeatherInfo` instance that contains information about temperature, atmosphericPressure 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. | @@ -259,8 +259,8 @@ Available requests: | `getWindSpeed()` | Returns wind's speed. | | `getWindDegrees()` | Returns wind's degree. | | `getWindUnit()` | Returns wind's unit. | -| `getPressure()` | Returns pressure value. | -| `getPressureUnit()` | Returns pressure's unit. | +| `getPressure()` | Returns atmosphericPressure value. | +| `getPressureUnit()` | Returns atmosphericPressure's unit. | | `toString()` | Returns pretty string for the whole available forecast information. | #### UV Index diff --git a/docs/Release_2.0.0.md b/docs/Release_2.0.0.md new file mode 100644 index 0000000..b08e2c6 --- /dev/null +++ b/docs/Release_2.0.0.md @@ -0,0 +1,253 @@ +### Implemented features: +* Current weather data +* 5 day / 3-hour forecast + +### Maven coordinates: + +```xml + + com.github.prominence + openweathermap-api + 2.0.0 + +``` + +### Gradle coordinates: + +```groovy +compile('com.github.prominence:openweathermap-api:2.0.0') +``` + +### How to use: + +Firstly, you need to create the instance of `OpenWeatherMapClient` class: +```java +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 APIs are: +* `currentWeather()` +* `forecast5Day3HourStep()` + +Default(more or less) customization points: +```java +... +// response language +.language(Language.RUSSIAN) +... +// response units of measure +.unitSystem(UnitSystem.IMPERIAL) +... +``` + +Available output forms: +* `asJava()` +* `asJSON()` + +Additional output forms, available for several APIs: +* `asXML()` +* `asHTML()` + +_All response forms can be in **sync** and **async** variants._ + +#### Current weather data +Examples: +```java +final String weatherJson = openWeatherClient + .currentWeather() + .single() + .byCityName("Minsk") + .language(Language.RUSSIAN) + .unitSystem(UnitSystem.IMPERIAL) + .retrieve() + .asJSON(); +``` + +```java +final Weather weather = openWeatherClient + .currentWeather() + .single() + .byCityName("Minsk") + .language(Language.RUSSIAN) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asJava(); +``` + +```java +final List weatherList = openWeatherClient + .currentWeather() + .multiple() + .byCitiesInCycle(Coordinate.withValues(55.5, 37.5)) + .language(Language.GERMAN) + .unitSystem(UnitSystem.IMPERIAL) + .retrieve() + .asJava(); +``` + +```java +final CompletableFuture weatherXmlFuture = openWeatherClient + .currentWeather() + .single() + .byZipCodeAndCountry("220015", "by") + .language(Language.RUSSIAN) + .unitSystem(UnitSystem.METRIC) + .retrieveAsync() + .asXML(); +``` + +You are able to set preferable options(via chain methods) and execute appropriate request. + +`com.github.prominence.openweathermap.api.model.weather.Weather`'s useful public methods(setters are not listed): + +| Method | Description | +|---------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `getState()` | Returns short weather description. Example: `Clear`. | +| `getDescription()` | Returns weather description. Example: `clear sky`. | +| `getWeatherIconUrl()` | Returns a link to weather icon hosted on https://openweathermap.org website. | +| `getCalculatedOn()` | Returns `LocalDateTime` object with data calculation time. | +| `getTemperature()` | Returns `Temperature` instance that contains information about temperature. Available fields: `value`, `maxTemperature`, `minTemperature`, `feelsLike` and `unit`. | +| `getAtmosphericPressure()`| Returns `AtmosphericPressure` instance that contains information about atmospheric pressure. Available fields: `value`, `seaLevelValue`, `groundLevelValue` and `unit`. | +| `getHumidity()` | Returns `Humidity` instance that contains humidity percentage information. | +| `getWind()` | Returns `Wind` instance that contains wind information: `speed`, `degrees`, `gust` and `unit`. | +| `getRain()` | Returns `Rain` instance that contains information about rain volume for the last one hour and/or the last 3 hours. Can be absent in case of no data. | +| `getSnow()` | Returns `Snow` instance that contains information about snow volume for the last one hour and/or the last 3 hours. Can be absent in case of no data. | +| `getClouds()` | Returns `Clouds` instance that contains information about cloudiness percentage. | +| `getLocation()` | Returns `Location` object. Available fields: `id`, `name`, `countryCode`, `sunrise` and `sunset` time, `zoneOffset` and `coordinate`. | +| `toString()` | Returns informative string for the whole available weather information. | + +`toString()` output example: +``` +Location: Minsk(BY), Weather: clear sky, -4.22 ℃, 1020.0 hPa, Clouds: 0% +``` + +#### 5 day / 3-hour forecast +Examples: +```java +final Forecast forecast = openWeatherClient + .forecast5Day3HourStep() + .byCityName("Minsk") + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .count(15) + .retrieve() + .asJava(); +``` + +```java +final String forecastJson = getClient() + .forecast5Day3HourStep() + .byCityName("New York", "NY", "US") + .language(Language.SPANISH) + .unitSystem(UnitSystem.IMPERIAL) + .count(15) + .retrieve() + .asJSON(); +``` + +```java +CompletableFuture forecastFuture = getClient() + .forecast5Day3HourStep() + .byCityId(350001514) + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .count(15) + .retrieveAsync() + .asXML(); +``` + +```java +final String forecastXml = getClient() + .forecast5Day3HourStep() + .byZipCodeInUSA("10005") + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asXML(); +``` + +You are able to set preferable options(via chain methods) and execute appropriate request. + +`com.github.prominence.openweathermap.api.request.forecast.free.Forecast`'s useful public methods(setters are not listed): + +| Method | Description | +|-------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------| +| `getLocation()` | Returns `Location` object. Available fields: `id`, `name`, `countryCode`, `sunrise` and `sunset` time, `zoneOffset`, `coordinate` and `population`. | +| `getWeatherForecasts()` | Returns list of `WeatherForecast` objects with forecast information. | +| `toString()` | Returns informative string for the whole available forecast information. | + +`toString()` output example: +``` +A forecast for Minsk with 15 timestamps. +``` + +`com.github.prominence.openweathermap.api.model.forecast.WeatherForecast`'s useful public methods(setters are not listed): + +| Method | Description | +|-------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `getState()` | Returns short weather description. Example: `Clear`. | +| `getDescription()` | Returns weather description. Example: `clear sky`. | +| `getWeatherIconUrl()` | Returns a link to weather icon hosted on https://openweathermap.org website. | +| `getForecastTime()` | Returns `LocalDateTime` object with weather forecast time. | +| `getTemperature()` | Returns `Temperature` instance that contains information about temperature. Available fields: `value`, `maxTemperature`, `minTemperature`, `feelsLike` and `unit`. | +| `getAtmosphericPressure()` | Returns `AtmosphericPressure` instance that contains information about atmospheric pressure. Available fields: `value`, `seaLevelValue`, `groundLevelValue` and `unit`. | +| `getHumidity()` | Returns `Humidity` instance that contains humidity percentage information. | +| `getWind()` | Returns `Wind` instance that contains wind information: `speed`, `degrees` and `unit`. | +| `getRain()` | Returns `Rain` instance that contains information about rain volume for the last 3 hours. Can be absent in case of no data. | +| `getSnow()` | Returns `Snow` instance that contains information about snow volume for the last 3 hours. Can be absent in case of no data. | +| `getClouds()` | Returns `Clouds` instance that contains information about cloudiness percentage. | +| `getForecastTimeISO()` | Returns String with time of data forecasted, ISO, UTC. | +| `getDayTime()` | Returns enumerations representing the part of day(day, night). | +| `toString()` | Returns informative string for the forecast of particular timestamp. | + +### Constants and options + +#### Language +| Constant | Description | +|-----------------------------------|-------------------------------| +| Language.ARABIC | Arabic language. | +| Language.BULGARIAN | Bulgarian language. | +| Language.CATALAN | Catalan language. | +| Language.CZECH | Czech language. | +| Language.GERMAN | German language. | +| Language.GREEK | Greek language. | +| Language.ENGLISH | English language. | +| Language.PERSIAN | Persian (Farsi) language. | +| Language.FINNISH | Finnish language. | +| Language.FRENCH | French language. | +| Language.GALICIAN | Galician language. | +| Language.CROATIAN | Croatian language. | +| Language.HUNGARIAN | Hungarian language. | +| Language.ITALIAN | Italian language. | +| Language.JAPANESE | Japanese language. | +| Language.KOREAN | Korean language. | +| Language.LATVIAN | Latvian language. | +| Language.LITHUANIAN | Lithuanian language. | +| Language.MACEDONIAN | Macedonian language. | +| Language.DUTCH | Dutch language. | +| Language.POLISH | Polish language. | +| Language.PORTUGUESE | Portuguese language. | +| Language.ROMANIAN | Romanian language. | +| Language.RUSSIAN | Russian language. | +| Language.SWEDISH | Swedish language. | +| Language.SLOVAK | Slovak language. | +| Language.SLOVENIAN | Slovenian language. | +| Language.SPANISH | Spanish language. | +| Language.TURKISH | Turkish language. | +| Language.UKRANIAN | Ukrainian language. | +| Language.VIETNAMESE | Vietnamese language. | +| Language.CHINESE_SIMPLIFIED | Chinese Simplified language. | +| Language.CHINESE_TRADITIONAL | Chinese Traditional language. | + +#### Unit +| Constant | Description | +|----------------------|------------------------------------------------| +| Unit.METRIC_SYSTEM | Celsius, meter/sec, hPa, mm(rain, snow). | +| Unit.IMPERIAL_SYSTEM | Fahrenheit, miles/hour, hPa, mm(rain, snow). | +| Unit.STANDARD_SYSTEM | Kelvin, meter/sec, hPa, mm(rain, snow). | + +### Dependencies +* com.fasterxml.jackson.core:jackson-databind:2.12.2 +* org.slf4j:slf4j-api:1.7.30 (*compile*) +* junit:junit:4.13.1 (*test*) \ No newline at end of file diff --git a/docs/SNAPSHOT.md b/docs/SNAPSHOT.md index a47c026..2461234 100644 --- a/docs/SNAPSHOT.md +++ b/docs/SNAPSHOT.md @@ -103,7 +103,7 @@ final CompletableFuture> weatherListFuture = openWeatherClient | `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. | +| `getPressure()` | Returns `Pressure` instance that contains information about atmosphericPressure and(not always) atmosphericPressure 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. | diff --git a/pom.xml b/pom.xml index 29c559b..6c2a7c2 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.github.prominence openweathermap-api - 2.0-SNAPSHOT + 2.0.0-SNAPSHOT jar Java OpenWeatherMap API @@ -70,7 +70,7 @@ org.apache.maven.plugins maven-jar-plugin - 3.1.0 + 3.2.0 **/test/* @@ -80,7 +80,7 @@ org.sonatype.plugins nexus-staging-maven-plugin - 1.6.7 + 1.6.8 true ossrh @@ -91,7 +91,7 @@ org.apache.maven.plugins maven-source-plugin - 2.2.1 + 3.2.1 attach-sources @@ -104,7 +104,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.10.4 + 3.2.0 8 @@ -120,7 +120,7 @@ org.apache.maven.plugins maven-gpg-plugin - 1.5 + 1.6 sign-artifacts @@ -134,7 +134,7 @@ org.jacoco jacoco-maven-plugin - 0.8.4 + 0.8.6 @@ -157,12 +157,12 @@ com.fasterxml.jackson.core jackson-databind - 2.10.0 + 2.12.2 org.slf4j slf4j-api - 1.7.26 + 1.7.30 compile diff --git a/src/main/java/com/github/prominence/openweathermap/api/OpenWeatherMapClient.java b/src/main/java/com/github/prominence/openweathermap/api/OpenWeatherMapClient.java new file mode 100644 index 0000000..e0d6440 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/OpenWeatherMapClient.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2021 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.annotation.SubscriptionAvailability; +import com.github.prominence.openweathermap.api.request.forecast.free.FiveDayThreeHourStepForecastRequester; +import com.github.prominence.openweathermap.api.request.forecast.free.FiveDayThreeHourStepForecastRequesterImpl; +import com.github.prominence.openweathermap.api.request.weather.CurrentWeatherRequester; +import com.github.prominence.openweathermap.api.request.weather.CurrentWeatherRequesterImpl; + +import static com.github.prominence.openweathermap.api.enums.SubscriptionPlan.*; + +/** + * The main public API client to communicate with OpenWeatherMap services. + * Requires API key for usage. More info on the website https://openweathermap.org/api. + */ +public class OpenWeatherMapClient { + private final String apiKey; + + /** + * Created OpenWeatherMap client object. + * @param apiKey API key obtained on OpwnWeatherMap site. + */ + public OpenWeatherMapClient(String apiKey) { + this.apiKey = apiKey; + } + + /** + * Current Weather API. + * @return requester for retrieving current weather information. + */ + @SubscriptionAvailability(plans = ALL) + public CurrentWeatherRequester currentWeather() { + return new CurrentWeatherRequesterImpl(apiKey); + } + + /** + * 5 Day / 3 Hour Forecast API. + * @return requester for retrieving 5 day/3-hour weather forecast information. + */ + @SubscriptionAvailability(plans = ALL) + public FiveDayThreeHourStepForecastRequester forecast5Day3HourStep() { + return new FiveDayThreeHourStepForecastRequesterImpl(apiKey); + } +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/CurrentWeatherRequestTerminator.java b/src/main/java/com/github/prominence/openweathermap/api/annotation/SubscriptionAvailability.java similarity index 60% rename from src/main/java/com/github/prominence/openweathermap/api/CurrentWeatherRequestTerminator.java rename to src/main/java/com/github/prominence/openweathermap/api/annotation/SubscriptionAvailability.java index 11d4339..8e30155 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/CurrentWeatherRequestTerminator.java +++ b/src/main/java/com/github/prominence/openweathermap/api/annotation/SubscriptionAvailability.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,11 +20,24 @@ * SOFTWARE. */ -package com.github.prominence.openweathermap.api; +package com.github.prominence.openweathermap.api.annotation; -public interface CurrentWeatherRequestTerminator extends RequestTerminator { +import com.github.prominence.openweathermap.api.enums.SubscriptionPlan; - S asXML(); +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; - S asHTML(); +/** + * Marker-type annotation to specify what type of license it needs to have to use API method. + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.CLASS) +public @interface SubscriptionAvailability { + /** + * Marks method with subscription plan it needs to have to use the method. + * @return subscription plan. + */ + SubscriptionPlan[] plans(); } 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 index 790786a..869b9e7 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/enums/Language.java +++ b/src/main/java/com/github/prominence/openweathermap/api/enums/Language.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,40 +22,174 @@ package com.github.prominence.openweathermap.api.enums; +/** + * An enumeration which lists all available languages for API usage. + * Usually it could be specified to get response with some fields translated into desired language. + */ public enum Language { - + /** + * Arabic language. + */ ARABIC("ar"), + + /** + * Bulgarian language. + */ BULGARIAN("bg"), + + /** + * Catalan language. + */ CATALAN("ca"), + + /** + * Czech language. + */ CZECH("cz"), + + /** + * German language. + */ GERMAN("de"), + + /** + * Greek language. + */ GREEK("el"), + + /** + * English language. + */ ENGLISH("en"), + + /** + * Persian language. + */ PERSIAN("fa"), + + /** + * Finnish language. + */ FINNISH("fi"), + + /** + * French language. + */ FRENCH("fr"), + + /** + * Galician language. + */ GALICIAN("gl"), + + /** + * Croatian language. + */ CROATIAN("hr"), + + /** + * Hungarian language. + */ HUNGARIAN("hu"), + + /** + * Italian language. + */ ITALIAN("it"), + + /** + * Japanese language. + */ JAPANESE("ja"), + + /** + * Korean language. + */ KOREAN("kr"), + + /** + * Latvian language. + */ LATVIAN("la"), + + /** + * Lithuanian language. + */ LITHUANIAN("lt"), + + /** + * Macedonian language. + */ MACEDONIAN("mk"), + + /** + * Dutch language. + */ DUTCH("nl"), + + /** + * Polish language. + */ POLISH("pl"), + + /** + * Portuguese language. + */ PORTUGUESE("pt"), + + /** + * Romanian language. + */ ROMANIAN ("ro"), + + /** + * Russian language. + */ RUSSIAN("ru"), + + /** + * Swedish language. + */ SWEDISH("se"), + + /** + * Slovak language. + */ SLOVAK("sk"), + + /** + * Slovenian language. + */ SLOVENIAN("sl"), + + /** + * Spanish language. + */ SPANISH("en"), + + /** + * Turkish language. + */ TURKISH("tr"), + + /** + * Ukranian language. + */ UKRANIAN("uk"), + + /** + * Vietnamese language. + */ VIETNAMESE("vi"), + + /** + * Chinese simplified language. + */ CHINESE_SIMPLIFIED("zh_cn"), + + /** + * Chinese traditional language. + */ CHINESE_TRADITIONAL("zh_tw"); private final String value; @@ -64,6 +198,10 @@ public enum Language { this.value = value; } + /** + * Returns language's value. + * @return value. + */ public String getValue() { return value; } diff --git a/src/main/java/com/github/prominence/openweathermap/api/enums/TimeFrame.java b/src/main/java/com/github/prominence/openweathermap/api/enums/SubscriptionPlan.java similarity index 64% rename from src/main/java/com/github/prominence/openweathermap/api/enums/TimeFrame.java rename to src/main/java/com/github/prominence/openweathermap/api/enums/SubscriptionPlan.java index 058ca63..b2419c7 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/enums/TimeFrame.java +++ b/src/main/java/com/github/prominence/openweathermap/api/enums/SubscriptionPlan.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,11 +22,38 @@ package com.github.prominence.openweathermap.api.enums; -public enum TimeFrame { - YEAR, - MONTH, - DAY, - HOUR, - MINUTE, - SECOND +/** + * An enumeration with all available subscription plans. + * More information at official website. + */ +public enum SubscriptionPlan { + /** + * Free subscription plan. + */ + FREE, + + /** + * Startup subscription plan. + */ + STARTUP, + + /** + * Developer subscription plan. + */ + DEVELOPER, + + /** + * Professional subscription plan. + */ + PROFESSIONAL, + + /** + * Enterprise subscription plan. + */ + ENTERPRISE, + + /** + * All existing subscription plans. + */ + ALL, } diff --git a/src/main/java/com/github/prominence/openweathermap/api/enums/UnitSystem.java b/src/main/java/com/github/prominence/openweathermap/api/enums/UnitSystem.java index b7e4853..94e2781 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/enums/UnitSystem.java +++ b/src/main/java/com/github/prominence/openweathermap/api/enums/UnitSystem.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,10 +22,23 @@ package com.github.prominence.openweathermap.api.enums; +/** + * An enumeration for supported unit systems with helper methods. + */ public enum UnitSystem { - + /** + * Metric units: Celsius, meter/sec, hPa, mm(rain, snow). + */ METRIC("metric"), + + /** + * Imperial units: Fahrenheit, miles/hour, hPa, mm(rain, snow). + */ IMPERIAL("imperial"), + + /** + * OpenWeatherMap standard units: Kelvin, meter/sec, hPa, mm(rain, snow). + */ STANDARD("standard"); private final String value; @@ -34,8 +47,12 @@ public enum UnitSystem { this.value = value; } - public static String getWindUnit(UnitSystem type) { - switch (type) { + /** + * Returns wind unit for current unit system. + * @return wind unit. + */ + public String getWindUnit() { + switch (this) { case IMPERIAL: return "miles/hour"; case STANDARD: @@ -45,8 +62,12 @@ public enum UnitSystem { } } - public static String getTemperatureUnit(UnitSystem type) { - switch (type) { + /** + * Returns temperature unit for current unit system. + * @return temperature unit. + */ + public String getTemperatureUnit() { + switch (this) { case METRIC: return "℃"; case IMPERIAL: @@ -57,6 +78,10 @@ public enum UnitSystem { } } + /** + * Returns unit system value. + * @return value unit system. + */ public String getValue() { return value; } 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 b1e642f..db5486f 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) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,10 +22,16 @@ package com.github.prominence.openweathermap.api.exception; +/** + * An exception that could be thrown in case of your API key is invalid or your subscription plan does not cover requested functionality. + * Subscription plans information you can find here. + * API Keys could be checked in your profile. + */ public class InvalidAuthTokenException extends RuntimeException { - + /** + * Creates {@link InvalidAuthTokenException} exception with default message. + */ public InvalidAuthTokenException() { super("Authentication token wasn't set or requested functionality is not permitted for your subscription plan. Please, check https://home.openweathermap.org/api_keys/ and https://openweathermap.org/price."); } - } diff --git a/src/main/java/com/github/prominence/openweathermap/api/exception/NoDataFoundException.java b/src/main/java/com/github/prominence/openweathermap/api/exception/NoDataFoundException.java index a46b888..95572b7 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/exception/NoDataFoundException.java +++ b/src/main/java/com/github/prominence/openweathermap/api/exception/NoDataFoundException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,14 +22,27 @@ package com.github.prominence.openweathermap.api.exception; +/** + * An exception that could be thrown in several cases: + *
    + *
  • There is no data found for your query(wrong coordinates somewhere in the sea, some distant place, etc.);
  • + *
  • Request is malformed. An occasion to report an issue;
  • + *
  • Any other unpredictable problems.
  • + *
+ */ public class NoDataFoundException extends RuntimeException { - + /** + * Creates {@link NoDataFoundException} with default message. + */ public NoDataFoundException() { super("Data for provided parameters wasn't found. Please, check requested location."); } + /** + * Creates {@link NoDataFoundException} with message from another throwable. + * @param throwable source throwable. + */ public NoDataFoundException(Throwable throwable) { super(throwable.getMessage(), throwable.getCause()); } - } diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/Pressure.java b/src/main/java/com/github/prominence/openweathermap/api/model/AtmosphericPressure.java similarity index 73% rename from src/main/java/com/github/prominence/openweathermap/api/model/Pressure.java rename to src/main/java/com/github/prominence/openweathermap/api/model/AtmosphericPressure.java index f3b11eb..b486a8b 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/model/Pressure.java +++ b/src/main/java/com/github/prominence/openweathermap/api/model/AtmosphericPressure.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,11 +25,10 @@ package com.github.prominence.openweathermap.api.model; import java.util.Objects; /** - * The Pressure type represents pressure value percentage. + * The AtmosphericPressure type represents atmospheric pressure value. * Its value can only be a double in [0, +∞) range. */ -public class Pressure { - +public class AtmosphericPressure { private static final String DEFAULT_UNIT = "hPa"; private double value; @@ -43,13 +42,22 @@ public class Pressure { * @param value the value representing pressure value. * @throws IllegalArgumentException in case if provided value isn't in allowed range. */ - public Pressure(double value) { - if (value < 0) { - throw new IllegalArgumentException("Pressure value must be in [0, +∞) range."); - } + private AtmosphericPressure(double value) { this.value = value; } + /** + * Static method for {@link AtmosphericPressure} creation with value checking. + * @param value atmospheric pressure value. + * @return instantiated {@link AtmosphericPressure} object. + */ + public static AtmosphericPressure withValue(double value) { + if (value < 0) { + throw new IllegalArgumentException("Atmospheric pressure value must be in [0, +∞) range."); + } + return new AtmosphericPressure(value); + } + /** * Returns pressure value. * @@ -67,7 +75,7 @@ public class Pressure { */ public void setValue(double value) { if (value < 0) { - throw new IllegalArgumentException("Pressure value must be in [0, +∞) range."); + throw new IllegalArgumentException("Atmospheric pressure value must be in [0, +∞) range."); } this.value = value; } @@ -89,7 +97,7 @@ public class Pressure { */ public void setSeaLevelValue(double seaLevelValue) { if (seaLevelValue < 0) { - throw new IllegalArgumentException("Pressure value must be in [0, +∞) range."); + throw new IllegalArgumentException("Atmospheric pressure value must be in [0, +∞) range."); } this.seaLevelValue = seaLevelValue; } @@ -111,7 +119,7 @@ public class Pressure { */ public void setGroundLevelValue(double groundLevelValue) { if (groundLevelValue < 0) { - throw new IllegalArgumentException("Pressure value must be in [0, +∞) range."); + throw new IllegalArgumentException("Atmospheric pressure value must be in [0, +∞) range."); } this.groundLevelValue = groundLevelValue; } @@ -128,11 +136,11 @@ public class Pressure { @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 && - Objects.equals(seaLevelValue, pressure.seaLevelValue) && - Objects.equals(groundLevelValue, pressure.groundLevelValue); + if (!(o instanceof AtmosphericPressure)) return false; + AtmosphericPressure atmosphericPressure = (AtmosphericPressure) o; + return Double.compare(atmosphericPressure.value, value) == 0 && + Objects.equals(seaLevelValue, atmosphericPressure.seaLevelValue) && + Objects.equals(groundLevelValue, atmosphericPressure.groundLevelValue); } @Override 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 554673b..e5f3fa4 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) 2019 Alexey Zinchenko + * Copyright (c) 2021 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 @@ -29,7 +29,6 @@ import java.util.Objects; * Its value can only be an integer in [0, 100] range. */ public class Clouds { - private static final String DEFAULT_UNIT = "%"; private byte value; @@ -40,11 +39,20 @@ public class Clouds { * @param value the value representing cloudiness percentage. * @throws IllegalArgumentException in case if provided value isn't in allowed range. */ - public Clouds(byte value) { + private Clouds(byte value) { + this.value = value; + } + + /** + * Static method for {@link Clouds} creation with value checking. + * @param value clouds percentage value. + * @return instantiated {@link Clouds} object. + */ + public static Clouds withValue(byte value) { if (value < 0 || value > 100) { throw new IllegalArgumentException("Cloudiness value must be in [0, 100] range."); } - this.value = value; + return new Clouds(value); } /** 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 index 5f42724..a96acfc 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/model/Coordinate.java +++ b/src/main/java/com/github/prominence/openweathermap/api/model/Coordinate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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 @@ -24,21 +24,38 @@ package com.github.prominence.openweathermap.api.model; import java.util.Objects; +/** + * Represents some location by its latitude and longitude. + */ public class Coordinate { private double latitude; private double longitude; - public Coordinate(double latitude, double longitude) { + private Coordinate(double latitude, double longitude) { + this.latitude = latitude; + this.longitude = longitude; + } + + /** + * Method for {@link Coordinate} creation with correctness check. + * @param latitude latitude + * @param longitude longitude + * @return coordinate object. + */ + public static Coordinate withValues(double latitude, double longitude) { if (latitude < -90 || latitude > 90) { throw new IllegalArgumentException("Latitude value must be in the next range: [-90.0; 90.0]."); } if (longitude < -180 || longitude > 180) { throw new IllegalArgumentException("Longitude value must be in the next range: [-180.0; 180.0]."); } - this.latitude = latitude; - this.longitude = longitude; + return new Coordinate(latitude, longitude); } + /** + * Sets latitude with checks. + * @param latitude latitude value + */ 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]."); @@ -46,6 +63,10 @@ public class Coordinate { this.latitude = latitude; } + /** + * Sets longitude with checks. + * @param longitude longitude value + */ 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]."); @@ -53,10 +74,18 @@ public class Coordinate { this.longitude = longitude; } + /** + * Returns latitude. + * @return latitude + */ public double getLatitude() { return latitude; } + /** + * Returns longitude. + * @return longitude + */ public double getLongitude() { return longitude; } 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 index 7aec701..2aec240 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/model/CoordinateRectangle.java +++ b/src/main/java/com/github/prominence/openweathermap/api/model/CoordinateRectangle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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 @@ -24,43 +24,77 @@ package com.github.prominence.openweathermap.api.model; import java.util.Objects; +/** + * Represents coordinate rectangle by its bottom-left and top-right coordinates. + */ public class CoordinateRectangle { + private final double longitudeLeft; + private final double latitudeBottom; + private final double longitudeRight; + private final double latitudeTop; - private double longitudeLeft; - private double latitudeBottom; - private double longitudeRight; - private double latitudeTop; - - public CoordinateRectangle(double longitudeLeft, double latitudeBottom, double longitudeRight, double latitudeTop) { - if (latitudeBottom < -90 || latitudeTop < -90 || latitudeBottom > 90 || latitudeTop > 90) { - throw new IllegalArgumentException("Latitude value must be in the next range: [-90.0; 90.0]."); - } - if (longitudeLeft < -180 || longitudeRight < -180 || longitudeLeft > 180 || longitudeRight > 180) { - throw new IllegalArgumentException("Longitude value must be in the next range: [-180.0; 180.0]."); - } + private CoordinateRectangle(double longitudeLeft, double latitudeBottom, double longitudeRight, double latitudeTop) { this.longitudeLeft = longitudeLeft; this.latitudeBottom = latitudeBottom; this.longitudeRight = longitudeRight; this.latitudeTop = latitudeTop; } + /** + * Method for {@link CoordinateRectangle} creation with correctness check. + * @param longitudeLeft left longitude + * @param latitudeBottom bottom latitude + * @param longitudeRight right longitude + * @param latitudeTop tip latitude + * @return coordinate rectangle object. + */ + public static CoordinateRectangle withValues(double longitudeLeft, double latitudeBottom, double longitudeRight, double latitudeTop) { + if (latitudeBottom < -90 || latitudeTop < -90 || latitudeBottom > 90 || latitudeTop > 90) { + throw new IllegalArgumentException("Latitude value must be in the next range: [-90.0; 90.0]."); + } + if (longitudeLeft < -180 || longitudeRight < -180 || longitudeLeft > 180 || longitudeRight > 180) { + throw new IllegalArgumentException("Longitude value must be in the next range: [-180.0; 180.0]."); + } + return new CoordinateRectangle(longitudeLeft, latitudeBottom, longitudeRight, latitudeTop); + } + + /** + * Returns left longitude value. + * @return left longitude + */ public double getLongitudeLeft() { return longitudeLeft; } + /** + * Returns bottom latitude value. + * @return bottom latitude + */ public double getLatitudeBottom() { return latitudeBottom; } + /** + * Returns right longitude value. + * @return right longitude + */ public double getLongitudeRight() { return longitudeRight; } + /** + * Returns top latitude value. + * @return top latitude + */ public double getLatitudeTop() { return latitudeTop; } - public String getFormattedString() { + /** + * Formatted coordinate rectangle string. + * @return formatted string + */ + public String getFormattedRequestString() { return longitudeLeft + "," + latitudeBottom + "," + longitudeRight + "," + latitudeTop; } @@ -82,6 +116,85 @@ public class CoordinateRectangle { @Override public String toString() { - return "Rectangle: " + getFormattedString(); + return "Rectangle: " + getFormattedRequestString(); + } + + /** + * Builder for CoordinateRectangle class. + */ + public static class Builder { + private Double longitudeLeft; + private Double latitudeBottom; + private Double longitudeRight; + private Double latitudeTop; + + /** + * Creates Builder object. + */ + public Builder() { + } + + /** + * Sets left longitude with correctness check. + * @param longitudeLeft left longitude + * @return builder object + */ + public Builder setLongitudeLeft(double longitudeLeft) { + if (longitudeLeft < -180 || longitudeLeft > 180) { + throw new IllegalArgumentException("Longitude value must be in the next range: [-180.0; 180.0]."); + } + this.longitudeLeft = longitudeLeft; + return this; + } + + /** + * Sets bottom latitude with correctness check. + * @param latitudeBottom bottom latitude + * @return builder object + */ + public Builder setLatitudeBottom(double latitudeBottom) { + if (latitudeBottom < -90 || latitudeBottom > 90) { + throw new IllegalArgumentException("Latitude value must be in the next range: [-90.0; 90.0]."); + } + this.latitudeBottom = latitudeBottom; + return this; + } + + /** + * Sets right longitude with correctness check. + * @param longitudeRight right longitude + * @return builder object + */ + public Builder setLongitudeRight(double longitudeRight) { + if (longitudeRight < -180 || longitudeRight > 180) { + throw new IllegalArgumentException("Longitude value must be in the next range: [-180.0; 180.0]."); + } + this.longitudeRight = longitudeRight; + return this; + } + + /** + * Sets top latitude with correctness check. + * @param latitudeTop top latitude + * @return builder object + */ + public Builder setLatitudeTop(double latitudeTop) { + if (latitudeTop < -90 || latitudeTop > 90) { + throw new IllegalArgumentException("Latitude value must be in the next range: [-90.0; 90.0]."); + } + this.latitudeTop = latitudeTop; + return this; + } + + /** + * Builds {@link CoordinateRectangle} object with correctness check. + * @return {@link CoordinateRectangle} built object. + */ + public CoordinateRectangle build() { + if (longitudeLeft == null || latitudeBottom == null || longitudeRight == null || latitudeTop == null) { + throw new IllegalStateException("Not all fields were set."); + } + return new CoordinateRectangle(longitudeLeft, latitudeBottom, longitudeRight, latitudeTop); + } } } diff --git a/src/main/java/com/github/prominence/openweathermap/api/enums/Accuracy.java b/src/main/java/com/github/prominence/openweathermap/api/model/DayTime.java similarity index 76% rename from src/main/java/com/github/prominence/openweathermap/api/enums/Accuracy.java rename to src/main/java/com/github/prominence/openweathermap/api/model/DayTime.java index f79c8bd..249dd35 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/enums/Accuracy.java +++ b/src/main/java/com/github/prominence/openweathermap/api/model/DayTime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,18 +20,32 @@ * SOFTWARE. */ -package com.github.prominence.openweathermap.api.enums; +package com.github.prominence.openweathermap.api.model; -public enum Accuracy { - LIKE("like"), - ACCURATE("accurate"); +/** + * Enumeration for time of a day representation. + */ +public enum DayTime { + /** + * Day value. + */ + DAY("d"), + + /** + * Night value. + */ + NIGHT("n"); private final String value; - Accuracy(String value) { + DayTime(String value) { this.value = value; } + /** + * Returns time of a day value. + * @return string value + */ public String getValue() { return value; } diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/Humidity.java b/src/main/java/com/github/prominence/openweathermap/api/model/Humidity.java index b28a6bd..ebd9d3a 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/model/Humidity.java +++ b/src/main/java/com/github/prominence/openweathermap/api/model/Humidity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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 @@ -29,7 +29,6 @@ import java.util.Objects; * Its value can only be an integer in [0, 100] range. */ public class Humidity { - private static final String DEFAULT_UNIT = "%"; private int value; @@ -40,11 +39,20 @@ public class Humidity { * @param value the value representing humidity percentage. * @throws IllegalArgumentException in case if provided value isn't in allowed range. */ - public Humidity(byte value) { + private Humidity(byte value) { + this.value = value; + } + + /** + * Creates {@link Humidity} object with correctness check. + * @param value humidity + * @return created {@link Humidity} object + */ + public static Humidity withValue(byte value) { if (value < 0 || value > 100) { throw new IllegalArgumentException("Humidity value must be in [0, 100] range."); } - this.value = value; + return new Humidity(value); } /** 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 deleted file mode 100644 index 927af43..0000000 --- a/src/main/java/com/github/prominence/openweathermap/api/model/Rain.java +++ /dev/null @@ -1,98 +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.model; - -import java.util.Objects; - -public class Rain { - - private static final String DEFAULT_UNIT = "mm"; - - 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 DEFAULT_UNIT; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof Rain)) return false; - Rain rain = (Rain) o; - return Objects.equals(oneHourRainLevel, rain.oneHourRainLevel) && - Objects.equals(threeHourRainLevel, rain.threeHourRainLevel); - } - - @Override - public int hashCode() { - return Objects.hash(oneHourRainLevel, threeHourRainLevel); - } - - @Override - public String toString() { - StringBuilder snowString = new StringBuilder(); - if (oneHourRainLevel == null && threeHourRainLevel == null) { - snowString.append("unknown"); - } else { - if (oneHourRainLevel != null) { - snowString.append("1 last hour rain level: "); - snowString.append(oneHourRainLevel); - snowString.append(getUnit()); - } - if (threeHourRainLevel != null) { - if (oneHourRainLevel != null) { - snowString.append(", "); - } - snowString.append("3 last hours rain level: "); - snowString.append(threeHourRainLevel); - snowString.append(getUnit()); - } - } - return snowString.toString(); - } -} 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 deleted file mode 100644 index 91c7bba..0000000 --- a/src/main/java/com/github/prominence/openweathermap/api/model/Snow.java +++ /dev/null @@ -1,98 +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.model; - -import java.util.Objects; - -public class Snow { - - private static final String DEFAULT_UNIT = "mm"; - - 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 DEFAULT_UNIT; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof Snow)) return false; - Snow snow = (Snow) o; - return Objects.equals(oneHourSnowLevel, snow.oneHourSnowLevel) && - Objects.equals(threeHourSnowLevel, snow.threeHourSnowLevel); - } - - @Override - public int hashCode() { - return Objects.hash(oneHourSnowLevel, threeHourSnowLevel); - } - - @Override - public String toString() { - StringBuilder snowString = new StringBuilder(); - if (oneHourSnowLevel == null && threeHourSnowLevel == null) { - snowString.append("unknown"); - } else { - if (oneHourSnowLevel != null) { - snowString.append("1 last hour snow level: "); - snowString.append(oneHourSnowLevel); - snowString.append(getUnit()); - } - if (threeHourSnowLevel != null) { - if (oneHourSnowLevel != null) { - snowString.append(", "); - } - snowString.append("3 last hours snow level: "); - snowString.append(threeHourSnowLevel); - snowString.append(getUnit()); - } - } - return snowString.toString(); - } -} 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 index f68dbd1..5ec1fec 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/model/Temperature.java +++ b/src/main/java/com/github/prominence/openweathermap/api/model/Temperature.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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 @@ -24,49 +24,110 @@ package com.github.prominence.openweathermap.api.model; import java.util.Objects; +/** + * Represents temperature values and unit. + */ public class Temperature { - private double value; private Double maxTemperature; private Double minTemperature; + private Double feelsLike; private String unit; - public Temperature(double value, String unit) { - if (unit == null) { - throw new IllegalArgumentException("Unit must be set."); - } + private Temperature(double value, String unit) { this.value = value; this.unit = unit; } + /** + * Creates {@link Temperature} object with correctness check. + * @param value temperature value + * @param unit temperature unit + * @return temperature object + */ + public static Temperature withValue(double value, String unit) { + if (unit == null) { + throw new IllegalArgumentException("Unit must be set."); + } + return new Temperature(value, unit); + } + + /** + * Returns temperature value. + * @return value + */ public double getValue() { return value; } + /** + * Sets temperature value. + * @param value temperature + */ public void setValue(double value) { this.value = value; } + /** + * Returns maximal temperature value. + * @return maximal temperature value + */ public Double getMaxTemperature() { return maxTemperature; } + /** + * Sets maximal temperature value. + * @param maxTemperature maximal temperature + */ public void setMaxTemperature(Double maxTemperature) { this.maxTemperature = maxTemperature; } + /** + * Returns minimal temperature value. + * @return minimal temperature value + */ public Double getMinTemperature() { return minTemperature; } + /** + * Sets minimal temperature value. + * @param minTemperature minimal temperature + */ public void setMinTemperature(Double minTemperature) { this.minTemperature = minTemperature; } + /** + * Returns 'feels like' temperature value. + * @return 'feels like' temperature value + */ + public Double getFeelsLike() { + return feelsLike; + } + + /** + * Sets 'feels like' temperature value. + * @param feelsLike 'feels like' temperature + */ + public void setFeelsLike(Double feelsLike) { + this.feelsLike = feelsLike; + } + + /** + * Returns temperature unit. + * @return unit + */ public String getUnit() { return unit; } + /** + * Sets temperature unit with correctness check. + * @param unit temperature unit + */ public void setUnit(String unit) { if (unit == null) { throw new IllegalArgumentException("Unit must be set."); @@ -82,12 +143,13 @@ public class Temperature { return Double.compare(that.value, value) == 0 && Objects.equals(maxTemperature, that.maxTemperature) && Objects.equals(minTemperature, that.minTemperature) && + Objects.equals(feelsLike, that.feelsLike) && Objects.equals(unit, that.unit); } @Override public int hashCode() { - return Objects.hash(value, maxTemperature, minTemperature, unit); + return Objects.hash(value, maxTemperature, minTemperature, feelsLike, unit); } @Override @@ -109,6 +171,12 @@ public class Temperature { stringBuilder.append(' '); stringBuilder.append(unit); } + if (feelsLike != null) { + stringBuilder.append(", Feels like: "); + stringBuilder.append(feelsLike); + stringBuilder.append(' '); + stringBuilder.append(unit); + } return stringBuilder.toString(); } diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/forecast/Forecast.java b/src/main/java/com/github/prominence/openweathermap/api/model/forecast/Forecast.java new file mode 100644 index 0000000..093beb2 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/model/forecast/Forecast.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2021 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.forecast; + +import java.util.List; +import java.util.Objects; + +/** + * Represents information about forecast for different timestamps. + */ +public class Forecast { + private Location location; + private List weatherForecasts; + + /** + * Returns location information. + * @return location + */ + public Location getLocation() { + return location; + } + + /** + * Sets forecast location. + * @param location forecast location + */ + public void setLocation(Location location) { + this.location = location; + } + + /** + * Returns list of weather forecasts for different timestamps. + * @return list of forecast-per-timestamp information. + */ + public List getWeatherForecasts() { + return weatherForecasts; + } + + /** + * Sets list of weather forecasts for different timestamps. + * @param weatherForecasts list of forecast information + */ + public void setWeatherForecasts(List weatherForecasts) { + this.weatherForecasts = weatherForecasts; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Forecast forecast = (Forecast) o; + return Objects.equals(location, forecast.location) && Objects.equals(weatherForecasts, forecast.weatherForecasts); + } + + @Override + public int hashCode() { + return Objects.hash(location, weatherForecasts); + } + + @Override + public String toString() { + return "A forecast for " + location.getName() + " with " + weatherForecasts.size() + " timestamps."; + } +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/forecast/Location.java b/src/main/java/com/github/prominence/openweathermap/api/model/forecast/Location.java new file mode 100644 index 0000000..0d79832 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/model/forecast/Location.java @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2021 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.forecast; + +import com.github.prominence.openweathermap.api.model.Coordinate; + +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.util.Objects; + +/** + * Represents location information. + */ +public class Location { + private int id; + private String name; + private String countryCode; + + private LocalDateTime sunrise; + private LocalDateTime sunset; + private ZoneOffset zoneOffset; + + private Coordinate coordinate; + + private Long population; + + private Location(int id, String name) { + this.id = id; + this.name = name; + } + + /** + * Creates {@link Location} object with correctness check. + * @param id location id + * @param name location name + * @return location object + */ + public static Location withValues(int id, String name) { + if (name == null) { + throw new IllegalArgumentException("Name must be set."); + } + return new Location(id, name); + } + + /** + * Returns ID. + * @return location ID + */ + public int getId() { + return id; + } + + /** + * Sets location ID. + * @param id location id + */ + public void setId(int id) { + this.id = id; + } + + /** + * Returns location name. + * @return location name + */ + public String getName() { + return name; + } + + /** + * Sets location name. + * @param name location name + */ + public void setName(String name) { + this.name = name; + } + + /** + * Returns country code. + * @return location country code + */ + public String getCountryCode() { + return countryCode; + } + + /** + * Sets location country code. + * @param countryCode location country code + */ + public void setCountryCode(String countryCode) { + this.countryCode = countryCode; + } + + /** + * Returns location sunrise time. + * @return sunrise time + */ + public LocalDateTime getSunrise() { + return sunrise; + } + + /** + * Sets location sunrise time. + * @param sunrise sunrise time + */ + public void setSunrise(LocalDateTime sunrise) { + this.sunrise = sunrise; + } + + /** + * Returns location sunset time. + * @return sunset time + */ + public LocalDateTime getSunset() { + return sunset; + } + + /** + * Sets location sunset time. + * @param sunset sunset time + */ + public void setSunset(LocalDateTime sunset) { + this.sunset = sunset; + } + + /** + * Returns location timezone offset. + * @return timezone offset + */ + public ZoneOffset getZoneOffset() { + return zoneOffset; + } + + /** + * Sets location timezone offset. + * @param zoneOffset timezone offset + */ + public void setZoneOffset(ZoneOffset zoneOffset) { + this.zoneOffset = zoneOffset; + } + + /** + * Returns location coordinates. + * @return location coordinates. + */ + public Coordinate getCoordinate() { + return coordinate; + } + + /** + * Sets location coordinates. + * @param coordinate location coordinates + */ + public void setCoordinate(Coordinate coordinate) { + this.coordinate = coordinate; + } + + /** + * Sets location population. + * @return location population + */ + public Long getPopulation() { + return population; + } + + /** + * Sets location population. + * @param population location population + */ + public void setPopulation(Long population) { + this.population = population; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Location)) return false; + Location location = (Location) o; + return id == location.id && + Objects.equals(name, location.name) && + Objects.equals(countryCode, location.countryCode) && + Objects.equals(sunrise, location.sunrise) && + Objects.equals(sunset, location.sunset) && + Objects.equals(zoneOffset, location.zoneOffset) && + Objects.equals(coordinate, location.coordinate) && + Objects.equals(population, location.population); + } + + @Override + public int hashCode() { + return Objects.hash(id, name, countryCode, sunrise, sunset, zoneOffset, coordinate, population); + } + + @Override + public String toString() { + final StringBuilder stringBuilder = new StringBuilder(); + if (coordinate != null) { + stringBuilder.append(coordinate.toString()); + stringBuilder.append(". "); + } + stringBuilder.append("ID: "); + stringBuilder.append(id); + stringBuilder.append(", Name: "); + stringBuilder.append(name); + if (countryCode != null) { + stringBuilder.append('('); + stringBuilder.append(countryCode); + stringBuilder.append(')'); + } + if (population != null) { + stringBuilder.append(", Population: "); + stringBuilder.append(population); + } + return stringBuilder.toString(); + } +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/forecast/Rain.java b/src/main/java/com/github/prominence/openweathermap/api/model/forecast/Rain.java new file mode 100644 index 0000000..f079bc2 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/model/forecast/Rain.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2021 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.forecast; + +import java.util.Objects; + +/** + * Represents rain information. + */ +public class Rain { + private static final String DEFAULT_UNIT = "mm"; + + private double threeHourRainLevel; + + private Rain(double threeHourRainLevel) { + this.threeHourRainLevel = threeHourRainLevel; + } + + /** + * Creates {@link Rain} object with correctness check. + * @param threeHourRainLevel 3-hour rain level value + * @return rain object. + */ + public static Rain withThreeHourLevelValue(double threeHourRainLevel) { + if (threeHourRainLevel < 0) { + throw new IllegalArgumentException("Rain level value cannot be negative."); + } + return new Rain(threeHourRainLevel); + } + + /** + * Returns 3-hour rain level value. + * @return 3-hour rain level value + */ + public double getThreeHourRainLevel() { + return threeHourRainLevel; + } + + /** + * Sets 3-hour rain level value with correctness check. + * @param threeHourRainLevel 3-hour rain level value + */ + public void setThreeHourRainLevel(double threeHourRainLevel) { + if (threeHourRainLevel < 0) { + throw new IllegalArgumentException("Rain level value cannot be negative."); + } + this.threeHourRainLevel = threeHourRainLevel; + } + + /** + * Returns rain level unit of measure. Currently is constant. + * @return rain level unit of measure + */ + public String getUnit() { + return DEFAULT_UNIT; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Rain rain = (Rain) o; + return Double.compare(rain.threeHourRainLevel, threeHourRainLevel) == 0; + } + + @Override + public int hashCode() { + return Objects.hash(threeHourRainLevel); + } + + @Override + public String toString() { + return "3-hour rain level: " + + threeHourRainLevel + ' ' + + getUnit(); + } +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/forecast/Snow.java b/src/main/java/com/github/prominence/openweathermap/api/model/forecast/Snow.java new file mode 100644 index 0000000..d0cea01 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/model/forecast/Snow.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2021 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.forecast; + +import java.util.Objects; + +/** + * Represents snow information. + */ +public class Snow { + private static final String DEFAULT_UNIT = "mm"; + + private double threeHourSnowLevel; + + private Snow(double threeHourSnowLevel) { + this.threeHourSnowLevel = threeHourSnowLevel; + } + + /** + * Creates {@link Snow} object with correctness check. + * @param threeHourSnowLevel 3-hour snow level value + * @return snow object. + */ + public static Snow withThreeHourLevelValue(double threeHourSnowLevel) { + if (threeHourSnowLevel < 0) { + throw new IllegalArgumentException("Snow level value cannot be negative."); + } + return new Snow(threeHourSnowLevel); + } + + /** + * Returns 3-hour snow level value. + * @return 3-hour snow level value + */ + public double getThreeHourSnowLevel() { + return threeHourSnowLevel; + } + + /** + * Sets 3-hour snow level value with correctness check. + * @param threeHourSnowLevel 3-hour snow level value + */ + public void setThreeHourSnowLevel(double threeHourSnowLevel) { + if (threeHourSnowLevel < 0) { + throw new IllegalArgumentException("Snow level value cannot be negative."); + } + this.threeHourSnowLevel = threeHourSnowLevel; + } + + /** + * Returns snow level unit of measure. Currently is constant. + * @return snow level unit of measure + */ + public String getUnit() { + return DEFAULT_UNIT; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Snow snow = (Snow) o; + return Double.compare(snow.threeHourSnowLevel, threeHourSnowLevel) == 0; + } + + @Override + public int hashCode() { + return Objects.hash(threeHourSnowLevel); + } + + @Override + public String toString() { + return "3-hour snow level: " + + threeHourSnowLevel + ' ' + + getUnit(); + } +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/forecast/WeatherForecast.java b/src/main/java/com/github/prominence/openweathermap/api/model/forecast/WeatherForecast.java new file mode 100644 index 0000000..7c12652 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/model/forecast/WeatherForecast.java @@ -0,0 +1,376 @@ +/* + * Copyright (c) 2021 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.forecast; + +import com.github.prominence.openweathermap.api.model.*; + +import java.time.LocalDateTime; +import java.util.Objects; + +/** + * Represents weather forecast information for a particular timestamp. + */ +public class WeatherForecast { + private String state; + private String description; + private String weatherIconUrl; + + private LocalDateTime forecastTime; + + private Temperature temperature; + private AtmosphericPressure atmosphericPressure; + private Humidity humidity; + + private Wind wind; + private Rain rain; + private Snow snow; + private Clouds clouds; + + private String forecastTimeISO; + private DayTime dayTime; + + private WeatherForecast(String state, String description) { + this.state = state; + this.description = description; + } + + /** + * For value weather forecast. + * + * @param state the state + * @param description the description + * @return the weather forecast + */ + public static WeatherForecast forValue(String state, String description) { + if (state == null) { + throw new IllegalArgumentException("State must be set."); + } + if (description == null) { + throw new IllegalArgumentException("Description must be set."); + } + return new WeatherForecast(state, description); + } + + /** + * Gets state. + * + * @return the state + */ + public String getState() { + return state; + } + + /** + * Sets state. + * + * @param state the state + */ + public void setState(String state) { + if (state == null) { + throw new IllegalArgumentException("State must be not null."); + } + this.state = state; + } + + /** + * Gets description. + * + * @return the description + */ + public String getDescription() { + return description; + } + + /** + * Sets description. + * + * @param description the description + */ + public void setDescription(String description) { + if (description == null) { + throw new IllegalArgumentException("Description must be not null."); + } + this.description = description; + } + + /** + * Gets weather icon url. + * + * @return the weather icon url + */ + public String getWeatherIconUrl() { + return weatherIconUrl; + } + + /** + * Sets weather icon url. + * + * @param weatherIconUrl the weather icon url + */ + public void setWeatherIconUrl(String weatherIconUrl) { + this.weatherIconUrl = weatherIconUrl; + } + + /** + * Gets forecast time. + * + * @return the forecast time + */ + public LocalDateTime getForecastTime() { + return forecastTime; + } + + /** + * Sets forecast time. + * + * @param forecastTime the forecast time + */ + public void setForecastTime(LocalDateTime forecastTime) { + this.forecastTime = forecastTime; + } + + /** + * Gets temperature. + * + * @return the temperature + */ + public Temperature getTemperature() { + return temperature; + } + + /** + * Sets temperature. + * + * @param temperature the temperature + */ + public void setTemperature(Temperature temperature) { + this.temperature = temperature; + } + + /** + * Gets atmospheric pressure. + * + * @return the atmospheric pressure + */ + public AtmosphericPressure getAtmosphericPressure() { + return atmosphericPressure; + } + + /** + * Sets atmospheric pressure. + * + * @param atmosphericPressure the atmospheric pressure + */ + public void setAtmosphericPressure(AtmosphericPressure atmosphericPressure) { + this.atmosphericPressure = atmosphericPressure; + } + + /** + * Gets humidity. + * + * @return the humidity + */ + public Humidity getHumidity() { + return humidity; + } + + /** + * Sets humidity. + * + * @param humidity the humidity + */ + public void setHumidity(Humidity humidity) { + this.humidity = humidity; + } + + /** + * Gets wind. + * + * @return the wind + */ + public Wind getWind() { + return wind; + } + + /** + * Sets wind. + * + * @param wind the wind + */ + public void setWind(Wind wind) { + this.wind = wind; + } + + /** + * Gets rain. + * + * @return the rain + */ + public Rain getRain() { + return rain; + } + + /** + * Sets rain. + * + * @param rain the rain + */ + public void setRain(Rain rain) { + this.rain = rain; + } + + /** + * Gets snow. + * + * @return the snow + */ + public Snow getSnow() { + return snow; + } + + /** + * Sets snow. + * + * @param snow the snow + */ + public void setSnow(Snow snow) { + this.snow = snow; + } + + /** + * Gets clouds. + * + * @return the clouds + */ + public Clouds getClouds() { + return clouds; + } + + /** + * Sets clouds. + * + * @param clouds the clouds + */ + public void setClouds(Clouds clouds) { + this.clouds = clouds; + } + + /** + * Gets forecast time iso. + * + * @return the forecast time iso + */ + public String getForecastTimeISO() { + return forecastTimeISO; + } + + /** + * Sets forecast time iso. + * + * @param forecastTimeISO the forecast time iso + */ + public void setForecastTimeISO(String forecastTimeISO) { + this.forecastTimeISO = forecastTimeISO; + } + + /** + * Gets day time. + * + * @return the day time + */ + public DayTime getDayTime() { + return dayTime; + } + + /** + * Sets day time. + * + * @param dayTime the day time + */ + public void setDayTime(DayTime dayTime) { + this.dayTime = dayTime; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + WeatherForecast that = (WeatherForecast) o; + return Objects.equals(state, that.state) && + Objects.equals(description, that.description) && + Objects.equals(weatherIconUrl, that.weatherIconUrl) && + Objects.equals(forecastTime, that.forecastTime) && + Objects.equals(temperature, that.temperature) && + Objects.equals(atmosphericPressure, that.atmosphericPressure) && + Objects.equals(humidity, that.humidity) && + Objects.equals(wind, that.wind) && + Objects.equals(rain, that.rain) && + Objects.equals(snow, that.snow) && + Objects.equals(clouds, that.clouds) && + Objects.equals(forecastTimeISO, that.forecastTimeISO) && + dayTime == that.dayTime; + } + + @Override + public int hashCode() { + return Objects.hash(state, description, weatherIconUrl, forecastTime, temperature, atmosphericPressure, humidity, wind, rain, snow, clouds, forecastTimeISO, dayTime); + } + + @Override + public String toString() { + final StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("Timestamp: "); + stringBuilder.append(forecastTimeISO); + stringBuilder.append(", Weather: "); + stringBuilder.append(description); + if (temperature != null) { + stringBuilder.append(", "); + stringBuilder.append(temperature.getValue()); + stringBuilder.append(' '); + stringBuilder.append(temperature.getUnit()); + } + if (atmosphericPressure != null) { + stringBuilder.append(", "); + stringBuilder.append(atmosphericPressure.getValue()); + stringBuilder.append(' '); + stringBuilder.append(atmosphericPressure.getUnit()); + } + if (clouds != null) { + stringBuilder.append(", "); + stringBuilder.append(clouds.toString()); + } + if (rain != null) { + stringBuilder.append(", Rain: "); + stringBuilder.append(rain.getThreeHourRainLevel()); + stringBuilder.append(' '); + stringBuilder.append(rain.getUnit()); + } + if (snow != null) { + stringBuilder.append(", Snow: "); + stringBuilder.append(snow.getThreeHourSnowLevel()); + stringBuilder.append(' '); + stringBuilder.append(snow.getUnit()); + } + return stringBuilder.toString(); + } +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/Wind.java b/src/main/java/com/github/prominence/openweathermap/api/model/forecast/Wind.java similarity index 88% rename from src/main/java/com/github/prominence/openweathermap/api/model/Wind.java rename to src/main/java/com/github/prominence/openweathermap/api/model/forecast/Wind.java index 4814161..d54af6d 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/model/Wind.java +++ b/src/main/java/com/github/prominence/openweathermap/api/model/forecast/Wind.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,15 +20,14 @@ * SOFTWARE. */ -package com.github.prominence.openweathermap.api.model; +package com.github.prominence.openweathermap.api.model.forecast; import java.util.Objects; /** - * The type Wind. + * Represents wind information. */ public class Wind { - private double speed; private Double degrees; private String unit; @@ -39,15 +38,25 @@ public class Wind { * @param speed the speed * @param unit the unitSystem */ - public Wind(double speed, String unit) { + private Wind(double speed, String unit) { + this.speed = speed; + this.unit = unit; + } + + /** + * Creates {@link Wind} object with correctness check + * @param speed the wind + * @param unit the unitSystem + * @return created wind object + */ + public static Wind withValue(double speed, String unit) { if (speed < 0) { throw new IllegalArgumentException("Wind speed value must be in positive or zero."); } if (unit == null) { throw new IllegalArgumentException("Unit must be set."); } - this.speed = speed; - this.unit = unit; + return new Wind(speed, unit); } /** diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/Location.java b/src/main/java/com/github/prominence/openweathermap/api/model/weather/Location.java similarity index 70% rename from src/main/java/com/github/prominence/openweathermap/api/model/Location.java rename to src/main/java/com/github/prominence/openweathermap/api/model/weather/Location.java index 3639dcd..0a8cbea 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/model/Location.java +++ b/src/main/java/com/github/prominence/openweathermap/api/model/weather/Location.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,14 +20,18 @@ * SOFTWARE. */ -package com.github.prominence.openweathermap.api.model; +package com.github.prominence.openweathermap.api.model.weather; + +import com.github.prominence.openweathermap.api.model.Coordinate; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.util.Objects; +/** + * Represents location information. + */ public class Location { - private int id; private String name; private String countryCode; @@ -38,66 +42,132 @@ public class Location { private Coordinate coordinate; - public Location(int id, String name) { - if (name == null) { - throw new IllegalArgumentException("Name must be set."); - } + private Location(int id, String name) { this.id = id; this.name = name; } + /** + * Creates {@link Location} object with correctness check. + * @param id location id + * @param name location name + * @return location object + */ + public static Location withValues(int id, String name) { + if (name == null) { + throw new IllegalArgumentException("Name must be set."); + } + return new Location(id, name); + } + + /** + * Returns ID. + * @return location ID + */ public int getId() { return id; } + /** + * Sets location ID. + * @param id location id + */ public void setId(int id) { this.id = id; } + /** + * Returns location name. + * @return location name + */ public String getName() { return name; } + /** + * Sets location name. + * @param name location name + */ public void setName(String name) { this.name = name; } + /** + * Returns country code. + * @return location country code + */ public String getCountryCode() { return countryCode; } + /** + * Sets location country code. + * @param countryCode location country code + */ public void setCountryCode(String countryCode) { this.countryCode = countryCode; } + /** + * Returns location sunrise time. + * @return sunrise time + */ public LocalDateTime getSunrise() { return sunrise; } + /** + * Sets location sunrise time. + * @param sunrise sunrise time + */ public void setSunrise(LocalDateTime sunrise) { this.sunrise = sunrise; } + /** + * Returns location sunset time. + * @return sunset time + */ public LocalDateTime getSunset() { return sunset; } + /** + * Sets location sunset time. + * @param sunset sunset time + */ public void setSunset(LocalDateTime sunset) { this.sunset = sunset; } + /** + * Returns location timezone offset. + * @return timezone offset + */ public ZoneOffset getZoneOffset() { return zoneOffset; } + /** + * Sets location timezone offset. + * @param zoneOffset timezone offset + */ public void setZoneOffset(ZoneOffset zoneOffset) { this.zoneOffset = zoneOffset; } + /** + * Returns location coordinates. + * @return location coordinates. + */ public Coordinate getCoordinate() { return coordinate; } + /** + * Sets location coordinates. + * @param coordinate location coordinates + */ public void setCoordinate(Coordinate coordinate) { this.coordinate = coordinate; } diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/weather/Rain.java b/src/main/java/com/github/prominence/openweathermap/api/model/weather/Rain.java new file mode 100644 index 0000000..78be760 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/model/weather/Rain.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2021 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.weather; + +import java.util.Objects; + +/** + * Represents rain information. + */ +public class Rain { + private static final String DEFAULT_UNIT = "mm"; + + private Double oneHourRainLevel; + private Double threeHourRainLevel; + + private Rain() { + } + + /** + * Creates {@link Rain} object with correctness check. + * + * @param oneHourRainLevel 1-hour rain level value + * @return rain object. + */ + public static Rain withOneHourLevelValue(double oneHourRainLevel) { + Rain rain = new Rain(); + rain.setOneHourRainLevel(oneHourRainLevel); + return rain; + } + + /** + * Creates {@link Rain} object with correctness check. + * + * @param threeHourRainLevel 3-hour rain level value + * @return rain object. + */ + public static Rain withThreeHourLevelValue(double threeHourRainLevel) { + Rain rain = new Rain(); + rain.setThreeHourRainLevel(threeHourRainLevel); + return rain; + } + + /** + * Creates {@link Rain} object with correctness check. + * + * @param oneHourRainLevel the one hour rain level + * @param threeHourRainLevel the three hour rain level + * @return the rain + */ + public static Rain withValues(double oneHourRainLevel, double threeHourRainLevel) { + Rain rain = new Rain(); + rain.setOneHourRainLevel(oneHourRainLevel); + rain.setThreeHourRainLevel(threeHourRainLevel); + return rain; + } + + /** + * Gets one hour rain level. + * + * @return the one hour rain level + */ + public Double getOneHourRainLevel() { + return oneHourRainLevel; + } + + /** + * Sets one hour rain level. + * + * @param oneHourRainLevel the one hour rain level + */ + public void setOneHourRainLevel(double oneHourRainLevel) { + if (oneHourRainLevel < 0) { + throw new IllegalArgumentException("Rain level value cannot be negative."); + } + this.oneHourRainLevel = oneHourRainLevel; + } + + /** + * Gets three hour rain level. + * + * @return the three hour rain level + */ + public Double getThreeHourRainLevel() { + return threeHourRainLevel; + } + + /** + * Sets three hour rain level. + * + * @param threeHourRainLevel the three hour rain level + */ + public void setThreeHourRainLevel(double threeHourRainLevel) { + if (threeHourRainLevel < 0) { + throw new IllegalArgumentException("Rain level value cannot be negative."); + } + this.threeHourRainLevel = threeHourRainLevel; + } + + /** + * Gets unit. + * + * @return the unit + */ + public String getUnit() { + return DEFAULT_UNIT; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Rain)) return false; + Rain rain = (Rain) o; + return Objects.equals(oneHourRainLevel, rain.oneHourRainLevel) && + Objects.equals(threeHourRainLevel, rain.threeHourRainLevel); + } + + @Override + public int hashCode() { + return Objects.hash(oneHourRainLevel, threeHourRainLevel); + } + + @Override + public String toString() { + StringBuilder snowString = new StringBuilder(); + if (oneHourRainLevel != null) { + snowString.append("1-hour rain level: "); + snowString.append(oneHourRainLevel); + snowString.append(getUnit()); + } + if (threeHourRainLevel != null) { + if (oneHourRainLevel != null) { + snowString.append(", "); + } + snowString.append("3-hours rain level: "); + snowString.append(threeHourRainLevel); + snowString.append(getUnit()); + } + return snowString.toString(); + } +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/weather/Snow.java b/src/main/java/com/github/prominence/openweathermap/api/model/weather/Snow.java new file mode 100644 index 0000000..66991fd --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/model/weather/Snow.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2021 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.weather; + +import java.util.Objects; + +/** + * Represents snow information. + */ +public class Snow { + private static final String DEFAULT_UNIT = "mm"; + + private Double oneHourSnowLevel; + private Double threeHourSnowLevel; + + private Snow() { + } + + /** + * Creates {@link Snow} object with correctness check. + * + * @param oneHourSnowLevel 1-hour snow level value + * @return snow object. + */ + public static Snow withOneHourLevelValue(double oneHourSnowLevel) { + Snow snow = new Snow(); + snow.setOneHourSnowLevel(oneHourSnowLevel); + return snow; + } + + /** + * Creates {@link Snow} object with correctness check. + * + * @param threeHourSnowLevel 3-hour snow level value + * @return snow object. + */ + public static Snow withThreeHourLevelValue(double threeHourSnowLevel) { + Snow snow = new Snow(); + snow.setThreeHourSnowLevel(threeHourSnowLevel); + return snow; + } + + /** + * Creates {@link Snow} object with correctness check. + * + * @param oneHourSnowLevel the one hour snow level + * @param threeHourSnowLevel the three hour snow level + * @return the snow + */ + public static Snow withValues(double oneHourSnowLevel, double threeHourSnowLevel) { + Snow snow = new Snow(); + snow.setOneHourSnowLevel(oneHourSnowLevel); + snow.setThreeHourSnowLevel(threeHourSnowLevel); + return snow; + } + + /** + * Gets one hour snow level. + * + * @return the one hour snow level + */ + public Double getOneHourSnowLevel() { + return oneHourSnowLevel; + } + + /** + * Sets one hour snow level. + * + * @param oneHourSnowLevel the one hour snow level + */ + public void setOneHourSnowLevel(double oneHourSnowLevel) { + if (oneHourSnowLevel < 0) { + throw new IllegalArgumentException("Snow level value cannot be negative."); + } + this.oneHourSnowLevel = oneHourSnowLevel; + } + + /** + * Gets three hour snow level. + * + * @return the three hour snow level + */ + public Double getThreeHourSnowLevel() { + return threeHourSnowLevel; + } + + /** + * Sets three hour snow level. + * + * @param threeHourSnowLevel the three hour snow level + */ + public void setThreeHourSnowLevel(double threeHourSnowLevel) { + if (threeHourSnowLevel < 0) { + throw new IllegalArgumentException("Snow level value cannot be negative."); + } + this.threeHourSnowLevel = threeHourSnowLevel; + } + + /** + * Gets unit. + * + * @return the unit + */ + public String getUnit() { + return DEFAULT_UNIT; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Snow)) return false; + Snow snow = (Snow) o; + return Objects.equals(oneHourSnowLevel, snow.oneHourSnowLevel) && + Objects.equals(threeHourSnowLevel, snow.threeHourSnowLevel); + } + + @Override + public int hashCode() { + return Objects.hash(oneHourSnowLevel, threeHourSnowLevel); + } + + @Override + public String toString() { + StringBuilder snowString = new StringBuilder(); + if (oneHourSnowLevel != null) { + snowString.append("1-hour snow level: "); + snowString.append(oneHourSnowLevel); + snowString.append(getUnit()); + } + if (threeHourSnowLevel != null) { + if (oneHourSnowLevel != null) { + snowString.append(", "); + } + snowString.append("3-hours snow level: "); + snowString.append(threeHourSnowLevel); + snowString.append(getUnit()); + } + return snowString.toString(); + } +} 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/Weather.java similarity index 64% rename from src/main/java/com/github/prominence/openweathermap/api/model/Weather.java rename to src/main/java/com/github/prominence/openweathermap/api/model/weather/Weather.java index f4bcba0..b2f5ff0 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/model/Weather.java +++ b/src/main/java/com/github/prominence/openweathermap/api/model/weather/Weather.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,21 +20,27 @@ * SOFTWARE. */ -package com.github.prominence.openweathermap.api.model; +package com.github.prominence.openweathermap.api.model.weather; + +import com.github.prominence.openweathermap.api.model.*; import java.time.LocalDateTime; import java.util.Objects; +/** + * Represents weather information. + */ public class Weather { - private String state; private String description; private String weatherIconUrl; - private LocalDateTime requestedOn; + + private LocalDateTime calculatedOn; private Temperature temperature; - private Pressure pressure; + private AtmosphericPressure atmosphericPressure; private Humidity humidity; + private Wind wind; private Rain rain; private Snow snow; @@ -42,21 +48,42 @@ public class Weather { private Location location; - public Weather(String state, String description) { + private Weather(String state, String description) { + this.state = state; + this.description = description; + } + + /** + * For value weather. + * + * @param state the state + * @param description the description + * @return the weather + */ + public static Weather forValue(String state, String description) { if (state == null) { throw new IllegalArgumentException("State must be set."); } if (description == null) { throw new IllegalArgumentException("Description must be set."); } - this.state = state; - this.description = description; + return new Weather(state, description); } + /** + * Gets state. + * + * @return the state + */ public String getState() { return state; } + /** + * Sets state. + * + * @param state the state + */ public void setState(String state) { if (state == null) { throw new IllegalArgumentException("State must be set."); @@ -64,10 +91,20 @@ public class Weather { this.state = state; } + /** + * Gets description. + * + * @return the description + */ public String getDescription() { return description; } + /** + * Sets description. + * + * @param description the description + */ public void setDescription(String description) { if (description == null) { throw new IllegalArgumentException("Description must be set."); @@ -75,82 +112,182 @@ public class Weather { this.description = description; } + /** + * Gets weather icon url. + * + * @return the weather icon url + */ public String getWeatherIconUrl() { return weatherIconUrl; } + /** + * Sets weather icon url. + * + * @param weatherIconUrl the weather icon url + */ public void setWeatherIconUrl(String weatherIconUrl) { this.weatherIconUrl = weatherIconUrl; } - public LocalDateTime getRequestedOn() { - return requestedOn; + /** + * Gets calculated on. + * + * @return the calculated on + */ + public LocalDateTime getCalculatedOn() { + return calculatedOn; } - public void setRequestedOn(LocalDateTime requestedOn) { - this.requestedOn = requestedOn; + /** + * Sets calculated on. + * + * @param calculatedOn the calculated on + */ + public void setCalculatedOn(LocalDateTime calculatedOn) { + this.calculatedOn = calculatedOn; } + /** + * Gets temperature. + * + * @return the temperature + */ public Temperature getTemperature() { return temperature; } + /** + * Sets temperature. + * + * @param temperature the temperature + */ public void setTemperature(Temperature temperature) { this.temperature = temperature; } - public Pressure getPressure() { - return pressure; + /** + * Gets atmospheric pressure. + * + * @return the atmospheric pressure + */ + public AtmosphericPressure getAtmosphericPressure() { + return atmosphericPressure; } - public void setPressure(Pressure pressure) { - this.pressure = pressure; + /** + * Sets atmospheric pressure. + * + * @param atmosphericPressure the atmospheric pressure + */ + public void setAtmosphericPressure(AtmosphericPressure atmosphericPressure) { + this.atmosphericPressure = atmosphericPressure; } + /** + * Gets humidity. + * + * @return the humidity + */ public Humidity getHumidity() { return humidity; } + /** + * Sets humidity. + * + * @param humidity the humidity + */ public void setHumidity(Humidity humidity) { this.humidity = humidity; } + /** + * Gets wind. + * + * @return the wind + */ public Wind getWind() { return wind; } + /** + * Sets wind. + * + * @param wind the wind + */ public void setWind(Wind wind) { this.wind = wind; } + /** + * Gets rain. + * + * @return the rain + */ public Rain getRain() { return rain; } + /** + * Sets rain. + * + * @param rain the rain + */ public void setRain(Rain rain) { this.rain = rain; } + /** + * Gets snow. + * + * @return the snow + */ public Snow getSnow() { return snow; } + /** + * Sets snow. + * + * @param snow the snow + */ public void setSnow(Snow snow) { this.snow = snow; } + /** + * Gets clouds. + * + * @return the clouds + */ public Clouds getClouds() { return clouds; } + /** + * Sets clouds. + * + * @param clouds the clouds + */ public void setClouds(Clouds clouds) { this.clouds = clouds; } + /** + * Gets location. + * + * @return the location + */ public Location getLocation() { return location; } + /** + * Sets location. + * + * @param location the location + */ public void setLocation(Location location) { this.location = location; } @@ -163,9 +300,9 @@ public class Weather { return Objects.equals(state, weather.state) && Objects.equals(description, weather.description) && Objects.equals(weatherIconUrl, weather.weatherIconUrl) && - Objects.equals(requestedOn, weather.requestedOn) && + Objects.equals(calculatedOn, weather.calculatedOn) && Objects.equals(temperature, weather.temperature) && - Objects.equals(pressure, weather.pressure) && + Objects.equals(atmosphericPressure, weather.atmosphericPressure) && Objects.equals(humidity, weather.humidity) && Objects.equals(wind, weather.wind) && Objects.equals(rain, weather.rain) && @@ -176,7 +313,7 @@ public class Weather { @Override public int hashCode() { - return Objects.hash(state, description, weatherIconUrl, requestedOn, temperature, pressure, humidity, wind, rain, snow, clouds, location); + return Objects.hash(state, description, weatherIconUrl, calculatedOn, temperature, atmosphericPressure, humidity, wind, rain, snow, clouds, location); } @Override @@ -201,11 +338,11 @@ public class Weather { stringBuilder.append(' '); stringBuilder.append(temperature.getUnit()); } - if (pressure != null) { + if (atmosphericPressure != null) { stringBuilder.append(", "); - stringBuilder.append(pressure.getValue()); + stringBuilder.append(atmosphericPressure.getValue()); stringBuilder.append(' '); - stringBuilder.append(pressure.getUnit()); + stringBuilder.append(atmosphericPressure.getUnit()); } if (clouds != null) { stringBuilder.append(", "); @@ -224,6 +361,5 @@ public class Weather { stringBuilder.append(snow.getUnit()); } return stringBuilder.toString(); - } } diff --git a/src/main/java/com/github/prominence/openweathermap/api/model/weather/Wind.java b/src/main/java/com/github/prominence/openweathermap/api/model/weather/Wind.java new file mode 100644 index 0000000..3d9b4a8 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/model/weather/Wind.java @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2021 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.weather; + +import java.util.Objects; + +/** + * The type Wind. + */ +public class Wind { + private double speed; + private Double degrees; + private Double gust; + private String unit; + + /** + * Instantiates a new Wind. + * + * @param speed the speed + * @param unit the unitSystem + */ + private Wind(double speed, String unit) { + this.speed = speed; + this.unit = unit; + } + + /** + * Creates {@link Wind} object with correctness check. + * @param speed the speed + * @param unit the unitSystem + * @return wind object + */ + public static Wind withValue(double speed, String unit) { + if (speed < 0) { + throw new IllegalArgumentException("Wind speed value must be in positive or zero."); + } + if (unit == null) { + throw new IllegalArgumentException("Unit must be set."); + } + return new Wind(speed, unit); + } + + /** + * Gets speed. + * + * @return the speed + */ + public double getSpeed() { + return speed; + } + + /** + * Sets speed. + * + * @param speed the speed + */ + public void setSpeed(double speed) { + if (speed < 0) { + throw new IllegalArgumentException("Wind speed value must be in positive or zero."); + } + this.speed = speed; + } + + /** + * Gets gust value. + * @return the gust + */ + public Double getGust() { + return gust; + } + + /** + * Sets gust value. + * @param gust the gust. + */ + public void setGust(double gust) { + if (gust < 0) { + throw new IllegalArgumentException("Gust value must be positive or zero."); + } + this.gust = gust; + } + + /** + * Gets degrees. + * + * @return the degrees + */ + public Double getDegrees() { + return degrees; + } + + /** + * Sets degrees. + * + * @param degrees the degrees + */ + public void setDegrees(double degrees) { + if (degrees < 0 || degrees > 360) { + throw new IllegalArgumentException("Wind direction value must be in [0, 360] range."); + } + this.degrees = degrees; + } + + /** + * Gets unitSystem. + * + * @return the unitSystem + */ + public String getUnit() { + return unit; + } + + /** + * Sets unitSystem. + * + * @param unit the unitSystem + */ + public void setUnit(String unit) { + if (unit == null) { + throw new IllegalArgumentException("Unit must be set."); + } + 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 && + Objects.equals(degrees, wind.degrees) && + Objects.equals(gust, wind.gust) && + Objects.equals(unit, wind.unit); + } + + @Override + public int hashCode() { + return Objects.hash(speed, degrees, gust, unit); + } + + @Override + public String toString() { + String output = "Wind speed: " + speed + " " + unit + + ", degrees: " + degrees; + if (gust != null) { + output += ", Gust: " + gust + " " + unit; + } + return output; + } +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/SingleResultCurrentWeatherAsyncRequestTerminator.java b/src/main/java/com/github/prominence/openweathermap/api/request/AsyncRequestTerminator.java similarity index 77% rename from src/main/java/com/github/prominence/openweathermap/api/SingleResultCurrentWeatherAsyncRequestTerminator.java rename to src/main/java/com/github/prominence/openweathermap/api/request/AsyncRequestTerminator.java index 491cb12..099f958 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/SingleResultCurrentWeatherAsyncRequestTerminator.java +++ b/src/main/java/com/github/prominence/openweathermap/api/request/AsyncRequestTerminator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,11 +20,15 @@ * SOFTWARE. */ -package com.github.prominence.openweathermap.api; - -import com.github.prominence.openweathermap.api.model.Weather; +package com.github.prominence.openweathermap.api.request; import java.util.concurrent.CompletableFuture; -public interface SingleResultCurrentWeatherAsyncRequestTerminator extends CurrentWeatherRequestTerminator, CompletableFuture> { +/** + * The interface Async request terminator. + * + * @param the type parameter + * @param the type parameter + */ +public interface AsyncRequestTerminator extends RequestTerminator, CompletableFuture> { } diff --git a/src/main/java/com/github/prominence/openweathermap/api/RequestCustomizer.java b/src/main/java/com/github/prominence/openweathermap/api/request/RequestCustomizer.java similarity index 75% rename from src/main/java/com/github/prominence/openweathermap/api/RequestCustomizer.java rename to src/main/java/com/github/prominence/openweathermap/api/request/RequestCustomizer.java index eb55271..daf544e 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/RequestCustomizer.java +++ b/src/main/java/com/github/prominence/openweathermap/api/request/RequestCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,31 @@ * SOFTWARE. */ -package com.github.prominence.openweathermap.api; +package com.github.prominence.openweathermap.api.request; -import com.github.prominence.openweathermap.api.enums.Accuracy; import com.github.prominence.openweathermap.api.enums.Language; import com.github.prominence.openweathermap.api.enums.UnitSystem; +/** + * The interface Request customizer. + * + * @param the type parameter + */ public interface RequestCustomizer> { - T accuracy(Accuracy accuracy); - + /** + * Customize language. + * + * @param language the language + * @return the request customizer + */ T language(Language language); + /** + * Customize unit system. + * + * @param unitSystem the unit system + * @return the request customizer + */ T unitSystem(UnitSystem unitSystem); } diff --git a/src/main/java/com/github/prominence/openweathermap/api/RequestTerminator.java b/src/main/java/com/github/prominence/openweathermap/api/request/RequestTerminator.java similarity index 75% rename from src/main/java/com/github/prominence/openweathermap/api/RequestTerminator.java rename to src/main/java/com/github/prominence/openweathermap/api/request/RequestTerminator.java index 10e91ad..20a8f97 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/RequestTerminator.java +++ b/src/main/java/com/github/prominence/openweathermap/api/request/RequestTerminator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,11 +20,27 @@ * SOFTWARE. */ -package com.github.prominence.openweathermap.api; +package com.github.prominence.openweathermap.api.request; +/** + * The interface Request terminator. + * + * @param the type parameter + * @param the type parameter + */ public interface RequestTerminator { + /** + * Java object response format. + * + * @return the java object + */ T asJava(); + /** + * JSON response format. + * + * @return the JSON string + */ S asJSON(); } diff --git a/src/main/java/com/github/prominence/openweathermap/api/impl/RequestUrlBuilder.java b/src/main/java/com/github/prominence/openweathermap/api/request/RequestUrlBuilder.java similarity index 52% rename from src/main/java/com/github/prominence/openweathermap/api/impl/RequestUrlBuilder.java rename to src/main/java/com/github/prominence/openweathermap/api/request/RequestUrlBuilder.java index 34e4e28..378bfca 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/impl/RequestUrlBuilder.java +++ b/src/main/java/com/github/prominence/openweathermap/api/request/RequestUrlBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,30 +20,74 @@ * SOFTWARE. */ -package com.github.prominence.openweathermap.api.impl; +package com.github.prominence.openweathermap.api.request; + +import com.github.prominence.openweathermap.api.enums.Language; +import com.github.prominence.openweathermap.api.enums.UnitSystem; import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; +/** + * The type Request url builder. + */ public class RequestUrlBuilder { - private StringBuilder builder = new StringBuilder(); - private Map requestParameters = new HashMap<>(); + private static final String API_KEY_PARAM_NAME = "appid"; - public RequestUrlBuilder(String baseUrl) { - builder.append(baseUrl); + private final StringBuilder builder = new StringBuilder("http://api.openweathermap.org/data/2.5/"); + private final Map requestParameters = new HashMap<>(); + + /** + * Instantiates a new Request url builder. + * + * @param key the API key + */ + public RequestUrlBuilder(String key) { + requestParameters.put(API_KEY_PARAM_NAME, key); } - void append(String value) { + /** + * Appends value. + * + * @param value the value + */ + public void append(String value) { builder.append(value); } + /** + * Adds request parameter. + * + * @param key the key + * @param value the value + */ public void addRequestParameter(String key, Object value) { requestParameters.put(key, value); } - String buildUrl() { + /** + * Applies customization. + * + * @param language the language + * @param unitSystem the unit system + */ + public void applyCustomization(Language language, UnitSystem unitSystem) { + if (language != null) { + addRequestParameter("lang", language.getValue()); + } + if (unitSystem != null && unitSystem != UnitSystem.STANDARD) { + addRequestParameter("units", unitSystem.getValue()); + } + } + + /** + * Builds url string. + * + * @return the string + */ + public String buildUrl() { final String joinedParameters = requestParameters.entrySet().stream() .map(entry -> entry.getKey() + "=" + entry.getValue()) .collect(Collectors.joining("&")); diff --git a/src/main/java/com/github/prominence/openweathermap/api/request/forecast/free/FiveDayThreeHourStepForecastAsyncRequestTerminator.java b/src/main/java/com/github/prominence/openweathermap/api/request/forecast/free/FiveDayThreeHourStepForecastAsyncRequestTerminator.java new file mode 100644 index 0000000..a2eeb14 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/request/forecast/free/FiveDayThreeHourStepForecastAsyncRequestTerminator.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021 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.request.forecast.free; + +import com.github.prominence.openweathermap.api.model.forecast.Forecast; +import com.github.prominence.openweathermap.api.request.AsyncRequestTerminator; + +import java.util.concurrent.CompletableFuture; + + +/** + * The forecast async request terminator interface. + */ +public interface FiveDayThreeHourStepForecastAsyncRequestTerminator extends AsyncRequestTerminator { + + /** + * XML response format. + * + * @return the completable future + */ + CompletableFuture asXML(); +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/request/forecast/free/FiveDayThreeHourStepForecastAsyncRequestTerminatorImpl.java b/src/main/java/com/github/prominence/openweathermap/api/request/forecast/free/FiveDayThreeHourStepForecastAsyncRequestTerminatorImpl.java new file mode 100644 index 0000000..9806ac7 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/request/forecast/free/FiveDayThreeHourStepForecastAsyncRequestTerminatorImpl.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2021 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.request.forecast.free; + +import com.github.prominence.openweathermap.api.enums.UnitSystem; +import com.github.prominence.openweathermap.api.model.forecast.Forecast; +import com.github.prominence.openweathermap.api.request.RequestUrlBuilder; +import com.github.prominence.openweathermap.api.utils.RequestUtils; + +import java.util.concurrent.CompletableFuture; + +/** + * Async request terminator. + */ +public class FiveDayThreeHourStepForecastAsyncRequestTerminatorImpl implements FiveDayThreeHourStepForecastAsyncRequestTerminator { + + private final RequestUrlBuilder urlBuilder; + private final UnitSystem unitSystem; + + /** + * Instantiates a new async request terminator. + * + * @param urlBuilder the url builder + * @param unitSystem the unit system + */ + FiveDayThreeHourStepForecastAsyncRequestTerminatorImpl(RequestUrlBuilder urlBuilder, UnitSystem unitSystem) { + this.urlBuilder = urlBuilder; + this.unitSystem = unitSystem; + } + + @Override + public CompletableFuture asJava() { + return CompletableFuture.supplyAsync(() -> new FiveDayThreeHourStepForecastResponseMapper(unitSystem).mapToForecast(getRawResponse())); + } + + @Override + public CompletableFuture asJSON() { + return CompletableFuture.supplyAsync(this::getRawResponse); + } + + @Override + public CompletableFuture asXML() { + urlBuilder.addRequestParameter("mode", "xml"); + return CompletableFuture.supplyAsync(this::getRawResponse); + } + + private String getRawResponse() { + return RequestUtils.getResponse(urlBuilder.buildUrl()); + } +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/request/forecast/free/FiveDayThreeHourStepForecastRequestCustomizer.java b/src/main/java/com/github/prominence/openweathermap/api/request/forecast/free/FiveDayThreeHourStepForecastRequestCustomizer.java new file mode 100644 index 0000000..c6b10c1 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/request/forecast/free/FiveDayThreeHourStepForecastRequestCustomizer.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021 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.request.forecast.free; + +import com.github.prominence.openweathermap.api.request.RequestCustomizer; + +/** + * The forecast request customizer interface. + */ +public interface FiveDayThreeHourStepForecastRequestCustomizer extends RequestCustomizer { + + /** + * Count customizer. + * + * @param numberOfTimestamps the number of timestamps + * @return forecast request customizer + */ + FiveDayThreeHourStepForecastRequestCustomizer count(int numberOfTimestamps); + + /** + * Retrieve forecast request terminator. + * + * @return forecast request terminator + */ + FiveDayThreeHourStepForecastRequestTerminator retrieve(); + + /** + * Retrieve forecast async request terminator. + * + * @return forecast async request terminator + */ + FiveDayThreeHourStepForecastAsyncRequestTerminator retrieveAsync(); +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/request/forecast/free/FiveDayThreeHourStepForecastRequestCustomizerImpl.java b/src/main/java/com/github/prominence/openweathermap/api/request/forecast/free/FiveDayThreeHourStepForecastRequestCustomizerImpl.java new file mode 100644 index 0000000..ec462b6 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/request/forecast/free/FiveDayThreeHourStepForecastRequestCustomizerImpl.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2021 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.request.forecast.free; + +import com.github.prominence.openweathermap.api.enums.Language; +import com.github.prominence.openweathermap.api.enums.UnitSystem; +import com.github.prominence.openweathermap.api.request.RequestUrlBuilder; + +/** + * The forecast request customizer. + */ +public class FiveDayThreeHourStepForecastRequestCustomizerImpl implements FiveDayThreeHourStepForecastRequestCustomizer { + + private final RequestUrlBuilder urlBuilder; + + private Language language; + private UnitSystem unitSystem = UnitSystem.STANDARD; + private int count = -1; + + /** + * Instantiates a new forecast request customizer. + * + * @param urlBuilder the url builder + */ + FiveDayThreeHourStepForecastRequestCustomizerImpl(RequestUrlBuilder urlBuilder) { + this.urlBuilder = urlBuilder; + } + + @Override + public FiveDayThreeHourStepForecastRequestCustomizer language(Language language) { + this.language = language; + return this; + } + + @Override + public FiveDayThreeHourStepForecastRequestCustomizer unitSystem(UnitSystem unitSystem) { + this.unitSystem = unitSystem; + return this; + } + + @Override + public FiveDayThreeHourStepForecastRequestCustomizer count(int numberOfTimestamps) { + count = numberOfTimestamps; + return this; + } + + @Override + public FiveDayThreeHourStepForecastRequestTerminator retrieve() { + urlBuilder.applyCustomization(language, unitSystem); + urlBuilder.addRequestParameter("cnt", count); + return new FiveDayThreeHourStepForecastRequestTerminatorImpl(urlBuilder, unitSystem); + } + + @Override + public FiveDayThreeHourStepForecastAsyncRequestTerminator retrieveAsync() { + urlBuilder.applyCustomization(language, unitSystem); + urlBuilder.addRequestParameter("cnt", count); + return new FiveDayThreeHourStepForecastAsyncRequestTerminatorImpl(urlBuilder, unitSystem); + } +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/ResponseMapper.java b/src/main/java/com/github/prominence/openweathermap/api/request/forecast/free/FiveDayThreeHourStepForecastRequestTerminator.java similarity index 67% rename from src/main/java/com/github/prominence/openweathermap/api/ResponseMapper.java rename to src/main/java/com/github/prominence/openweathermap/api/request/forecast/free/FiveDayThreeHourStepForecastRequestTerminator.java index 38ce552..0f07243 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/ResponseMapper.java +++ b/src/main/java/com/github/prominence/openweathermap/api/request/forecast/free/FiveDayThreeHourStepForecastRequestTerminator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,21 @@ * SOFTWARE. */ -package com.github.prominence.openweathermap.api; +package com.github.prominence.openweathermap.api.request.forecast.free; -import java.util.List; +import com.github.prominence.openweathermap.api.model.forecast.Forecast; +import com.github.prominence.openweathermap.api.request.RequestTerminator; -public interface ResponseMapper { - T getSingle(String json); +/** + * The forecast request terminator interface. + */ +public interface FiveDayThreeHourStepForecastRequestTerminator extends RequestTerminator { - List getList(String json); + /** + * XML response format. + * + * @return the XML string + */ + String asXML(); } diff --git a/src/main/java/com/github/prominence/openweathermap/api/request/forecast/free/FiveDayThreeHourStepForecastRequestTerminatorImpl.java b/src/main/java/com/github/prominence/openweathermap/api/request/forecast/free/FiveDayThreeHourStepForecastRequestTerminatorImpl.java new file mode 100644 index 0000000..70802cd --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/request/forecast/free/FiveDayThreeHourStepForecastRequestTerminatorImpl.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2021 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.request.forecast.free; + +import com.github.prominence.openweathermap.api.enums.UnitSystem; +import com.github.prominence.openweathermap.api.model.forecast.Forecast; +import com.github.prominence.openweathermap.api.request.RequestUrlBuilder; +import com.github.prominence.openweathermap.api.utils.RequestUtils; + +/** + * The forecast request terminator. + */ +public class FiveDayThreeHourStepForecastRequestTerminatorImpl implements FiveDayThreeHourStepForecastRequestTerminator { + + private final RequestUrlBuilder urlBuilder; + private final UnitSystem unitSystem; + + /** + * Instantiates a new forecast request terminator. + * + * @param urlBuilder the url builder + * @param unitSystem the unit system + */ + FiveDayThreeHourStepForecastRequestTerminatorImpl(RequestUrlBuilder urlBuilder, UnitSystem unitSystem) { + this.urlBuilder = urlBuilder; + this.unitSystem = unitSystem; + } + + @Override + public Forecast asJava() { + return new FiveDayThreeHourStepForecastResponseMapper(unitSystem).mapToForecast(getRawResponse()); + } + + @Override + public String asJSON() { + return getRawResponse(); + } + + @Override + public String asXML() { + urlBuilder.addRequestParameter("mode", "xml"); + return getRawResponse(); + } + + private String getRawResponse() { + return RequestUtils.getResponse(urlBuilder.buildUrl()); + } +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/request/forecast/free/FiveDayThreeHourStepForecastRequester.java b/src/main/java/com/github/prominence/openweathermap/api/request/forecast/free/FiveDayThreeHourStepForecastRequester.java new file mode 100644 index 0000000..a19211f --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/request/forecast/free/FiveDayThreeHourStepForecastRequester.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2021 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.request.forecast.free; + +import com.github.prominence.openweathermap.api.model.Coordinate; + +/** + * An interface for API methods. + */ +public interface FiveDayThreeHourStepForecastRequester { + + /** + * By city name forecast request customizer. + * + * @param cityName the city name + * @return the forecast request customizer + */ + FiveDayThreeHourStepForecastRequestCustomizer byCityName(String cityName); + + /** + * By city name forecast request customizer. + * + * @param cityName the city name + * @param stateCode the state code + * @return the forecast request customizer + */ + FiveDayThreeHourStepForecastRequestCustomizer byCityName(String cityName, String stateCode); + + /** + * By city name forecast request customizer. + * + * @param cityName the city name + * @param stateCode the state code + * @param countryCode the country code + * @return the forecast request customizer + */ + FiveDayThreeHourStepForecastRequestCustomizer byCityName(String cityName, String stateCode, String countryCode); + + /** + * By city id forecast request customizer. + * + * @param cityId the city id + * @return the forecast request customizer + */ + FiveDayThreeHourStepForecastRequestCustomizer byCityId(long cityId); + + /** + * By coordinate forecast request customizer. + * + * @param coordinate the coordinate + * @return the forecast request customizer + */ + FiveDayThreeHourStepForecastRequestCustomizer byCoordinate(Coordinate coordinate); + + /** + * By zip code and country forecast request customizer. + * + * @param zipCode the zip code + * @param countryCode the country code + * @return the forecast request customizer + */ + FiveDayThreeHourStepForecastRequestCustomizer byZipCodeAndCountry(String zipCode, String countryCode); + + /** + * By zip code in USA forecast request customizer. + * + * @param zipCode the zip code + * @return the forecast request customizer + */ + FiveDayThreeHourStepForecastRequestCustomizer byZipCodeInUSA(String zipCode); +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/request/forecast/free/FiveDayThreeHourStepForecastRequesterImpl.java b/src/main/java/com/github/prominence/openweathermap/api/request/forecast/free/FiveDayThreeHourStepForecastRequesterImpl.java new file mode 100644 index 0000000..c0479b2 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/request/forecast/free/FiveDayThreeHourStepForecastRequesterImpl.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2021 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.request.forecast.free; + +import com.github.prominence.openweathermap.api.model.Coordinate; +import com.github.prominence.openweathermap.api.request.RequestUrlBuilder; + +/** + * The forecast requester. + */ +public class FiveDayThreeHourStepForecastRequesterImpl implements FiveDayThreeHourStepForecastRequester { + + private final RequestUrlBuilder urlBuilder; + + /** + * Instantiates a new forecast requester. + * + * @param apiKey the api key + */ + public FiveDayThreeHourStepForecastRequesterImpl(String apiKey) { + urlBuilder = new RequestUrlBuilder(apiKey); + urlBuilder.append("forecast"); + } + + @Override + public FiveDayThreeHourStepForecastRequestCustomizer byCityName(String cityName) { + urlBuilder.addRequestParameter("q", cityName); + return new FiveDayThreeHourStepForecastRequestCustomizerImpl(urlBuilder); + } + + @Override + public FiveDayThreeHourStepForecastRequestCustomizer byCityName(String cityName, String stateCode) { + urlBuilder.addRequestParameter("q", cityName + "," + stateCode); + return new FiveDayThreeHourStepForecastRequestCustomizerImpl(urlBuilder); + } + + @Override + public FiveDayThreeHourStepForecastRequestCustomizer byCityName(String cityName, String stateCode, String countryCode) { + urlBuilder.addRequestParameter("q", cityName + "," + stateCode + "," + countryCode); + return new FiveDayThreeHourStepForecastRequestCustomizerImpl(urlBuilder); + } + + @Override + public FiveDayThreeHourStepForecastRequestCustomizer byCityId(long cityId) { + urlBuilder.addRequestParameter("id", cityId); + return new FiveDayThreeHourStepForecastRequestCustomizerImpl(urlBuilder); + } + + @Override + public FiveDayThreeHourStepForecastRequestCustomizer byCoordinate(Coordinate coordinate) { + urlBuilder.addRequestParameter("lat", String.valueOf(coordinate.getLatitude())); + urlBuilder.addRequestParameter("lon", String.valueOf(coordinate.getLongitude())); + return new FiveDayThreeHourStepForecastRequestCustomizerImpl(urlBuilder); + } + + @Override + public FiveDayThreeHourStepForecastRequestCustomizer byZipCodeAndCountry(String zipCode, String countryCode) { + urlBuilder.addRequestParameter("zip", zipCode + "," + countryCode); + return new FiveDayThreeHourStepForecastRequestCustomizerImpl(urlBuilder); + } + + @Override + public FiveDayThreeHourStepForecastRequestCustomizer byZipCodeInUSA(String zipCode) { + urlBuilder.addRequestParameter("zip", zipCode); + return new FiveDayThreeHourStepForecastRequestCustomizerImpl(urlBuilder); + } +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/request/forecast/free/FiveDayThreeHourStepForecastResponseMapper.java b/src/main/java/com/github/prominence/openweathermap/api/request/forecast/free/FiveDayThreeHourStepForecastResponseMapper.java new file mode 100644 index 0000000..8bcf504 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/request/forecast/free/FiveDayThreeHourStepForecastResponseMapper.java @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2021 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.request.forecast.free; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.prominence.openweathermap.api.enums.UnitSystem; +import com.github.prominence.openweathermap.api.model.*; +import com.github.prominence.openweathermap.api.model.forecast.*; +import com.github.prominence.openweathermap.api.model.forecast.Location; +import com.github.prominence.openweathermap.api.model.forecast.Rain; +import com.github.prominence.openweathermap.api.model.forecast.Snow; +import com.github.prominence.openweathermap.api.model.Temperature; + +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(but the real response can differ): + * --- cod Internal parameter + * --- message Internal parameter + * --- cnt A number of timestamps returned in the API response + * --- list + * |- list.dt Time of data forecasted, unix, UTC + * |- list.main + * |- list.main.temp Temperature. Unit Default: Kelvin, Metric: Celsius, Imperial: Fahrenheit. + * |- list.main.feels_like This temperature parameter accounts for the human perception of weather. Unit Default: Kelvin, Metric: Celsius, Imperial: Fahrenheit. + * |- list.main.temp_min Minimum temperature at the moment of calculation. This is minimal forecasted temperature (within large megalopolises and urban areas), use this parameter optionally. Unit Default: Kelvin, Metric: Celsius, Imperial: Fahrenheit. + * |- list.main.temp_max Maximum temperature at the moment of calculation. This is maximal forecasted temperature (within large megalopolises and urban areas), use this parameter optionally. Unit Default: Kelvin, Metric: Celsius, Imperial: Fahrenheit. + * |- list.main.pressure Atmospheric pressure on the sea level by default, hPa + * |- list.main.sea_level Atmospheric pressure on the sea level, hPa + * |- list.main.grnd_level Atmospheric pressure on the ground level, hPa + * |- list.main.humidity Humidity, % + * |- list.main.temp_kf Internal par + * |- list.weather + * |- list.weather.id Weather condition id + * |- list.weather.main Group of weather parameters (Rain, Snow, Extreme etc.) + * |- list.weather.description Weather condition within the group. You can get the output in your language. + * |- list.weather.icon Weather icon id + * |- list.clouds + * |- list.clouds.all Cloudiness, % + * |- list.wind + * |- list.wind.speed Wind speed. Unit Default: meter/sec, Metric: meter/sec, Imperial: miles/hour. + * |- list.wind.deg Wind direction, degrees (meteorological) + * |- list.visibility Average visibility, metres + * |- list.pop Probability of precipitation + * |- list.rain + * |- list.rain.3h Rain volume for last 3 hours, mm + * |- list.snow + * |- list.snow.3h Snow volume for last 3 hours + * |- list.sys + * |- list.sys.pod Part of the day (n - night, d - day) + * |- list.dt_txt Time of data forecasted, ISO, UTC + * --- city + * |- city.id City ID + * |- city.name City name + * |- city.coord + * |- city.coord.lat City geo location, latitude + * |- city.coord.lon City geo location, longitude + * |- city.country Country code (GB, JP etc.) + * |- city.timezone Shift in seconds from UTC + */ +public class FiveDayThreeHourStepForecastResponseMapper { + + private final UnitSystem unitSystem; + + /** + * Instantiates a new forecast response mapper. + * + * @param unitSystem the unit system + */ + public FiveDayThreeHourStepForecastResponseMapper(UnitSystem unitSystem) { + this.unitSystem = unitSystem; + } + + /** + * Maps forecast response into java object. + * + * @param json the json string + * @return the forecast + */ + public Forecast mapToForecast(String json) { + ObjectMapper objectMapper = new ObjectMapper(); + Forecast forecast; + try { + JsonNode root = objectMapper.readTree(json); + forecast = mapToForecast(root); + } catch (IOException e) { + throw new RuntimeException("Cannot parse Forecast response"); + } + + return forecast; + } + + private Forecast mapToForecast(JsonNode root) { + Forecast forecast = new Forecast(); + forecast.setLocation(parseLocation(root.get("city"))); + + List forecasts = new ArrayList<>(root.get("cnt").asInt()); + + JsonNode forecastListNode = root.get("list"); + forecastListNode.forEach(forecastNode -> forecasts.add(parseWeatherForecast(forecastNode))); + + forecast.setWeatherForecasts(forecasts); + + return forecast; + } + + private WeatherForecast parseWeatherForecast(JsonNode rootNode) { + JsonNode weatherNode = rootNode.get("weather").get(0); + WeatherForecast weatherForecast = WeatherForecast.forValue( + weatherNode.get("main").asText(), + weatherNode.get("description").asText() + ); + weatherForecast.setWeatherIconUrl("https://openweathermap.org/img/w/" + weatherNode.get("icon").asText() + ".png"); + + JsonNode mainNode = rootNode.get("main"); + weatherForecast.setTemperature(parseTemperature(mainNode)); + weatherForecast.setAtmosphericPressure(parsePressure(mainNode)); + weatherForecast.setHumidity(parseHumidity(mainNode)); + weatherForecast.setClouds(parseClouds(rootNode)); + weatherForecast.setWind(parseWind(rootNode)); + weatherForecast.setRain(parseRain(rootNode)); + weatherForecast.setSnow(parseSnow(rootNode)); + + JsonNode sysNode = rootNode.get("sys"); + if (sysNode != null) { + weatherForecast.setDayTime("d".equals(sysNode.get("pod").asText()) ? DayTime.DAY : DayTime.NIGHT); + } + + weatherForecast.setForecastTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(rootNode.get("dt").asLong()), TimeZone.getDefault().toZoneId())); + weatherForecast.setForecastTimeISO(rootNode.get("dt_txt").asText()); + + return weatherForecast; + } + + private Temperature parseTemperature(JsonNode rootNode) { + final double tempValue = rootNode.get("temp").asDouble(); + Temperature temperature = Temperature.withValue(tempValue, unitSystem.getTemperatureUnit()); + + final JsonNode tempMaxNode = rootNode.get("temp_max"); + if (tempMaxNode != null) { + temperature.setMaxTemperature(tempMaxNode.asDouble()); + } + final JsonNode tempMinNode = rootNode.get("temp_min"); + if (tempMinNode != null) { + temperature.setMinTemperature(tempMinNode.asDouble()); + } + final JsonNode tempFeelsLike = rootNode.get("fells_like"); + if (tempFeelsLike != null) { + temperature.setFeelsLike(tempFeelsLike.asDouble()); + } + + return temperature; + } + + private AtmosphericPressure parsePressure(JsonNode rootNode) { + AtmosphericPressure atmosphericPressure = AtmosphericPressure.withValue(rootNode.get("pressure").asDouble()); + + final JsonNode seaLevelNode = rootNode.get("sea_level"); + final JsonNode groundLevelNode = rootNode.get("grnd_level"); + if (seaLevelNode != null) { + atmosphericPressure.setSeaLevelValue(seaLevelNode.asDouble()); + } + if (groundLevelNode != null) { + atmosphericPressure.setGroundLevelValue(groundLevelNode.asDouble()); + } + + return atmosphericPressure; + } + + private Humidity parseHumidity(JsonNode rootNode) { + return Humidity.withValue((byte) (rootNode.get("humidity").asInt())); + } + + private Wind parseWind(JsonNode root) { + final JsonNode windNode = root.get("wind"); + double speed = windNode.get("speed").asDouble(); + + Wind wind = Wind.withValue(speed, unitSystem.getWindUnit()); + final JsonNode degNode = windNode.get("deg"); + if (degNode != null) { + wind.setDegrees(degNode.asDouble()); + } + + return wind; + } + + private Rain parseRain(JsonNode root) { + final JsonNode rainNode = root.get("rain"); + if (rainNode != null) { + final JsonNode threeHourNode = rainNode.get("3h"); + if (threeHourNode != null) { + return Rain.withThreeHourLevelValue(threeHourNode.asDouble()); + } + } + return null; + } + + private Snow parseSnow(JsonNode root) { + final JsonNode snowNode = root.get("snow"); + if (snowNode != null) { + final JsonNode threeHourNode = snowNode.get("3h"); + if (threeHourNode != null) { + Rain.withThreeHourLevelValue(threeHourNode.asDouble()); + } + } + return null; + } + + private Clouds parseClouds(JsonNode rootNode) { + Clouds clouds = null; + + final JsonNode cloudsNode = rootNode.get("clouds"); + final JsonNode allValueNode = cloudsNode.get("all"); + if (allValueNode != null) { + clouds = Clouds.withValue((byte) allValueNode.asInt()); + } + + return clouds; + } + + private Location parseLocation(JsonNode rootNode) { + Location location = Location.withValues(rootNode.get("id").asInt(), rootNode.get("name").asText()); + + final JsonNode timezoneNode = rootNode.get("timezone"); + if (timezoneNode != null) { + location.setZoneOffset(ZoneOffset.ofTotalSeconds(timezoneNode.asInt())); + } + + final JsonNode countryNode = rootNode.get("country"); + if (countryNode != null) { + location.setCountryCode(countryNode.asText()); + } + + final JsonNode sunriseNode = rootNode.get("sunrise"); + final JsonNode sunsetNode = rootNode.get("sunset"); + if (sunriseNode != null) { + location.setSunrise(LocalDateTime.ofInstant(Instant.ofEpochSecond(sunriseNode.asLong()), TimeZone.getDefault().toZoneId())); + } + if (sunsetNode != null) { + location.setSunset(LocalDateTime.ofInstant(Instant.ofEpochSecond(sunsetNode.asLong()), TimeZone.getDefault().toZoneId())); + } + + final JsonNode coordNode = rootNode.get("coord"); + if (coordNode != null) { + location.setCoordinate(parseCoordinate(coordNode)); + } + + final JsonNode populationNode = rootNode.get("population"); + if (populationNode != null) { + location.setPopulation(populationNode.asLong()); + } + + return location; + } + + private Coordinate parseCoordinate(JsonNode rootNode) { + JsonNode latitudeNode = rootNode.get("lat"); + JsonNode longitudeNode = rootNode.get("lon"); + if (latitudeNode != null && longitudeNode != null) { + return Coordinate.withValues(latitudeNode.asDouble(), longitudeNode.asDouble()); + } + return null; + } +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/MultipleLocationsWeatherRequester.java b/src/main/java/com/github/prominence/openweathermap/api/request/weather/CurrentWeatherRequester.java similarity index 56% rename from src/main/java/com/github/prominence/openweathermap/api/MultipleLocationsWeatherRequester.java rename to src/main/java/com/github/prominence/openweathermap/api/request/weather/CurrentWeatherRequester.java index 5a24828..9c459d4 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/MultipleLocationsWeatherRequester.java +++ b/src/main/java/com/github/prominence/openweathermap/api/request/weather/CurrentWeatherRequester.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,19 +20,27 @@ * SOFTWARE. */ -package com.github.prominence.openweathermap.api; +package com.github.prominence.openweathermap.api.request.weather; -import com.github.prominence.openweathermap.api.model.Coordinate; -import com.github.prominence.openweathermap.api.model.CoordinateRectangle; +import com.github.prominence.openweathermap.api.request.weather.multiple.MultipleLocationsCurrentWeatherRequester; +import com.github.prominence.openweathermap.api.request.weather.single.SingleLocationCurrentWeatherRequester; -public interface MultipleLocationsWeatherRequester { +/** + * An interface for API methods. + */ +public interface CurrentWeatherRequester { - 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); + /** + * Single location current weather requester. + * + * @return the single location current weather requester + */ + SingleLocationCurrentWeatherRequester single(); + /** + * Multiple locations current weather requester. + * + * @return the multiple locations current weather requester + */ + MultipleLocationsCurrentWeatherRequester multiple(); } diff --git a/src/main/java/com/github/prominence/openweathermap/api/impl/CurrentWeatherRequesterImpl.java b/src/main/java/com/github/prominence/openweathermap/api/request/weather/CurrentWeatherRequesterImpl.java similarity index 55% rename from src/main/java/com/github/prominence/openweathermap/api/impl/CurrentWeatherRequesterImpl.java rename to src/main/java/com/github/prominence/openweathermap/api/request/weather/CurrentWeatherRequesterImpl.java index 31ee121..b3b0811 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/impl/CurrentWeatherRequesterImpl.java +++ b/src/main/java/com/github/prominence/openweathermap/api/request/weather/CurrentWeatherRequesterImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,25 +20,35 @@ * SOFTWARE. */ -package com.github.prominence.openweathermap.api.impl; +package com.github.prominence.openweathermap.api.request.weather; -import com.github.prominence.openweathermap.api.CurrentWeatherRequester; -import com.github.prominence.openweathermap.api.MultipleLocationsWeatherRequester; -import com.github.prominence.openweathermap.api.SingleLocationWeatherRequester; +import com.github.prominence.openweathermap.api.request.RequestUrlBuilder; +import com.github.prominence.openweathermap.api.request.weather.multiple.MultipleLocationsCurrentWeatherRequesterImpl; +import com.github.prominence.openweathermap.api.request.weather.multiple.MultipleLocationsCurrentWeatherRequester; +import com.github.prominence.openweathermap.api.request.weather.single.SingleLocationCurrentWeatherRequesterImpl; +import com.github.prominence.openweathermap.api.request.weather.single.SingleLocationCurrentWeatherRequester; +/** + * The type Current weather requester. + */ public class CurrentWeatherRequesterImpl implements CurrentWeatherRequester { - private RequestUrlBuilder urlBuilder = new RequestUrlBuilder("http://api.openweathermap.org/data/2.5/"); + private final RequestUrlBuilder urlBuilder; - CurrentWeatherRequesterImpl(String apiKey) { - urlBuilder.addRequestParameter("appid", apiKey); + /** + * Instantiates a new Current weather requester. + * + * @param apiKey the api key + */ + public CurrentWeatherRequesterImpl(String apiKey) { + urlBuilder = new RequestUrlBuilder(apiKey); } - public SingleLocationWeatherRequester single() { + public SingleLocationCurrentWeatherRequester single() { return new SingleLocationCurrentWeatherRequesterImpl(urlBuilder); } - public MultipleLocationsWeatherRequester multiple() { + public MultipleLocationsCurrentWeatherRequester 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/request/weather/CurrentWeatherResponseMapper.java similarity index 57% rename from src/main/java/com/github/prominence/openweathermap/api/impl/CurrentWeatherResponseMapper.java rename to src/main/java/com/github/prominence/openweathermap/api/request/weather/CurrentWeatherResponseMapper.java index 0af4674..690edc4 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/impl/CurrentWeatherResponseMapper.java +++ b/src/main/java/com/github/prominence/openweathermap/api/request/weather/CurrentWeatherResponseMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,11 +20,11 @@ * SOFTWARE. */ -package com.github.prominence.openweathermap.api.impl; +package com.github.prominence.openweathermap.api.request.weather; 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.model.weather.*; import com.github.prominence.openweathermap.api.enums.UnitSystem; import com.github.prominence.openweathermap.api.model.*; @@ -50,6 +50,7 @@ import java.util.TimeZone; * --- base Internal parameter * --- main * |- main.temp Temperature. UnitSystem Default: Kelvin, Metric: Celsius, Imperial: Fahrenheit. + * |- main.feels_like Temperature. This temperature parameter accounts for the human perception of weather. 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). UnitSystem Default: Kelvin, Metric: Celsius, Imperial: Fahrenheit. @@ -59,6 +60,7 @@ import java.util.TimeZone; * --- wind * |- wind.speed Wind speed. UnitSystem Default: meter/sec, Metric: meter/sec, Imperial: miles/hour. * |- wind.deg Wind direction, degrees (meteorological) + * |- wind.gust Wind gust. Unit Default: meter/sec, Metric: meter/sec, Imperial: miles/hour * --- clouds * |- clouds.all Cloudiness, % * --- rain @@ -75,19 +77,30 @@ import java.util.TimeZone; * |- sys.country Country code (GB, JP etc.) * |- sys.sunrise Sunrise time, unix, UTC * |- sys.sunset Sunset time, unix, UTC + * --- timezone Shift in seconds from UTC * --- id City ID * --- name City name * --- cod Internal parameter */ -public class CurrentWeatherResponseMapper implements ResponseMapper { +public class CurrentWeatherResponseMapper { - private UnitSystem unitSystem; + private final UnitSystem unitSystem; - CurrentWeatherResponseMapper(UnitSystem unitSystem) { + /** + * Instantiates a new Current weather response mapper. + * + * @param unitSystem the unit system + */ + public CurrentWeatherResponseMapper(UnitSystem unitSystem) { this.unitSystem = unitSystem != null ? unitSystem : UnitSystem.STANDARD; } - @Override + /** + * Gets single result. + * + * @param json the json string + * @return the weather object + */ public Weather getSingle(String json) { ObjectMapper objectMapper = new ObjectMapper(); Weather weather; @@ -101,31 +114,34 @@ public class CurrentWeatherResponseMapper implements ResponseMapper { return weather; } - private Weather getSingle(JsonNode root) { - final Weather weather; - - JsonNode weatherState = root.get("weather").get(0); - weather = new Weather(weatherState.get("main").asText(), weatherState.get("description").asText()); + private Weather getSingle(JsonNode rootNode) { + JsonNode weatherState = rootNode.get("weather").get(0); + Weather weather = Weather.forValue(weatherState.get("main").asText(), 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)); + weather.setTemperature(parseTemperature(rootNode)); + weather.setAtmosphericPressure(parsePressure(rootNode)); + weather.setHumidity(parseHumidity(rootNode)); + weather.setWind(parseWind(rootNode)); + weather.setRain(parseRain(rootNode)); + weather.setSnow(parseSnow(rootNode)); + weather.setClouds(parseClouds(rootNode)); + weather.setLocation(parseLocation(rootNode)); - final JsonNode dtNode = root.get("dt"); + final JsonNode dtNode = rootNode.get("dt"); if (dtNode != null) { - weather.setRequestedOn(LocalDateTime.ofInstant(Instant.ofEpochSecond(dtNode.asInt()), TimeZone.getDefault().toZoneId())); + weather.setCalculatedOn(LocalDateTime.ofInstant(Instant.ofEpochSecond(dtNode.asInt()), TimeZone.getDefault().toZoneId())); } return weather; } - @Override + /** + * Gets list of results. + * + * @param json the json string + * @return the list of weathers + */ public List getList(String json) { ObjectMapper objectMapper = new ObjectMapper(); List weatherList = new ArrayList<>(); @@ -140,12 +156,17 @@ public class CurrentWeatherResponseMapper implements ResponseMapper { return weatherList; } - private Temperature parseTemperature(JsonNode root) { + private Temperature parseTemperature(JsonNode rootNode) { Temperature temperature; - final JsonNode mainNode = root.get("main"); + final JsonNode mainNode = rootNode.get("main"); final double tempValue = mainNode.get("temp").asDouble(); - temperature = new Temperature(tempValue, UnitSystem.getTemperatureUnit(unitSystem)); + temperature = Temperature.withValue(tempValue, unitSystem.getTemperatureUnit()); + + final JsonNode feelsLikeNode = mainNode.get("feels_like"); + if (feelsLikeNode != null) { + temperature.setFeelsLike(feelsLikeNode.asDouble()); + } final JsonNode tempMaxNode = mainNode.get("temp_max"); if (tempMaxNode != null) { temperature.setMaxTemperature(tempMaxNode.asDouble()); @@ -158,101 +179,99 @@ public class CurrentWeatherResponseMapper implements ResponseMapper { return temperature; } - private Pressure parsePressure(JsonNode root) { - final JsonNode mainNode = root.get("main"); - Pressure pressure = new Pressure(mainNode.get("pressure").asDouble()); + private AtmosphericPressure parsePressure(JsonNode rootNode) { + final JsonNode mainNode = rootNode.get("main"); + AtmosphericPressure atmosphericPressure = AtmosphericPressure.withValue(mainNode.get("pressure").asDouble()); final JsonNode seaLevelNode = mainNode.get("sea_level"); - final JsonNode grndLevelNode = mainNode.get("grnd_level"); + final JsonNode groundLevelNode = mainNode.get("grnd_level"); if (seaLevelNode != null) { - pressure.setSeaLevelValue(seaLevelNode.asDouble()); + atmosphericPressure.setSeaLevelValue(seaLevelNode.asDouble()); } - if (grndLevelNode != null) { - pressure.setGroundLevelValue(grndLevelNode.asDouble()); + if (groundLevelNode != null) { + atmosphericPressure.setGroundLevelValue(groundLevelNode.asDouble()); } - return pressure; + return atmosphericPressure; } - private Humidity parseHumidity(JsonNode root) { - final JsonNode mainNode = root.get("main"); + private Humidity parseHumidity(JsonNode rootNode) { + final JsonNode mainNode = rootNode.get("main"); - return new Humidity((byte) (mainNode.get("humidity").asInt())); + return Humidity.withValue((byte) (mainNode.get("humidity").asInt())); } - private Wind parseWind(JsonNode root) { - final JsonNode windNode = root.get("wind"); + private Wind parseWind(JsonNode rootNode) { + final JsonNode windNode = rootNode.get("wind"); double speed = windNode.get("speed").asDouble(); - Wind wind = new Wind(speed, UnitSystem.getWindUnit(unitSystem)); + Wind wind = Wind.withValue(speed, unitSystem.getWindUnit()); + final JsonNode degNode = windNode.get("deg"); if (degNode != null) { wind.setDegrees(degNode.asDouble()); } + final JsonNode gustNode = windNode.get("gust"); + if (gustNode != null) { + wind.setGust(gustNode.asDouble()); + } return wind; } - private Rain parseRain(JsonNode root) { - Rain rain = null; - - final JsonNode rainNode = root.get("rain"); + private Rain parseRain(JsonNode rootNode) { + final JsonNode rainNode = rootNode.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()); + if (oneHourNode != null && oneHourNode.isDouble() && threeHourNode != null && threeHourNode.isDouble()) { + return Rain.withValues(oneHourNode.asDouble(), threeHourNode.asDouble()); + } else if (oneHourNode != null && oneHourNode.isDouble()) { + return Rain.withOneHourLevelValue(oneHourNode.asDouble()); + } else if (threeHourNode != null && threeHourNode.isDouble()) { + return Rain.withThreeHourLevelValue(threeHourNode.asDouble()); } } - - return rain; + return null; } - private Snow parseSnow(JsonNode root) { - Snow snow = null; - - final JsonNode snowNode = root.get("snow"); - + private Snow parseSnow(JsonNode rootNode) { + final JsonNode snowNode = rootNode.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()); + if (oneHourNode != null && oneHourNode.isDouble() && threeHourNode != null && threeHourNode.isDouble()) { + return Snow.withValues(oneHourNode.asDouble(), threeHourNode.asDouble()); + } else if (oneHourNode != null && oneHourNode.isDouble()) { + return Snow.withOneHourLevelValue(oneHourNode.asDouble()); + } else if (threeHourNode != null && threeHourNode.isDouble()) { + return Snow.withThreeHourLevelValue(threeHourNode.asDouble()); } } - - return snow; + return null; } - private Clouds parseClouds(JsonNode root) { + private Clouds parseClouds(JsonNode rootNode) { Clouds clouds = null; - final JsonNode cloudsNode = root.get("clouds"); + final JsonNode cloudsNode = rootNode.get("clouds"); final JsonNode allValueNode = cloudsNode.get("all"); if (allValueNode != null) { - clouds = new Clouds((byte) allValueNode.asInt()); + clouds = Clouds.withValue((byte) allValueNode.asInt()); } return clouds; } - private Location parseLocation(JsonNode root) { - Location location = new Location(root.get("id").asInt(), root.get("name").asText()); + private Location parseLocation(JsonNode rootNode) { + Location location = Location.withValues(rootNode.get("id").asInt(), rootNode.get("name").asText()); - final JsonNode timezoneNode = root.get("timezone"); + final JsonNode timezoneNode = rootNode.get("timezone"); if (timezoneNode != null) { location.setZoneOffset(ZoneOffset.ofTotalSeconds(timezoneNode.asInt())); } - final JsonNode sysNode = root.get("sys"); + final JsonNode sysNode = rootNode.get("sys"); if (sysNode != null) { final JsonNode countryNode = sysNode.get("country"); if (countryNode != null) { @@ -269,21 +288,20 @@ public class CurrentWeatherResponseMapper implements ResponseMapper { } } - final JsonNode coordNode = root.get("coord"); + final JsonNode coordNode = rootNode.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())); - } + location.setCoordinate(parseCoordinate(coordNode)); } return location; } + + private Coordinate parseCoordinate(JsonNode rootNode) { + JsonNode latitudeNode = rootNode.get("lat"); + JsonNode longitudeNode = rootNode.get("lon"); + if (latitudeNode != null && longitudeNode != null) { + return Coordinate.withValues(latitudeNode.asDouble(), longitudeNode.asDouble()); + } + return null; + } } diff --git a/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleLocationsCurrentWeatherRequester.java b/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleLocationsCurrentWeatherRequester.java new file mode 100644 index 0000000..291674e --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleLocationsCurrentWeatherRequester.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021 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.request.weather.multiple; + +import com.github.prominence.openweathermap.api.model.Coordinate; +import com.github.prominence.openweathermap.api.model.CoordinateRectangle; + +/** + * The interface Multiple locations current weather requester. + */ +public interface MultipleLocationsCurrentWeatherRequester { + + /** + * By rectangle multiple result current weather request customizer. + * + * @param rectangle the rectangle + * @param zoom the zoom + * @return the multiple result current weather request customizer + */ + MultipleResultCurrentWeatherRequestCustomizer byRectangle(CoordinateRectangle rectangle, int zoom); + + /** + * By cities in cycle multiple result current weather request customizer. + * + * @param point the point + * @return the multiple result cities in circle current weather request customizer + */ + MultipleResultCitiesInCircleCurrentWeatherRequestCustomizer byCitiesInCycle(Coordinate point); + + /** + * By cities in cycle multiple result current weather request customizer. + * + * @param point the point + * @param citiesCount the cities count + * @return the multiple result cities in circle current weather request customizer + */ + MultipleResultCitiesInCircleCurrentWeatherRequestCustomizer byCitiesInCycle(Coordinate point, int citiesCount); + +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/impl/MultipleLocationsCurrentWeatherRequesterImpl.java b/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleLocationsCurrentWeatherRequesterImpl.java similarity index 57% rename from src/main/java/com/github/prominence/openweathermap/api/impl/MultipleLocationsCurrentWeatherRequesterImpl.java rename to src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleLocationsCurrentWeatherRequesterImpl.java index 72597b8..6b28095 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/impl/MultipleLocationsCurrentWeatherRequesterImpl.java +++ b/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleLocationsCurrentWeatherRequesterImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,24 +20,31 @@ * SOFTWARE. */ -package com.github.prominence.openweathermap.api.impl; +package com.github.prominence.openweathermap.api.request.weather.multiple; -import com.github.prominence.openweathermap.api.MultipleLocationsWeatherRequester; -import com.github.prominence.openweathermap.api.MultipleResultCurrentWeatherRequestCustomizer; +import com.github.prominence.openweathermap.api.request.RequestUrlBuilder; import com.github.prominence.openweathermap.api.model.Coordinate; import com.github.prominence.openweathermap.api.model.CoordinateRectangle; -public class MultipleLocationsCurrentWeatherRequesterImpl implements MultipleLocationsWeatherRequester { +/** + * The type Multiple locations current weather requester. + */ +public class MultipleLocationsCurrentWeatherRequesterImpl implements MultipleLocationsCurrentWeatherRequester { - private RequestUrlBuilder urlBuilder; + private final RequestUrlBuilder urlBuilder; - MultipleLocationsCurrentWeatherRequesterImpl(RequestUrlBuilder urlBuilder) { + /** + * Instantiates a new Multiple locations current weather requester. + * + * @param urlBuilder the url builder + */ + public MultipleLocationsCurrentWeatherRequesterImpl(RequestUrlBuilder urlBuilder) { this.urlBuilder = urlBuilder; } @Override public MultipleResultCurrentWeatherRequestCustomizer byRectangle(CoordinateRectangle rectangle, int zoom) { - String coordinates = rectangle.getFormattedString() + "," + zoom; + String coordinates = rectangle.getFormattedRequestString() + "," + zoom; urlBuilder.append("box/city"); urlBuilder.addRequestParameter("bbox", coordinates); @@ -45,32 +52,21 @@ public class MultipleLocationsCurrentWeatherRequesterImpl implements MultipleLoc } @Override - public MultipleResultCurrentWeatherRequestCustomizer byRectangle(CoordinateRectangle rectangle, int zoom, boolean useServerClustering) { - String coordinates = rectangle.getFormattedString() + "," + 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) { + public MultipleResultCitiesInCircleCurrentWeatherRequestCustomizer 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); + return new MultipleResultCitiesInCircleCurrentWeatherRequestCustomizerImpl(urlBuilder); } @Override - public MultipleResultCurrentWeatherRequestCustomizer byCitiesInCycle(Coordinate point, int citiesCount, boolean useServerClustering) { + public MultipleResultCitiesInCircleCurrentWeatherRequestCustomizer byCitiesInCycle(Coordinate point) { 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); + + return new MultipleResultCitiesInCircleCurrentWeatherRequestCustomizerImpl(urlBuilder); } } diff --git a/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCitiesInCircleCurrentWeatherAsyncRequestTerminator.java b/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCitiesInCircleCurrentWeatherAsyncRequestTerminator.java new file mode 100644 index 0000000..31905d1 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCitiesInCircleCurrentWeatherAsyncRequestTerminator.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021 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.request.weather.multiple; + +import com.github.prominence.openweathermap.api.model.weather.Weather; +import com.github.prominence.openweathermap.api.request.AsyncRequestTerminator; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +/** + * The interface Multiple result current weather async request terminator. + */ +public interface MultipleResultCitiesInCircleCurrentWeatherAsyncRequestTerminator extends AsyncRequestTerminator, String> { + /** + * XML response format. + * + * @return the completable future + */ + CompletableFuture asXML(); +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCitiesInCircleCurrentWeatherAsyncRequestTerminatorImpl.java b/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCitiesInCircleCurrentWeatherAsyncRequestTerminatorImpl.java new file mode 100644 index 0000000..99b120b --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCitiesInCircleCurrentWeatherAsyncRequestTerminatorImpl.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2021 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.request.weather.multiple; + +import com.github.prominence.openweathermap.api.enums.UnitSystem; +import com.github.prominence.openweathermap.api.model.weather.Weather; +import com.github.prominence.openweathermap.api.request.RequestUrlBuilder; +import com.github.prominence.openweathermap.api.request.weather.CurrentWeatherResponseMapper; +import com.github.prominence.openweathermap.api.utils.RequestUtils; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +/** + * The type Multiple result current weather async request terminator. + */ +public class MultipleResultCitiesInCircleCurrentWeatherAsyncRequestTerminatorImpl implements MultipleResultCitiesInCircleCurrentWeatherAsyncRequestTerminator { + + private final RequestUrlBuilder urlBuilder; + private final UnitSystem unitSystem; + + /** + * Instantiates a new Multiple result current weather async request terminator. + * + * @param urlBuilder the url builder + * @param unitSystem the unit system + */ + MultipleResultCitiesInCircleCurrentWeatherAsyncRequestTerminatorImpl(RequestUrlBuilder urlBuilder, UnitSystem unitSystem) { + this.urlBuilder = urlBuilder; + this.unitSystem = unitSystem; + } + + @Override + public CompletableFuture> asJava() { + return CompletableFuture.supplyAsync(() -> new CurrentWeatherResponseMapper(unitSystem).getList(getRawResponse())); + } + + @Override + public CompletableFuture asJSON() { + return CompletableFuture.supplyAsync(this::getRawResponse); + } + + @Override + public CompletableFuture asXML() { + urlBuilder.addRequestParameter("mode", "xml"); + return CompletableFuture.supplyAsync(this::getRawResponse); + } + + private String getRawResponse() { + return RequestUtils.getResponse(urlBuilder.buildUrl()); + } +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCitiesInCircleCurrentWeatherRequestCustomizer.java b/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCitiesInCircleCurrentWeatherRequestCustomizer.java new file mode 100644 index 0000000..b51357e --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCitiesInCircleCurrentWeatherRequestCustomizer.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 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.request.weather.multiple; + +import com.github.prominence.openweathermap.api.request.RequestCustomizer; + +/** + * The interface Multiple result current weather request customizer. + */ +public interface MultipleResultCitiesInCircleCurrentWeatherRequestCustomizer extends RequestCustomizer { + + /** + * Retrieve multiple result current weather request terminator. + * + * @return the multiple result current weather request terminator + */ + MultipleResultCitiesInCircleCurrentWeatherRequestTerminator retrieve(); + + /** + * Retrieve async multiple result current weather async request terminator. + * + * @return the multiple result current weather async request terminator + */ + MultipleResultCitiesInCircleCurrentWeatherAsyncRequestTerminator retrieveAsync(); +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCitiesInCircleCurrentWeatherRequestCustomizerImpl.java b/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCitiesInCircleCurrentWeatherRequestCustomizerImpl.java new file mode 100644 index 0000000..09935df --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCitiesInCircleCurrentWeatherRequestCustomizerImpl.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2021 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.request.weather.multiple; + +import com.github.prominence.openweathermap.api.enums.Language; +import com.github.prominence.openweathermap.api.enums.UnitSystem; +import com.github.prominence.openweathermap.api.request.RequestUrlBuilder; + +/** + * The type Multiple result current weather request customizer. + */ +public class MultipleResultCitiesInCircleCurrentWeatherRequestCustomizerImpl implements MultipleResultCitiesInCircleCurrentWeatherRequestCustomizer { + + private final RequestUrlBuilder urlBuilder; + + private Language language; + private UnitSystem unitSystem = UnitSystem.STANDARD; + + /** + * Instantiates a new Multiple result current weather request customizer. + * + * @param urlBuilder the url builder + */ + MultipleResultCitiesInCircleCurrentWeatherRequestCustomizerImpl(RequestUrlBuilder urlBuilder) { + this.urlBuilder = urlBuilder; + } + + @Override + public MultipleResultCitiesInCircleCurrentWeatherRequestTerminator retrieve() { + urlBuilder.applyCustomization(language, unitSystem); + return new MultipleResultCitiesInCircleCurrentWeatherRequestTerminatorImpl(urlBuilder, unitSystem); + } + + @Override + public MultipleResultCitiesInCircleCurrentWeatherAsyncRequestTerminator retrieveAsync() { + urlBuilder.applyCustomization(language, unitSystem); + return new MultipleResultCitiesInCircleCurrentWeatherAsyncRequestTerminatorImpl(urlBuilder, unitSystem); + } + + @Override + public MultipleResultCitiesInCircleCurrentWeatherRequestCustomizer language(Language language) { + this.language = language; + return this; + } + + @Override + public MultipleResultCitiesInCircleCurrentWeatherRequestCustomizer unitSystem(UnitSystem unitSystem) { + this.unitSystem = unitSystem; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/github/prominence/openweathermap/api/CurrentWeatherRequester.java b/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCitiesInCircleCurrentWeatherRequestTerminator.java similarity index 64% rename from src/main/java/com/github/prominence/openweathermap/api/CurrentWeatherRequester.java rename to src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCitiesInCircleCurrentWeatherRequestTerminator.java index d9f7467..dcd1905 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/CurrentWeatherRequester.java +++ b/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCitiesInCircleCurrentWeatherRequestTerminator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,11 +20,21 @@ * SOFTWARE. */ -package com.github.prominence.openweathermap.api; +package com.github.prominence.openweathermap.api.request.weather.multiple; -public interface CurrentWeatherRequester { +import com.github.prominence.openweathermap.api.model.weather.Weather; +import com.github.prominence.openweathermap.api.request.RequestTerminator; - SingleLocationWeatherRequester single(); +import java.util.List; - MultipleLocationsWeatherRequester multiple(); +/** + * The interface Multiple result current weather request terminator. + */ +public interface MultipleResultCitiesInCircleCurrentWeatherRequestTerminator extends RequestTerminator, String> { + /** + * XML response format. + * + * @return the XML string + */ + String asXML(); } diff --git a/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCitiesInCircleCurrentWeatherRequestTerminatorImpl.java b/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCitiesInCircleCurrentWeatherRequestTerminatorImpl.java new file mode 100644 index 0000000..6d22b90 --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCitiesInCircleCurrentWeatherRequestTerminatorImpl.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2021 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.request.weather.multiple; + +import com.github.prominence.openweathermap.api.enums.UnitSystem; +import com.github.prominence.openweathermap.api.model.weather.Weather; +import com.github.prominence.openweathermap.api.request.RequestUrlBuilder; +import com.github.prominence.openweathermap.api.request.weather.CurrentWeatherResponseMapper; +import com.github.prominence.openweathermap.api.utils.RequestUtils; + +import java.util.List; + +/** + * The type Multiple result current weather request terminator. + */ +public class MultipleResultCitiesInCircleCurrentWeatherRequestTerminatorImpl implements MultipleResultCitiesInCircleCurrentWeatherRequestTerminator { + + private final RequestUrlBuilder urlBuilder; + private final UnitSystem unitSystem; + + /** + * Instantiates a new Multiple result current weather request terminator. + * + * @param urlBuilder the url builder + * @param unitSystem the unit system + */ + MultipleResultCitiesInCircleCurrentWeatherRequestTerminatorImpl(RequestUrlBuilder urlBuilder, UnitSystem unitSystem) { + this.urlBuilder = urlBuilder; + this.unitSystem = unitSystem; + } + + @Override + public List asJava() { + return new CurrentWeatherResponseMapper(unitSystem).getList(getRawResponse()); + } + + @Override + public String asJSON() { + return getRawResponse(); + } + + @Override + public String asXML() { + urlBuilder.addRequestParameter("mode", "xml"); + return getRawResponse(); + } + + private String getRawResponse() { + return RequestUtils.getResponse(urlBuilder.buildUrl()); + } +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/MultipleResultCurrentWeatherAsyncRequestTerminator.java b/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCurrentWeatherAsyncRequestTerminator.java similarity index 74% rename from src/main/java/com/github/prominence/openweathermap/api/MultipleResultCurrentWeatherAsyncRequestTerminator.java rename to src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCurrentWeatherAsyncRequestTerminator.java index 35a1d1f..6374a96 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/MultipleResultCurrentWeatherAsyncRequestTerminator.java +++ b/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCurrentWeatherAsyncRequestTerminator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,12 +20,15 @@ * SOFTWARE. */ -package com.github.prominence.openweathermap.api; +package com.github.prominence.openweathermap.api.request.weather.multiple; -import com.github.prominence.openweathermap.api.model.Weather; +import com.github.prominence.openweathermap.api.model.weather.Weather; +import com.github.prominence.openweathermap.api.request.AsyncRequestTerminator; import java.util.List; -import java.util.concurrent.CompletableFuture; -public interface MultipleResultCurrentWeatherAsyncRequestTerminator extends CurrentWeatherRequestTerminator>, CompletableFuture> { +/** + * The interface Multiple result current weather async request terminator. + */ +public interface MultipleResultCurrentWeatherAsyncRequestTerminator extends AsyncRequestTerminator, String> { } diff --git a/src/main/java/com/github/prominence/openweathermap/api/impl/MultipleResultCurrentWeatherAsyncRequestTerminatorImpl.java b/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCurrentWeatherAsyncRequestTerminatorImpl.java similarity index 74% rename from src/main/java/com/github/prominence/openweathermap/api/impl/MultipleResultCurrentWeatherAsyncRequestTerminatorImpl.java rename to src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCurrentWeatherAsyncRequestTerminatorImpl.java index a66dd90..876c73a 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/impl/MultipleResultCurrentWeatherAsyncRequestTerminatorImpl.java +++ b/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCurrentWeatherAsyncRequestTerminatorImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,21 +20,31 @@ * SOFTWARE. */ -package com.github.prominence.openweathermap.api.impl; +package com.github.prominence.openweathermap.api.request.weather.multiple; -import com.github.prominence.openweathermap.api.MultipleResultCurrentWeatherAsyncRequestTerminator; +import com.github.prominence.openweathermap.api.request.RequestUrlBuilder; +import com.github.prominence.openweathermap.api.request.weather.CurrentWeatherResponseMapper; import com.github.prominence.openweathermap.api.enums.UnitSystem; -import com.github.prominence.openweathermap.api.model.Weather; +import com.github.prominence.openweathermap.api.model.weather.Weather; import com.github.prominence.openweathermap.api.utils.RequestUtils; import java.util.List; import java.util.concurrent.CompletableFuture; +/** + * The type Multiple result current weather async request terminator. + */ public class MultipleResultCurrentWeatherAsyncRequestTerminatorImpl implements MultipleResultCurrentWeatherAsyncRequestTerminator { - private RequestUrlBuilder urlBuilder; - private UnitSystem unitSystem; + private final RequestUrlBuilder urlBuilder; + private final UnitSystem unitSystem; + /** + * Instantiates a new Multiple result current weather async request terminator. + * + * @param urlBuilder the url builder + * @param unitSystem the unit system + */ MultipleResultCurrentWeatherAsyncRequestTerminatorImpl(RequestUrlBuilder urlBuilder, UnitSystem unitSystem) { this.urlBuilder = urlBuilder; this.unitSystem = unitSystem; @@ -50,18 +60,6 @@ public class MultipleResultCurrentWeatherAsyncRequestTerminatorImpl implements M 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.getResponse(urlBuilder.buildUrl()); } diff --git a/src/main/java/com/github/prominence/openweathermap/api/MultipleResultCurrentWeatherRequestCustomizer.java b/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCurrentWeatherRequestCustomizer.java similarity index 69% rename from src/main/java/com/github/prominence/openweathermap/api/MultipleResultCurrentWeatherRequestCustomizer.java rename to src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCurrentWeatherRequestCustomizer.java index 5560a73..57f5e06 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/MultipleResultCurrentWeatherRequestCustomizer.java +++ b/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCurrentWeatherRequestCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,11 +20,26 @@ * SOFTWARE. */ -package com.github.prominence.openweathermap.api; +package com.github.prominence.openweathermap.api.request.weather.multiple; +import com.github.prominence.openweathermap.api.request.RequestCustomizer; + +/** + * The interface Multiple result current weather request customizer. + */ public interface MultipleResultCurrentWeatherRequestCustomizer extends RequestCustomizer { + /** + * Retrieve multiple result current weather request terminator. + * + * @return the multiple result current weather request terminator + */ MultipleResultCurrentWeatherRequestTerminator retrieve(); + /** + * Retrieve async multiple result current weather async request terminator. + * + * @return the multiple result current weather async request terminator + */ MultipleResultCurrentWeatherAsyncRequestTerminator retrieveAsync(); } diff --git a/src/main/java/com/github/prominence/openweathermap/api/impl/MultipleResultCurrentWeatherRequestCustomizerImpl.java b/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCurrentWeatherRequestCustomizerImpl.java similarity index 64% rename from src/main/java/com/github/prominence/openweathermap/api/impl/MultipleResultCurrentWeatherRequestCustomizerImpl.java rename to src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCurrentWeatherRequestCustomizerImpl.java index 1b0a243..911ae54 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/impl/MultipleResultCurrentWeatherRequestCustomizerImpl.java +++ b/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCurrentWeatherRequestCustomizerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,45 +20,43 @@ * SOFTWARE. */ -package com.github.prominence.openweathermap.api.impl; +package com.github.prominence.openweathermap.api.request.weather.multiple; -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.request.RequestUrlBuilder; import com.github.prominence.openweathermap.api.enums.Language; import com.github.prominence.openweathermap.api.enums.UnitSystem; +/** + * The type Multiple result current weather request customizer. + */ public class MultipleResultCurrentWeatherRequestCustomizerImpl implements MultipleResultCurrentWeatherRequestCustomizer { - private RequestUrlBuilder urlBuilder; + private final RequestUrlBuilder urlBuilder; - private Accuracy accuracy; private Language language; - private UnitSystem unitSystem; + private UnitSystem unitSystem = UnitSystem.STANDARD; + /** + * Instantiates a new Multiple result current weather request customizer. + * + * @param urlBuilder the url builder + */ MultipleResultCurrentWeatherRequestCustomizerImpl(RequestUrlBuilder urlBuilder) { this.urlBuilder = urlBuilder; } @Override public MultipleResultCurrentWeatherRequestTerminator retrieve() { - applyCustomization(); + urlBuilder.applyCustomization(language, unitSystem); return new MultipleResultCurrentWeatherRequestTerminatorImpl(urlBuilder, unitSystem); } @Override public MultipleResultCurrentWeatherAsyncRequestTerminator retrieveAsync() { - applyCustomization(); + urlBuilder.applyCustomization(language, unitSystem); return new MultipleResultCurrentWeatherAsyncRequestTerminatorImpl(urlBuilder, unitSystem); } - @Override - public MultipleResultCurrentWeatherRequestCustomizer accuracy(Accuracy accuracy) { - this.accuracy = accuracy; - return this; - } - @Override public MultipleResultCurrentWeatherRequestCustomizer language(Language language) { this.language = language; @@ -70,16 +68,4 @@ public class MultipleResultCurrentWeatherRequestCustomizerImpl implements Multip this.unitSystem = unitSystem; return this; } - - private void applyCustomization() { - if (accuracy != null) { - urlBuilder.addRequestParameter("type", accuracy.getValue()); - } - if (language != null) { - urlBuilder.addRequestParameter("lang", language.getValue()); - } - if (unitSystem != null && unitSystem != UnitSystem.STANDARD) { - urlBuilder.addRequestParameter("units", unitSystem.getValue()); - } - } } \ No newline at end of file diff --git a/src/main/java/com/github/prominence/openweathermap/api/MultipleResultCurrentWeatherRequestTerminator.java b/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCurrentWeatherRequestTerminator.java similarity index 75% rename from src/main/java/com/github/prominence/openweathermap/api/MultipleResultCurrentWeatherRequestTerminator.java rename to src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCurrentWeatherRequestTerminator.java index 2cc71aa..aa916f6 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/MultipleResultCurrentWeatherRequestTerminator.java +++ b/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCurrentWeatherRequestTerminator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,11 +20,15 @@ * SOFTWARE. */ -package com.github.prominence.openweathermap.api; +package com.github.prominence.openweathermap.api.request.weather.multiple; -import com.github.prominence.openweathermap.api.model.Weather; +import com.github.prominence.openweathermap.api.model.weather.Weather; +import com.github.prominence.openweathermap.api.request.RequestTerminator; import java.util.List; -public interface MultipleResultCurrentWeatherRequestTerminator extends CurrentWeatherRequestTerminator, String> { +/** + * The interface Multiple result current weather request terminator. + */ +public interface MultipleResultCurrentWeatherRequestTerminator extends RequestTerminator, String> { } diff --git a/src/main/java/com/github/prominence/openweathermap/api/impl/MultipleResultCurrentWeatherRequestTerminatorImpl.java b/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCurrentWeatherRequestTerminatorImpl.java similarity index 73% rename from src/main/java/com/github/prominence/openweathermap/api/impl/MultipleResultCurrentWeatherRequestTerminatorImpl.java rename to src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCurrentWeatherRequestTerminatorImpl.java index daca10d..dc1e927 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/impl/MultipleResultCurrentWeatherRequestTerminatorImpl.java +++ b/src/main/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCurrentWeatherRequestTerminatorImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,20 +20,30 @@ * SOFTWARE. */ -package com.github.prominence.openweathermap.api.impl; +package com.github.prominence.openweathermap.api.request.weather.multiple; -import com.github.prominence.openweathermap.api.MultipleResultCurrentWeatherRequestTerminator; +import com.github.prominence.openweathermap.api.request.RequestUrlBuilder; +import com.github.prominence.openweathermap.api.request.weather.CurrentWeatherResponseMapper; import com.github.prominence.openweathermap.api.enums.UnitSystem; -import com.github.prominence.openweathermap.api.model.Weather; +import com.github.prominence.openweathermap.api.model.weather.Weather; import com.github.prominence.openweathermap.api.utils.RequestUtils; import java.util.List; +/** + * The type Multiple result current weather request terminator. + */ public class MultipleResultCurrentWeatherRequestTerminatorImpl implements MultipleResultCurrentWeatherRequestTerminator { - private RequestUrlBuilder urlBuilder; - private UnitSystem unitSystem; + private final RequestUrlBuilder urlBuilder; + private final UnitSystem unitSystem; + /** + * Instantiates a new Multiple result current weather request terminator. + * + * @param urlBuilder the url builder + * @param unitSystem the unit system + */ MultipleResultCurrentWeatherRequestTerminatorImpl(RequestUrlBuilder urlBuilder, UnitSystem unitSystem) { this.urlBuilder = urlBuilder; this.unitSystem = unitSystem; @@ -49,18 +59,6 @@ public class MultipleResultCurrentWeatherRequestTerminatorImpl implements Multip 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.getResponse(urlBuilder.buildUrl()); } diff --git a/src/main/java/com/github/prominence/openweathermap/api/request/weather/single/SingleLocationCurrentWeatherRequester.java b/src/main/java/com/github/prominence/openweathermap/api/request/weather/single/SingleLocationCurrentWeatherRequester.java new file mode 100644 index 0000000..0dc887a --- /dev/null +++ b/src/main/java/com/github/prominence/openweathermap/api/request/weather/single/SingleLocationCurrentWeatherRequester.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2021 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.request.weather.single; + +import com.github.prominence.openweathermap.api.model.Coordinate; + +/** + * The interface Single location current weather requester. + */ +public interface SingleLocationCurrentWeatherRequester { + + /** + * By city name current weather request customizer. + * + * @param cityName the city name + * @return the single result current weather request customizer + */ + SingleResultCurrentWeatherRequestCustomizer byCityName(String cityName); + + /** + * By city name current weather request customizer. + * + * @param cityName the city name + * @param countryCode the country code + * @return the single result current weather request customizer + */ + SingleResultCurrentWeatherRequestCustomizer byCityName(String cityName, String countryCode); + + /** + * By city name current weather request customizer. + * + * @param cityName the city name + * @param stateCode the state code + * @param countryCode the country code + * @return the single result current weather request customizer + */ + SingleResultCurrentWeatherRequestCustomizer byCityName(String cityName, String stateCode, String countryCode); + + /** + * By city id current weather request customizer. + * + * @param cityId the city id + * @return the single result current weather request customizer + */ + SingleResultCurrentWeatherRequestCustomizer byCityId(long cityId); + + /** + * By coordinate current weather request customizer. + * + * @param coordinate the coordinate + * @return the single result current weather request customizer + */ + SingleResultCurrentWeatherRequestCustomizer byCoordinate(Coordinate coordinate); + + /** + * By zip code and country current weather request customizer. + * + * @param zipCode the zip code + * @param countryCode the country code + * @return the single result current weather request customizer + */ + SingleResultCurrentWeatherRequestCustomizer byZipCodeAndCountry(String zipCode, String countryCode); + + /** + * By zip code in usa current weather request customizer. + * + * @param zipCode the zip code + * @return the single result current weather request customizer + */ + SingleResultCurrentWeatherRequestCustomizer byZipCodeInUSA(String zipCode); +} diff --git a/src/main/java/com/github/prominence/openweathermap/api/impl/SingleLocationCurrentWeatherRequesterImpl.java b/src/main/java/com/github/prominence/openweathermap/api/request/weather/single/SingleLocationCurrentWeatherRequesterImpl.java similarity index 57% rename from src/main/java/com/github/prominence/openweathermap/api/impl/SingleLocationCurrentWeatherRequesterImpl.java rename to src/main/java/com/github/prominence/openweathermap/api/request/weather/single/SingleLocationCurrentWeatherRequesterImpl.java index 8ff61ba..dd452e6 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/impl/SingleLocationCurrentWeatherRequesterImpl.java +++ b/src/main/java/com/github/prominence/openweathermap/api/request/weather/single/SingleLocationCurrentWeatherRequesterImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,43 +20,63 @@ * SOFTWARE. */ -package com.github.prominence.openweathermap.api.impl; +package com.github.prominence.openweathermap.api.request.weather.single; -import com.github.prominence.openweathermap.api.SingleLocationWeatherRequester; +import com.github.prominence.openweathermap.api.request.RequestUrlBuilder; import com.github.prominence.openweathermap.api.model.Coordinate; -public class SingleLocationCurrentWeatherRequesterImpl implements SingleLocationWeatherRequester { +/** + * The type Single location current weather requester. + */ +public class SingleLocationCurrentWeatherRequesterImpl implements SingleLocationCurrentWeatherRequester { - private RequestUrlBuilder urlBuilder; + private final RequestUrlBuilder urlBuilder; - SingleLocationCurrentWeatherRequesterImpl(RequestUrlBuilder urlBuilder) { + /** + * Instantiates a new Single location current weather requester. + * + * @param urlBuilder the url builder + */ + public SingleLocationCurrentWeatherRequesterImpl(RequestUrlBuilder urlBuilder) { this.urlBuilder = urlBuilder; urlBuilder.append("weather"); } - public SingleResultCurrentWeatherRequestCustomizerImpl byCityName(String cityName) { + public SingleResultCurrentWeatherRequestCustomizer byCityName(String cityName) { urlBuilder.addRequestParameter("q", cityName); return new SingleResultCurrentWeatherRequestCustomizerImpl(urlBuilder); } - public SingleResultCurrentWeatherRequestCustomizerImpl byCityName(String cityName, String countryCode) { + public SingleResultCurrentWeatherRequestCustomizer byCityName(String cityName, String countryCode) { urlBuilder.addRequestParameter("q", cityName + "," + countryCode); return new SingleResultCurrentWeatherRequestCustomizerImpl(urlBuilder); } - public SingleResultCurrentWeatherRequestCustomizerImpl byCityId(long cityId) { + @Override + public SingleResultCurrentWeatherRequestCustomizer byCityName(String cityName, String stateCode, String countryCode) { + urlBuilder.addRequestParameter("q", cityName + "," + stateCode + "," + countryCode); + return new SingleResultCurrentWeatherRequestCustomizerImpl(urlBuilder); + } + + public SingleResultCurrentWeatherRequestCustomizer byCityId(long cityId) { urlBuilder.addRequestParameter("id", cityId); return new SingleResultCurrentWeatherRequestCustomizerImpl(urlBuilder); } - public SingleResultCurrentWeatherRequestCustomizerImpl byCoordinate(Coordinate coordinate) { + public SingleResultCurrentWeatherRequestCustomizer 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) { + public SingleResultCurrentWeatherRequestCustomizer byZipCodeAndCountry(String zipCode, String countryCode) { urlBuilder.addRequestParameter("zip", zipCode + "," + countryCode); return new SingleResultCurrentWeatherRequestCustomizerImpl(urlBuilder); } + + @Override + public SingleResultCurrentWeatherRequestCustomizer byZipCodeInUSA(String zipCode) { + urlBuilder.addRequestParameter("zip", zipCode); + return new SingleResultCurrentWeatherRequestCustomizerImpl(urlBuilder); + } } diff --git a/src/main/java/com/github/prominence/openweathermap/api/SingleLocationWeatherRequester.java b/src/main/java/com/github/prominence/openweathermap/api/request/weather/single/SingleResultCurrentWeatherAsyncRequestTerminator.java similarity index 59% rename from src/main/java/com/github/prominence/openweathermap/api/SingleLocationWeatherRequester.java rename to src/main/java/com/github/prominence/openweathermap/api/request/weather/single/SingleResultCurrentWeatherAsyncRequestTerminator.java index 15c9666..3c4cd61 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/SingleLocationWeatherRequester.java +++ b/src/main/java/com/github/prominence/openweathermap/api/request/weather/single/SingleResultCurrentWeatherAsyncRequestTerminator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,19 +20,28 @@ * SOFTWARE. */ -package com.github.prominence.openweathermap.api; +package com.github.prominence.openweathermap.api.request.weather.single; -import com.github.prominence.openweathermap.api.model.Coordinate; +import com.github.prominence.openweathermap.api.model.weather.Weather; +import com.github.prominence.openweathermap.api.request.AsyncRequestTerminator; -public interface SingleLocationWeatherRequester { +import java.util.concurrent.CompletableFuture; - SingleResultCurrentWeatherRequestCustomizer byCityName(String cityName); +/** + * The current weather async request terminator interface. + */ +public interface SingleResultCurrentWeatherAsyncRequestTerminator extends AsyncRequestTerminator { + /** + * XML response format. + * + * @return the completable future + */ + CompletableFuture asXML(); - SingleResultCurrentWeatherRequestCustomizer byCityName(String cityName, String countryCode); - - SingleResultCurrentWeatherRequestCustomizer byCityId(long cityId); - - SingleResultCurrentWeatherRequestCustomizer byCoordinate(Coordinate coordinate); - - SingleResultCurrentWeatherRequestCustomizer byZipCodeAndCountry(String zipCode, String countryCode); + /** + * HTML response format. + * + * @return the completable future + */ + CompletableFuture asHTML(); } diff --git a/src/main/java/com/github/prominence/openweathermap/api/impl/SingleResultCurrentWeatherAsyncRequestTerminatorImpl.java b/src/main/java/com/github/prominence/openweathermap/api/request/weather/single/SingleResultCurrentWeatherAsyncRequestTerminatorImpl.java similarity index 77% rename from src/main/java/com/github/prominence/openweathermap/api/impl/SingleResultCurrentWeatherAsyncRequestTerminatorImpl.java rename to src/main/java/com/github/prominence/openweathermap/api/request/weather/single/SingleResultCurrentWeatherAsyncRequestTerminatorImpl.java index b90bd27..439671b 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/impl/SingleResultCurrentWeatherAsyncRequestTerminatorImpl.java +++ b/src/main/java/com/github/prominence/openweathermap/api/request/weather/single/SingleResultCurrentWeatherAsyncRequestTerminatorImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,20 +20,30 @@ * SOFTWARE. */ -package com.github.prominence.openweathermap.api.impl; +package com.github.prominence.openweathermap.api.request.weather.single; -import com.github.prominence.openweathermap.api.SingleResultCurrentWeatherAsyncRequestTerminator; +import com.github.prominence.openweathermap.api.request.RequestUrlBuilder; +import com.github.prominence.openweathermap.api.request.weather.CurrentWeatherResponseMapper; import com.github.prominence.openweathermap.api.enums.UnitSystem; -import com.github.prominence.openweathermap.api.model.Weather; +import com.github.prominence.openweathermap.api.model.weather.Weather; import com.github.prominence.openweathermap.api.utils.RequestUtils; import java.util.concurrent.CompletableFuture; +/** + * The type Single result current weather async request terminator. + */ public class SingleResultCurrentWeatherAsyncRequestTerminatorImpl implements SingleResultCurrentWeatherAsyncRequestTerminator { - private RequestUrlBuilder urlBuilder; - private UnitSystem unitSystem; + private final RequestUrlBuilder urlBuilder; + private final UnitSystem unitSystem; + /** + * Instantiates a new Single result current weather async request terminator. + * + * @param urlBuilder the url builder + * @param unitSystem the unit system + */ SingleResultCurrentWeatherAsyncRequestTerminatorImpl(RequestUrlBuilder urlBuilder, UnitSystem unitSystem) { this.urlBuilder = urlBuilder; this.unitSystem = unitSystem; diff --git a/src/main/java/com/github/prominence/openweathermap/api/SingleResultCurrentWeatherRequestCustomizer.java b/src/main/java/com/github/prominence/openweathermap/api/request/weather/single/SingleResultCurrentWeatherRequestCustomizer.java similarity index 71% rename from src/main/java/com/github/prominence/openweathermap/api/SingleResultCurrentWeatherRequestCustomizer.java rename to src/main/java/com/github/prominence/openweathermap/api/request/weather/single/SingleResultCurrentWeatherRequestCustomizer.java index 8e071c1..0ce8577 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/SingleResultCurrentWeatherRequestCustomizer.java +++ b/src/main/java/com/github/prominence/openweathermap/api/request/weather/single/SingleResultCurrentWeatherRequestCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,12 +20,27 @@ * SOFTWARE. */ -package com.github.prominence.openweathermap.api; +package com.github.prominence.openweathermap.api.request.weather.single; +import com.github.prominence.openweathermap.api.request.RequestCustomizer; + +/** + * The current weather request customizer interface. + */ public interface SingleResultCurrentWeatherRequestCustomizer extends RequestCustomizer { + /** + * Retrieve current weather request terminator. + * + * @return the single result current weather request terminator + */ SingleResultCurrentWeatherRequestTerminator retrieve(); + /** + * Retrieve current weather async request terminator. + * + * @return the single result current weather async request terminator + */ SingleResultCurrentWeatherAsyncRequestTerminator retrieveAsync(); } diff --git a/src/main/java/com/github/prominence/openweathermap/api/impl/SingleResultCurrentWeatherRequestCustomizerImpl.java b/src/main/java/com/github/prominence/openweathermap/api/request/weather/single/SingleResultCurrentWeatherRequestCustomizerImpl.java similarity index 64% rename from src/main/java/com/github/prominence/openweathermap/api/impl/SingleResultCurrentWeatherRequestCustomizerImpl.java rename to src/main/java/com/github/prominence/openweathermap/api/request/weather/single/SingleResultCurrentWeatherRequestCustomizerImpl.java index b4ad417..f8d149e 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/impl/SingleResultCurrentWeatherRequestCustomizerImpl.java +++ b/src/main/java/com/github/prominence/openweathermap/api/request/weather/single/SingleResultCurrentWeatherRequestCustomizerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,45 +20,43 @@ * SOFTWARE. */ -package com.github.prominence.openweathermap.api.impl; +package com.github.prominence.openweathermap.api.request.weather.single; -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.request.RequestUrlBuilder; import com.github.prominence.openweathermap.api.enums.Language; import com.github.prominence.openweathermap.api.enums.UnitSystem; +/** + * The type Single result current weather request customizer. + */ public class SingleResultCurrentWeatherRequestCustomizerImpl implements SingleResultCurrentWeatherRequestCustomizer { - private RequestUrlBuilder urlBuilder; + private final RequestUrlBuilder urlBuilder; - private Accuracy accuracy; private Language language; - private UnitSystem unitSystem; + private UnitSystem unitSystem = UnitSystem.STANDARD; + /** + * Instantiates a new Single result current weather request customizer. + * + * @param urlBuilder the url builder + */ SingleResultCurrentWeatherRequestCustomizerImpl(RequestUrlBuilder urlBuilder) { this.urlBuilder = urlBuilder; } @Override public SingleResultCurrentWeatherRequestTerminator retrieve() { - applyCustomization(); + urlBuilder.applyCustomization(language, unitSystem); return new SingleResultCurrentWeatherRequestTerminatorImpl(urlBuilder, unitSystem); } @Override public SingleResultCurrentWeatherAsyncRequestTerminator retrieveAsync() { - applyCustomization(); + urlBuilder.applyCustomization(language, unitSystem); return new SingleResultCurrentWeatherAsyncRequestTerminatorImpl(urlBuilder, unitSystem); } - @Override - public SingleResultCurrentWeatherRequestCustomizer accuracy(Accuracy accuracy) { - this.accuracy = accuracy; - return this; - } - @Override public SingleResultCurrentWeatherRequestCustomizer language(Language language) { this.language = language; @@ -70,16 +68,4 @@ public class SingleResultCurrentWeatherRequestCustomizerImpl implements SingleRe this.unitSystem = unitSystem; return this; } - - private void applyCustomization() { - if (accuracy != null) { - urlBuilder.addRequestParameter("type", accuracy.getValue()); - } - if (language != null) { - urlBuilder.addRequestParameter("lang", language.getValue()); - } - if (unitSystem != null && unitSystem != UnitSystem.STANDARD) { - urlBuilder.addRequestParameter("units", unitSystem.getValue()); - } - } } \ No newline at end of file diff --git a/src/main/java/com/github/prominence/openweathermap/api/SingleResultCurrentWeatherRequestTerminator.java b/src/main/java/com/github/prominence/openweathermap/api/request/weather/single/SingleResultCurrentWeatherRequestTerminator.java similarity index 66% rename from src/main/java/com/github/prominence/openweathermap/api/SingleResultCurrentWeatherRequestTerminator.java rename to src/main/java/com/github/prominence/openweathermap/api/request/weather/single/SingleResultCurrentWeatherRequestTerminator.java index ed0ef73..499091d 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/SingleResultCurrentWeatherRequestTerminator.java +++ b/src/main/java/com/github/prominence/openweathermap/api/request/weather/single/SingleResultCurrentWeatherRequestTerminator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,9 +20,26 @@ * SOFTWARE. */ -package com.github.prominence.openweathermap.api; +package com.github.prominence.openweathermap.api.request.weather.single; -import com.github.prominence.openweathermap.api.model.Weather; +import com.github.prominence.openweathermap.api.model.weather.Weather; +import com.github.prominence.openweathermap.api.request.RequestTerminator; -public interface SingleResultCurrentWeatherRequestTerminator extends CurrentWeatherRequestTerminator { +/** + * The current weather request terminator interface. + */ +public interface SingleResultCurrentWeatherRequestTerminator extends RequestTerminator { + /** + * XML response format. + * + * @return the XML string + */ + String asXML(); + + /** + * HTML response format. + * + * @return the HTML string + */ + String asHTML(); } diff --git a/src/main/java/com/github/prominence/openweathermap/api/impl/SingleResultCurrentWeatherRequestTerminatorImpl.java b/src/main/java/com/github/prominence/openweathermap/api/request/weather/single/SingleResultCurrentWeatherRequestTerminatorImpl.java similarity index 75% rename from src/main/java/com/github/prominence/openweathermap/api/impl/SingleResultCurrentWeatherRequestTerminatorImpl.java rename to src/main/java/com/github/prominence/openweathermap/api/request/weather/single/SingleResultCurrentWeatherRequestTerminatorImpl.java index 9c93db2..76ec882 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/impl/SingleResultCurrentWeatherRequestTerminatorImpl.java +++ b/src/main/java/com/github/prominence/openweathermap/api/request/weather/single/SingleResultCurrentWeatherRequestTerminatorImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,18 +20,28 @@ * SOFTWARE. */ -package com.github.prominence.openweathermap.api.impl; +package com.github.prominence.openweathermap.api.request.weather.single; -import com.github.prominence.openweathermap.api.SingleResultCurrentWeatherRequestTerminator; +import com.github.prominence.openweathermap.api.request.RequestUrlBuilder; +import com.github.prominence.openweathermap.api.request.weather.CurrentWeatherResponseMapper; import com.github.prominence.openweathermap.api.enums.UnitSystem; -import com.github.prominence.openweathermap.api.model.Weather; +import com.github.prominence.openweathermap.api.model.weather.Weather; import com.github.prominence.openweathermap.api.utils.RequestUtils; +/** + * The type Single result current weather request terminator. + */ public class SingleResultCurrentWeatherRequestTerminatorImpl implements SingleResultCurrentWeatherRequestTerminator { - private RequestUrlBuilder urlBuilder; - private UnitSystem unitSystem; + private final RequestUrlBuilder urlBuilder; + private final UnitSystem unitSystem; + /** + * Instantiates a new Single result current weather request terminator. + * + * @param urlBuilder the url builder + * @param unitSystem the unit system + */ SingleResultCurrentWeatherRequestTerminatorImpl(RequestUrlBuilder urlBuilder, UnitSystem unitSystem) { this.urlBuilder = urlBuilder; this.unitSystem = unitSystem; 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 5ee37cc..ea8cfe5 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) 2019 Alexey Zinchenko + * Copyright (c) 2021 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 @@ -46,6 +46,27 @@ public final class RequestUtils { private RequestUtils() { } + /** + * Executes call to provided API url and retrieves response in String representation. + * + * @param url the url to make API request. + * @return response from the request in String representation. + * @throws IllegalArgumentException in case if provided parameter isn't a valid url for {@link URL} instance. + */ + public static String getResponse(String url) { + URL requestUrl; + try { + requestUrl = new URL(url); + } catch (MalformedURLException ex) { + logger.error("Invalid URL: ", ex); + throw new IllegalArgumentException(ex); + } + logger.debug("Executing OpenWeatherMap API request: " + url); + final InputStream requestInputStream = executeRequest(requestUrl); + + return convertInputStreamToString(requestInputStream); + } + /** * Executes call to provided API url and retrieves response as an InputStream instance. * @@ -53,7 +74,6 @@ public final class RequestUtils { * @return InputStream instance containing http response body. * @throws InvalidAuthTokenException in case if authentication token wasn't set or requested functionality is not permitted for its subscription plan. * @throws NoDataFoundException in case if there is no any data for requested location(s) or request is invalid. - * @throws IllegalStateException in case of unexpected response or error. */ private static InputStream executeRequest(URL requestUrl) { InputStream resultStream; @@ -82,26 +102,6 @@ public final class RequestUtils { return resultStream; } - /** - * Executes call to provided API url and retrieves response in String representation. - * - * @param url the url to make API request. - * @return response from the request in String representation. - * @throws IllegalArgumentException in case if provided parameter isn't a valid url for {@link URL} instance. - */ - public static String getResponse(String url) { - URL requestUrl; - try { - requestUrl = new URL(url); - } catch (MalformedURLException ex) { - logger.error("Invalid URL: ", ex); - throw new IllegalArgumentException(ex); - } - final InputStream requestInputStream = executeRequest(requestUrl); - - return convertInputStreamToString(requestInputStream); - } - /** * Reads the input stream line-by-line and returns its content in String representation. * @@ -124,5 +124,4 @@ public final class RequestUtils { return result.toString(); } - } diff --git a/src/test/java/com/github/prominence/openweathermap/api/ApiTest.java b/src/test/java/com/github/prominence/openweathermap/api/ApiTest.java index 443431e..9f564d7 100644 --- a/src/test/java/com/github/prominence/openweathermap/api/ApiTest.java +++ b/src/test/java/com/github/prominence/openweathermap/api/ApiTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,7 +22,6 @@ package com.github.prominence.openweathermap.api; -import com.github.prominence.openweathermap.api.impl.OpenWeatherMapClient; import org.junit.BeforeClass; public class ApiTest { diff --git a/src/test/java/com/github/prominence/openweathermap/api/CurrentWeatherIntegrationTest.java b/src/test/java/com/github/prominence/openweathermap/api/CurrentWeatherIntegrationTest.java deleted file mode 100644 index b540f50..0000000 --- a/src/test/java/com/github/prominence/openweathermap/api/CurrentWeatherIntegrationTest.java +++ /dev/null @@ -1,414 +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; - -import com.github.prominence.openweathermap.api.enums.Accuracy; -import com.github.prominence.openweathermap.api.enums.Language; -import com.github.prominence.openweathermap.api.enums.UnitSystem; -import com.github.prominence.openweathermap.api.exception.NoDataFoundException; -import com.github.prominence.openweathermap.api.exception.InvalidAuthTokenException; -import com.github.prominence.openweathermap.api.impl.OpenWeatherMapClient; -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; -import java.util.concurrent.ExecutionException; - -public class CurrentWeatherIntegrationTest extends ApiTest { - - @Test - public void whenGetSingleCurrentWeatherByCoordinateRequestAsJava_thenReturnNotNull() { - final Weather weather = getClient() - .currentWeather() - .single() - .byCoordinate(new Coordinate(5, 5)) - .accuracy(Accuracy.ACCURATE) - .unitSystem(UnitSystem.METRIC) - .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) - .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) - .unitSystem(UnitSystem.METRIC) - .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) - .unitSystem(UnitSystem.METRIC) - .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) - .unitSystem(UnitSystem.METRIC) - .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) - .unitSystem(UnitSystem.METRIC) - .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) - .unitSystem(UnitSystem.METRIC) - .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) - .unitSystem(UnitSystem.METRIC) - .retrieve() - .asHTML(); - - assert weatherHtml != null; - System.out.println(weatherHtml); - } - - @Test - public void whenGetAnySingleCurrentWeatherAsyncRequestAsXml_thenReturnNotNull() throws ExecutionException, InterruptedException { - final CompletableFuture weatherXmlFuture = getClient() - .currentWeather() - .single() - .byZipCodeAndCountry("220015", "by") - .language(Language.RUSSIAN) - .unitSystem(UnitSystem.METRIC) - .retrieveAsync() - .asXML(); - - assert weatherXmlFuture != null; - System.out.println(weatherXmlFuture.get()); - } - - @Test - public void whenGetAnySingleCurrentWeatherAsyncRequestAsJava_thenReturnNotNull() throws ExecutionException, InterruptedException { - final CompletableFuture weatherFuture = getClient() - .currentWeather() - .single() - .byZipCodeAndCountry("220015", "by") - .language(Language.RUSSIAN) - .unitSystem(UnitSystem.METRIC) - .retrieveAsync() - .asJava(); - - assert weatherFuture != null; - System.out.println(weatherFuture.get()); - } - - @Test - public void whenGetAnySingleCurrentWeatherAsyncRequestAsJson_thenReturnNotNull() throws ExecutionException, InterruptedException { - final CompletableFuture weatherFuture = getClient() - .currentWeather() - .single() - .byZipCodeAndCountry("220015", "by") - .language(Language.RUSSIAN) - .unitSystem(UnitSystem.METRIC) - .retrieveAsync() - .asJSON(); - - assert weatherFuture != null; - System.out.println(weatherFuture.get()); - } - - @Test - public void whenGetAnySingleCurrentWeatherAsyncRequestAsHtml_thenReturnNotNull() throws ExecutionException, InterruptedException { - final CompletableFuture weatherFuture = getClient() - .currentWeather() - .single() - .byZipCodeAndCountry("220015", "by") - .language(Language.RUSSIAN) - .unitSystem(UnitSystem.METRIC) - .retrieveAsync() - .asHTML(); - - assert weatherFuture != null; - System.out.println(weatherFuture.get()); - } - - @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) - .unitSystem(UnitSystem.METRIC) - .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) - .unitSystem(UnitSystem.METRIC) - .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) - .unitSystem(UnitSystem.IMPERIAL) - .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) - .unitSystem(UnitSystem.IMPERIAL) - .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) - .unitSystem(UnitSystem.IMPERIAL) - .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) - .unitSystem(UnitSystem.IMPERIAL) - .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) - .unitSystem(UnitSystem.IMPERIAL) - .retrieve() - .asHTML(); - - assert weather != null; - System.out.println(weather); - } - - @Test - public void whenGetMultipleCurrentWeatherByCoordinateAndServerClusteringAsyncRequestAsJava_thenReturnNotNull() throws ExecutionException, InterruptedException { - final CompletableFuture> weatherListFuture = getClient() - .currentWeather() - .multiple() - .byCitiesInCycle(new Coordinate(55.5, 37.5), 10, true) - .language(Language.GERMAN) - .unitSystem(UnitSystem.IMPERIAL) - .retrieveAsync() - .asJava(); - - assert weatherListFuture != null; - List weatherList = weatherListFuture.get(); - assert weatherList.size() > 0; - System.out.println(weatherList); - } - - @Test - public void whenGetMultipleCurrentWeatherByCoordinateAndServerClusteringAsyncRequestAsXml_thenReturnNotNull() throws ExecutionException, InterruptedException { - final CompletableFuture weatherFuture = getClient() - .currentWeather() - .multiple() - .byCitiesInCycle(new Coordinate(55.5, 37.5), 10, true) - .language(Language.GERMAN) - .unitSystem(UnitSystem.IMPERIAL) - .retrieveAsync() - .asXML(); - - assert weatherFuture != null; - System.out.println(weatherFuture.get()); - } - - @Test - public void whenGetMultipleCurrentWeatherByCoordinateAndServerClusteringAsyncRequestAsJson_thenReturnNotNull() throws ExecutionException, InterruptedException { - final CompletableFuture weatherFuture = getClient() - .currentWeather() - .multiple() - .byCitiesInCycle(new Coordinate(55.5, 37.5), 10, true) - .language(Language.GERMAN) - .unitSystem(UnitSystem.IMPERIAL) - .retrieveAsync() - .asJSON(); - - assert weatherFuture != null; - System.out.println(weatherFuture.get()); - } - - @Test - public void whenGetMultipleCurrentWeatherByCoordinateAndServerClusteringAsyncRequestAsHtml_thenReturnNotNull() throws ExecutionException, InterruptedException { - final CompletableFuture weatherFuture = getClient() - .currentWeather() - .multiple() - .byCitiesInCycle(new Coordinate(55.5, 37.5), 10, true) - .language(Language.GERMAN) - .unitSystem(UnitSystem.IMPERIAL) - .retrieveAsync() - .asHTML(); - - assert weatherFuture != null; - System.out.println(weatherFuture.get()); - } - - @Test(expected = InvalidAuthTokenException.class) - public void whenRequestCurrentWeatherWithInvalidApiKey_thenThrowAnException() { - OpenWeatherMapClient client = new OpenWeatherMapClient("invalidKey"); - client - .currentWeather() - .single() - .byCityName("London") - .retrieve() - .asJSON(); - } - - @Test(expected = NoDataFoundException.class) - public void whenRequestCurrentWeatherForInvalidLocation_thenThrowAnException() { - getClient() - .currentWeather() - .single() - .byCityName("InvalidCity") - .retrieve() - .asJava(); - } -} diff --git a/src/test/java/com/github/prominence/openweathermap/api/model/AtmosphericPressureUnitTest.java b/src/test/java/com/github/prominence/openweathermap/api/model/AtmosphericPressureUnitTest.java new file mode 100644 index 0000000..c8d98e4 --- /dev/null +++ b/src/test/java/com/github/prominence/openweathermap/api/model/AtmosphericPressureUnitTest.java @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2021 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. + */ + +/* + * Copyright (c) 2021 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 org.junit.Assert; +import org.junit.Test; + +public class AtmosphericPressureUnitTest { + @Test + public void whenCreatePressureWithArgs_thenValueIsSet() { + AtmosphericPressure atmosphericPressure = AtmosphericPressure.withValue(100); + Assert.assertEquals(100, atmosphericPressure.getValue(), 0.00001); + + Assert.assertEquals(0, AtmosphericPressure.withValue(0).getValue(), 0.00001); + Assert.assertEquals(100, AtmosphericPressure.withValue(100).getValue(), 0.00001); + Assert.assertEquals(55, AtmosphericPressure.withValue(55).getValue(), 0.00001); + } + + @Test + public void whenCreateTwoIdenticalInstances_thenWheyAreEquals() { + AtmosphericPressure one = AtmosphericPressure.withValue(22); + AtmosphericPressure two = AtmosphericPressure.withValue(22); + + Assert.assertTrue(one.equals(two)); + Assert.assertTrue(one.equals(one)); + Assert.assertEquals(one.hashCode(), two.hashCode()); + + one.setSeaLevelValue(333); + one.setGroundLevelValue(555); + + two.setSeaLevelValue(333); + two.setGroundLevelValue(555); + + Assert.assertTrue(one.equals(two)); + Assert.assertTrue(two.equals(one)); + Assert.assertEquals(one.hashCode(), two.hashCode()); + } + + @Test + public void whenCreateTwoDifferentInstances_thenWheyAreNotEquals() { + AtmosphericPressure one = AtmosphericPressure.withValue(5); + AtmosphericPressure two = AtmosphericPressure.withValue(88); + + Assert.assertFalse(one.equals(two)); + Assert.assertFalse(two.equals(one)); + Assert.assertFalse(one.equals(new Object())); + Assert.assertNotEquals(one.hashCode(), two.hashCode()); + + one = AtmosphericPressure.withValue(44); + one.setSeaLevelValue(44); + two = AtmosphericPressure.withValue(44); + two.setGroundLevelValue(22); + + Assert.assertFalse(one.equals(two)); + Assert.assertFalse(two.equals(one)); + + two.setSeaLevelValue(44); + + Assert.assertFalse(one.equals(two)); + Assert.assertFalse(two.equals(one)); + } + + @Test + public void whenSetValidValues_thenAllIsFine() { + AtmosphericPressure atmosphericPressure = AtmosphericPressure.withValue(14); + atmosphericPressure.setValue(0); + atmosphericPressure.setValue(15); + atmosphericPressure.setValue(100); + + atmosphericPressure.setGroundLevelValue(222); + Assert.assertEquals(222, atmosphericPressure.getGroundLevelValue(), 0.00001); + + atmosphericPressure.setSeaLevelValue(4232); + Assert.assertEquals(4232, atmosphericPressure.getSeaLevelValue(), 0.00001); + } + + @Test + public void whenCallToString_thenAllIsFine() { + final String pressureString = AtmosphericPressure.withValue(44).toString(); + Assert.assertNotNull(pressureString); + Assert.assertNotEquals("", pressureString); + } + + @Test(expected = IllegalArgumentException.class) + public void whenCreatePressureByConstructorWithInvalidDataNegative_thenThrowAnException() { + AtmosphericPressure.withValue(-33); + } + + @Test(expected = IllegalArgumentException.class) + public void whenCreatePressureAndSetInvalidDataNegative_thenThrowAnException() { + AtmosphericPressure atmosphericPressure = AtmosphericPressure.withValue(88); + atmosphericPressure.setValue(-89); + } + + @Test(expected = IllegalArgumentException.class) + public void whenSetInvalidSeaLevelPressure_thenThrowAnException() { + AtmosphericPressure atmosphericPressure = AtmosphericPressure.withValue(88); + atmosphericPressure.setSeaLevelValue(-89); + } + + @Test(expected = IllegalArgumentException.class) + public void whenSetInvalidGroundLevelPressure_thenThrowAnException() { + AtmosphericPressure atmosphericPressure = AtmosphericPressure.withValue(88); + atmosphericPressure.setGroundLevelValue(-223); + } +} diff --git a/src/test/java/com/github/prominence/openweathermap/api/model/CloudsUnitTest.java b/src/test/java/com/github/prominence/openweathermap/api/model/CloudsUnitTest.java index ff0202d..caa25dd 100644 --- a/src/test/java/com/github/prominence/openweathermap/api/model/CloudsUnitTest.java +++ b/src/test/java/com/github/prominence/openweathermap/api/model/CloudsUnitTest.java @@ -1,74 +1,121 @@ +/* + * Copyright (c) 2021 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. + */ + +/* + * Copyright (c) 2021 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 org.junit.Assert; import org.junit.Test; public class CloudsUnitTest { - @Test public void whenCreateCloudsWithValidArgs_thenValueIsSet() { - Clouds clouds = new Clouds((byte) 100); - assert clouds.getValue() == 100; + Clouds clouds = Clouds.withValue((byte) 100); + Assert.assertEquals(100, clouds.getValue()); - assert new Clouds((byte) 0).getValue() == 0; - assert new Clouds((byte) 100).getValue() == 100; - assert new Clouds((byte) 55).getValue() == 55; + Assert.assertEquals(0, Clouds.withValue((byte) 0).getValue()); + Assert.assertEquals(100, Clouds.withValue((byte) 100).getValue()); + Assert.assertEquals(55, Clouds.withValue((byte) 55).getValue()); } @Test(expected = IllegalArgumentException.class) public void whenCreateCloudsByConstructorWithInvalidDataAboveHundred_thenThrowAnException() { - new Clouds((byte) 110); + Clouds.withValue((byte) 110); } @Test(expected = IllegalArgumentException.class) public void whenCreateCloudsByConstructorWithInvalidDataNegative_thenThrowAnException() { - new Clouds((byte) -33); + Clouds.withValue((byte) -33); } @Test public void whenSetValidValues_thenAllIsFine() { - Clouds clouds = new Clouds((byte) 14); + Clouds clouds = Clouds.withValue((byte) 14); clouds.setValue((byte) 0); + Assert.assertEquals(0, clouds.getValue()); clouds.setValue((byte) 15); + Assert.assertEquals(15, clouds.getValue()); clouds.setValue((byte) 100); + Assert.assertEquals(100, clouds.getValue()); } @Test(expected = IllegalArgumentException.class) public void whenCreateCloudsAndSetInvalidDataAboveHundred_thenThrowAnException() { - Clouds clouds = new Clouds((byte) 12); + Clouds clouds = Clouds.withValue((byte) 12); clouds.setValue((byte) 112); } @Test(expected = IllegalArgumentException.class) public void whenCreateCloudsAndSetInvalidDataNegative_thenThrowAnException() { - Clouds clouds = new Clouds((byte) 88); + Clouds clouds = Clouds.withValue((byte) 88); clouds.setValue((byte) -89); } @Test public void whenCreateTwoIdenticalInstances_thenWheyAreEquals() { - Clouds one = new Clouds((byte) 22); - Clouds two = new Clouds((byte) 22); + Clouds one = Clouds.withValue((byte) 22); + Clouds two = Clouds.withValue((byte) 22); - assert one.equals(two); - assert one.equals(one); - assert one.hashCode() == two.hashCode(); + Assert.assertTrue(one.equals(two)); + Assert.assertTrue(one.equals(one)); + Assert.assertEquals(one.hashCode(), two.hashCode()); } @Test public void whenCreateTwoDifferentInstances_thenWheyAreNotEquals() { - Clouds one = new Clouds((byte) 5); - Clouds two = new Clouds((byte) 88); + Clouds one = Clouds.withValue((byte) 5); + Clouds two = Clouds.withValue((byte) 88); - assert !one.equals(two); - assert !two.equals(one); - assert !one.equals(new Object()); - assert one.hashCode() != two.hashCode(); + Assert.assertFalse(one.equals(two)); + Assert.assertFalse(two.equals(one)); + Assert.assertFalse(one.equals(new Object())); + Assert.assertNotEquals(one.hashCode(), two.hashCode()); } @Test public void whenCallToString_thenAllIsFine() { - final String cloudsString = new Clouds((byte) 44).toString(); - assert cloudsString != null; - assert !"".equals(cloudsString); + final String cloudsString = Clouds.withValue((byte) 44).toString(); + Assert.assertNotNull(cloudsString); + Assert.assertNotEquals("", cloudsString); } } diff --git a/src/test/java/com/github/prominence/openweathermap/api/model/CoordinateRectangleUnitTest.java b/src/test/java/com/github/prominence/openweathermap/api/model/CoordinateRectangleUnitTest.java index 6637ee3..68339c9 100644 --- a/src/test/java/com/github/prominence/openweathermap/api/model/CoordinateRectangleUnitTest.java +++ b/src/test/java/com/github/prominence/openweathermap/api/model/CoordinateRectangleUnitTest.java @@ -1,107 +1,170 @@ +/* + * Copyright (c) 2021 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 org.junit.Assert; import org.junit.Test; public class CoordinateRectangleUnitTest { - @Test public void whenCreateObjectWithValidArgs_thenObjectIsCreated() { - new CoordinateRectangle(44.5, 22.4, 54.4, 22.2); + CoordinateRectangle.withValues(44.5, 22.4, 54.4, 22.2); } @Test(expected = IllegalArgumentException.class) public void whenCreateObjectWithLatitudeBottomBelowMinus90_thenThrowAnException() { - new CoordinateRectangle(44.5, -91.2, 54.4, 22.2); + CoordinateRectangle.withValues(44.5, -91.2, 54.4, 22.2); } @Test(expected = IllegalArgumentException.class) public void whenCreateObjectWithLatitudeBottomAbove90_thenThrowAnException() { - new CoordinateRectangle(44.5, 91.2, 54.4, 22.2); + CoordinateRectangle.withValues(44.5, 91.2, 54.4, 22.2); } @Test(expected = IllegalArgumentException.class) public void whenCreateObjectWithLatitudeTopBelowMinus90_thenThrowAnException() { - new CoordinateRectangle(44.5, 22.4, 54.4, -92.3); + CoordinateRectangle.withValues(44.5, 22.4, 54.4, -92.3); } @Test(expected = IllegalArgumentException.class) public void whenCreateObjectWithLatitudeTopAbove90_thenThrowAnException() { - new CoordinateRectangle(44.5, 22.5, 54.4, 94.887); + CoordinateRectangle.withValues(44.5, 22.5, 54.4, 94.887); } @Test(expected = IllegalArgumentException.class) public void whenCreateObjectWithLongitudeLeftBelowMinus180_thenThrowAnException() { - new CoordinateRectangle(-944.5, 22.4, 54.4, 22.2); + CoordinateRectangle.withValues(-944.5, 22.4, 54.4, 22.2); } @Test(expected = IllegalArgumentException.class) public void whenCreateObjectWithLongitudeLeftAbove180_thenThrowAnException() { - new CoordinateRectangle(544.5, 22.4, 54.4, 22.2); + CoordinateRectangle.withValues(544.5, 22.4, 54.4, 22.2); } @Test(expected = IllegalArgumentException.class) public void whenCreateObjectWithLongitudeRightBelowMinus180_thenThrowAnException() { - new CoordinateRectangle(44.5, 22.4, -254.4, 22.2); + CoordinateRectangle.withValues(44.5, 22.4, -254.4, 22.2); } @Test(expected = IllegalArgumentException.class) public void whenCreateObjectWithLongitudeRightAbove180_thenThrowAnException() { - new CoordinateRectangle(44.5, 22.4, 354.4, 22.2); + CoordinateRectangle.withValues(44.5, 22.4, 354.4, 22.2); + } + + @Test(expected = IllegalArgumentException.class) + public void whenCreateObjectUsingBuilderWithInvalidLatitudeBottom_thenFail() { + new CoordinateRectangle.Builder() + .setLatitudeBottom(-1000); + } + + @Test(expected = IllegalArgumentException.class) + public void whenCreateObjectUsingBuilderWithInvalidLatitudeTop_thenFail() { + new CoordinateRectangle.Builder() + .setLatitudeTop(-1000); + } + + @Test(expected = IllegalArgumentException.class) + public void whenCreateObjectUsingBuilderWithInvalidLongitudeLeft_thenFail() { + new CoordinateRectangle.Builder() + .setLongitudeLeft(-1000); + } + + @Test(expected = IllegalArgumentException.class) + public void whenCreateObjectUsingBuilderWithInvalidLongitudeRight_thenFail() { + new CoordinateRectangle.Builder() + .setLongitudeRight(-1000); + } + + @Test(expected = IllegalStateException.class) + public void whenCreateObjectUsingBuilderWithoutAllPropertiesSet_thenFail() { + new CoordinateRectangle.Builder() + .setLongitudeRight(10) + .build(); + } + + @Test + public void whenCreateObjectUsingBuilderWithCorrectUsage_thenOk() { + new CoordinateRectangle.Builder() + .setLongitudeRight(10) + .setLongitudeLeft(10) + .setLatitudeTop(10) + .setLatitudeBottom(10) + .build(); } @Test public void whenGetAllParameters_thenAllIsFine() { - final CoordinateRectangle rectangle = new CoordinateRectangle(44.5, 22.4, 54.4, 22.2); - assert rectangle.getLongitudeLeft() == 44.5; - assert rectangle.getLatitudeBottom() == 22.4; - assert rectangle.getLongitudeRight() == 54.4; - assert rectangle.getLatitudeTop() == 22.2; + final CoordinateRectangle rectangle = CoordinateRectangle.withValues(44.5, 22.4, 54.4, 22.2); + Assert.assertEquals(44.5, rectangle.getLongitudeLeft(), 0.00001); + Assert.assertEquals(22.4, rectangle.getLatitudeBottom(), 0.00001); + Assert.assertEquals(54.4, rectangle.getLongitudeRight(), 0.00001); + Assert.assertEquals(22.2, rectangle.getLatitudeTop(), 0.00001); } @Test public void whenCallToString_thenAllIsFine() { - final CoordinateRectangle rectangle = new CoordinateRectangle(44.5, 22.4, 54.4, 22.2); + final CoordinateRectangle rectangle = CoordinateRectangle.withValues(44.5, 22.4, 54.4, 22.2); - assert rectangle.toString() != null; - assert !"".equals(rectangle.toString()); + Assert.assertNotNull(rectangle.toString()); + Assert.assertNotEquals("", rectangle.toString()); } @Test public void whenCallHashCode_thenAllIsFine() { - final CoordinateRectangle first = new CoordinateRectangle(44.5, 22.4, 54.4, 22.2); - final CoordinateRectangle second = new CoordinateRectangle(44.5, 22.4, 54.4, 22.2); + final CoordinateRectangle first = CoordinateRectangle.withValues(44.5, 22.4, 54.4, 22.2); + final CoordinateRectangle second = CoordinateRectangle.withValues(44.5, 22.4, 54.4, 22.2); - assert first.hashCode() == second.hashCode(); + Assert.assertEquals(first.hashCode(), second.hashCode()); - final CoordinateRectangle third = new CoordinateRectangle(44.5, 22.4, 54.4, 23.566); + final CoordinateRectangle third = CoordinateRectangle.withValues(44.5, 22.4, 54.4, 23.566); - assert first.hashCode() != third.hashCode(); - assert second.hashCode() != third.hashCode(); + Assert.assertNotEquals(first.hashCode(), third.hashCode()); + Assert.assertNotEquals(second.hashCode(), third.hashCode()); } @Test public void whenCheckEquality_thenAllIsFine() { - CoordinateRectangle first = new CoordinateRectangle(44.5, 22.4, 54.4, 22.2); - CoordinateRectangle second = new CoordinateRectangle(44.5, 22.4, 54.4, 22.2); + CoordinateRectangle first = CoordinateRectangle.withValues(44.5, 22.4, 54.4, 22.2); + CoordinateRectangle second = CoordinateRectangle.withValues(44.5, 22.4, 54.4, 22.2); - assert first.equals(second); - assert first.equals(first); - assert !first.equals(new Object()); + Assert.assertTrue(first.equals(second)); + Assert.assertTrue(first.equals(first)); + Assert.assertFalse(first.equals(new Object())); - first = new CoordinateRectangle(49.5, 22.4, 54.4, 22.2); + first = CoordinateRectangle.withValues(49.5, 22.4, 54.4, 22.2); - assert !first.equals(second); + Assert.assertFalse(first.equals(second)); - first = new CoordinateRectangle(44.5, 29.4, 54.4, 22.2); + first = CoordinateRectangle.withValues(44.5, 29.4, 54.4, 22.2); - assert !first.equals(second); + Assert.assertFalse(first.equals(second)); - first = new CoordinateRectangle(44.5, 22.4, 24.4, 22.2); + first = CoordinateRectangle.withValues(44.5, 22.4, 24.4, 22.2); - assert !first.equals(second); + Assert.assertFalse(first.equals(second)); - first = new CoordinateRectangle(44.5, 22.4, 54.4, -2.2); + first = CoordinateRectangle.withValues(44.5, 22.4, 54.4, -2.2); - assert !first.equals(second); + Assert.assertFalse(first.equals(second)); } } diff --git a/src/test/java/com/github/prominence/openweathermap/api/model/CoordinateUnitTest.java b/src/test/java/com/github/prominence/openweathermap/api/model/CoordinateUnitTest.java index 560f002..8482ce1 100644 --- a/src/test/java/com/github/prominence/openweathermap/api/model/CoordinateUnitTest.java +++ b/src/test/java/com/github/prominence/openweathermap/api/model/CoordinateUnitTest.java @@ -1,141 +1,169 @@ +/* + * Copyright (c) 2021 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 org.junit.Assert; import org.junit.Test; public class CoordinateUnitTest { - @Test public void whenCreateCoordinateWithValidValues_thenObjectCreated() { - new Coordinate(44, 53); + Coordinate.withValues(44, 53); } @Test(expected = IllegalArgumentException.class) public void whenCreateCoordinateWithInvalidLatitudeBelowMinus90_thenThrowAnException() { - new Coordinate(-333, 44); + Coordinate.withValues(-333, 44); } @Test(expected = IllegalArgumentException.class) public void whenCreateCoordinateWithInvalidLatitudeAbove90_thenThrowAnException() { - new Coordinate(223, 44); + Coordinate.withValues(223, 44); } @Test(expected = IllegalArgumentException.class) public void whenCreateCoordinateWithInvalidLongitudeBelowMinus180_thenThrowAnException() { - new Coordinate(33, -999); + Coordinate.withValues(33, -999); } @Test(expected = IllegalArgumentException.class) public void whenCreateCoordinateWithInvalidLongitudeAbove180_thenThrowAnException() { - new Coordinate(33, 999); + Coordinate.withValues(33, 999); } @Test public void whenSetValidCoordinates_thenAllIsFine() { - final Coordinate coordinate = new Coordinate(0, 0); + final Coordinate coordinate = Coordinate.withValues(0, 0); coordinate.setLatitude(-90); + Assert.assertEquals(-90, coordinate.getLatitude(), 0.00001); coordinate.setLatitude(90); + Assert.assertEquals(90, coordinate.getLatitude(), 0.00001); coordinate.setLatitude(44); + Assert.assertEquals(44, coordinate.getLatitude(), 0.00001); coordinate.setLongitude(-180); + Assert.assertEquals(-180, coordinate.getLongitude(), 0.00001); coordinate.setLongitude(180); + Assert.assertEquals(180, coordinate.getLongitude(), 0.00001); coordinate.setLongitude(130); + Assert.assertEquals(130, coordinate.getLongitude(), 0.00001); } @Test(expected = IllegalArgumentException.class) public void whenSetInvalidLatitudeBelowMinus90_thenThrowAnException() { - final Coordinate coordinate = new Coordinate(0, 0); + final Coordinate coordinate = Coordinate.withValues(0, 0); coordinate.setLatitude(-91); } @Test(expected = IllegalArgumentException.class) public void whenSetInvalidLatitudeAbove90_thenThrowAnException() { - final Coordinate coordinate = new Coordinate(0, 0); + final Coordinate coordinate = Coordinate.withValues(0, 0); coordinate.setLatitude(92); } @Test(expected = IllegalArgumentException.class) public void whenSetInvalidLongitudeBelowMinus180_thenThrowAnException() { - final Coordinate coordinate = new Coordinate(0, 0); + final Coordinate coordinate = Coordinate.withValues(0, 0); coordinate.setLongitude(-194); } @Test(expected = IllegalArgumentException.class) public void whenSetInvalidLongitudeAbove180_thenThrowAnException() { - final Coordinate coordinate = new Coordinate(0, 0); + final Coordinate coordinate = Coordinate.withValues(0, 0); coordinate.setLongitude(444); } @Test public void whenGetLatitude_thenAllIsFine() { - final Coordinate coordinate = new Coordinate(0, 0); - assert coordinate.getLatitude() == 0; + final Coordinate coordinate = Coordinate.withValues(0, 0); + Assert.assertEquals(0, coordinate.getLatitude(), 0.00001); coordinate.setLatitude(45); - assert coordinate.getLatitude() == 45; + Assert.assertEquals(45, coordinate.getLatitude(), 0.00001); } @Test public void whenGetLongitude_thenAllIsFine() { - final Coordinate coordinate = new Coordinate(0, 0); - assert coordinate.getLongitude() == 0; + final Coordinate coordinate = Coordinate.withValues(0, 0); + Assert.assertEquals(0, coordinate.getLongitude(), 0.00001); coordinate.setLongitude(33); - assert coordinate.getLongitude() == 33; + Assert.assertEquals(33, coordinate.getLongitude(), 0.00001); } @Test public void whenCallToString_thenAllIsFine() { - final Coordinate coordinate = new Coordinate(0, 0); - assert coordinate.toString() != null; - assert !"".equals(coordinate.toString()); + final Coordinate coordinate = Coordinate.withValues(0, 0); + Assert.assertNotNull(coordinate.toString()); + Assert.assertNotEquals("", coordinate.toString()); } @Test - public void RainwhenCallHashCode_thenAllIsFine() { - final Coordinate first = new Coordinate(22, 66); - final Coordinate second = new Coordinate(22, 44); + public void whenCallHashCode_thenAllIsFine() { + final Coordinate first = Coordinate.withValues(22, 66); + final Coordinate second = Coordinate.withValues(22, 44); - assert first.hashCode() != second.hashCode(); + Assert.assertNotEquals(first.hashCode(), second.hashCode()); second.setLongitude(66); - assert first.hashCode() == second.hashCode(); + Assert.assertEquals(first.hashCode(), second.hashCode()); second.setLatitude(89); - assert first.hashCode() != second.hashCode(); + Assert.assertNotEquals(first.hashCode(), second.hashCode()); first.setLatitude(89); - assert first.hashCode() == second.hashCode(); + Assert.assertEquals(first.hashCode(), second.hashCode()); } @Test public void whenCheckEquality_thenAllIsFine() { - final Coordinate first = new Coordinate(11, 99); - final Coordinate second = new Coordinate(11, 99); + final Coordinate first = Coordinate.withValues(11, 99); + final Coordinate second = Coordinate.withValues(11, 99); - assert first.equals(second); - assert first.equals(first); - assert !first.equals(new Object()); + Assert.assertTrue(first.equals(second)); + Assert.assertTrue(first.equals(first)); + Assert.assertFalse(first.equals(new Object())); first.setLatitude(34); - assert !first.equals(second); + Assert.assertFalse(first.equals(second)); second.setLatitude(34); - assert first.equals(second); + Assert.assertTrue(first.equals(second)); second.setLongitude(74); - assert !first.equals(second); + Assert.assertFalse(first.equals(second)); first.setLongitude(74); - assert first.equals(second); + Assert.assertTrue(first.equals(second)); } } diff --git a/src/main/java/com/github/prominence/openweathermap/api/impl/OpenWeatherMapClient.java b/src/test/java/com/github/prominence/openweathermap/api/model/DayTimeUnitTest.java similarity index 75% rename from src/main/java/com/github/prominence/openweathermap/api/impl/OpenWeatherMapClient.java rename to src/test/java/com/github/prominence/openweathermap/api/model/DayTimeUnitTest.java index f33f743..b920299 100644 --- a/src/main/java/com/github/prominence/openweathermap/api/impl/OpenWeatherMapClient.java +++ b/src/test/java/com/github/prominence/openweathermap/api/model/DayTimeUnitTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Alexey Zinchenko + * Copyright (c) 2021 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,15 @@ * SOFTWARE. */ -package com.github.prominence.openweathermap.api.impl; +package com.github.prominence.openweathermap.api.model; -public class OpenWeatherMapClient { +import org.junit.Assert; +import org.junit.Test; - private final String apiKey; - - public OpenWeatherMapClient(String apiKey) { - this.apiKey = apiKey; - } - - public CurrentWeatherRequesterImpl currentWeather() { - return new CurrentWeatherRequesterImpl(apiKey); +public class DayTimeUnitTest { + @Test + public void whenGetValue_thenValueIsPresentAndValid() { + Assert.assertEquals("d", DayTime.DAY.getValue()); + Assert.assertEquals("n", DayTime.NIGHT.getValue()); } } diff --git a/src/test/java/com/github/prominence/openweathermap/api/model/HumidityUnitTest.java b/src/test/java/com/github/prominence/openweathermap/api/model/HumidityUnitTest.java index 3ea3130..7d3d490 100644 --- a/src/test/java/com/github/prominence/openweathermap/api/model/HumidityUnitTest.java +++ b/src/test/java/com/github/prominence/openweathermap/api/model/HumidityUnitTest.java @@ -1,74 +1,99 @@ +/* + * Copyright (c) 2021 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 org.junit.Assert; import org.junit.Test; public class HumidityUnitTest { - @Test public void whenCreateHumidityWithArgs_thenValueIsSet() { - Humidity humidity = new Humidity((byte) 100); - assert humidity.getValue() == 100; + Humidity humidity = Humidity.withValue((byte) 100); + Assert.assertEquals(100, humidity.getValue()); - assert new Humidity((byte) 0).getValue() == 0; - assert new Humidity((byte) 100).getValue() == 100; - assert new Humidity((byte) 55).getValue() == 55; + Assert.assertEquals(0, Humidity.withValue((byte) 0).getValue()); + Assert.assertEquals(55, Humidity.withValue((byte) 55).getValue()); } @Test(expected = IllegalArgumentException.class) public void whenCreateHumidityByConstructorWithInvalidDataAboveHundred_thenThrowAnException() { - new Humidity((byte) 112); + Humidity.withValue((byte) 112); } @Test(expected = IllegalArgumentException.class) public void whenCreateHumidityByConstructorWithInvalidDataNegative_thenThrowAnException() { - new Humidity((byte) -33); + Humidity.withValue((byte) -33); } @Test public void whenSetValidValues_thenAllIsFine() { - Humidity humidity = new Humidity((byte) 14); + Humidity humidity = Humidity.withValue((byte) 14); + Assert.assertEquals(14, humidity.getValue()); humidity.setValue((byte) 0); + Assert.assertEquals(0, humidity.getValue()); humidity.setValue((byte) 15); + Assert.assertEquals(15, humidity.getValue()); humidity.setValue((byte) 100); + Assert.assertEquals(100, humidity.getValue()); } @Test(expected = IllegalArgumentException.class) public void whenCreateHumidityAndSetInvalidDataAboveHundred_thenThrowAnException() { - Humidity humidity = new Humidity((byte) 12); + Humidity humidity = Humidity.withValue((byte) 12); humidity.setValue((byte) 112); } @Test(expected = IllegalArgumentException.class) public void whenCreateHumidityAndSetInvalidDataNegative_thenThrowAnException() { - Humidity humidity = new Humidity((byte) 88); + Humidity humidity = Humidity.withValue((byte) 88); humidity.setValue((byte) -89); } @Test public void whenCreateTwoIdenticalInstances_thenWheyAreEquals() { - Humidity one = new Humidity((byte) 22); - Humidity two = new Humidity((byte) 22); + Humidity one = Humidity.withValue((byte) 22); + Humidity two = Humidity.withValue((byte) 22); - assert one.equals(two); - assert one.equals(one); - assert one.hashCode() == two.hashCode(); + Assert.assertTrue(one.equals(two)); + Assert.assertTrue(one.equals(one)); + Assert.assertEquals(one.hashCode(), two.hashCode()); } @Test public void whenCreateTwoDifferentInstances_thenWheyAreNotEquals() { - Humidity one = new Humidity((byte) 5); - Humidity two = new Humidity((byte) 88); + Humidity one = Humidity.withValue((byte) 5); + Humidity two = Humidity.withValue((byte) 88); - assert !one.equals(two); - assert !two.equals(one); - assert !one.equals(new Object()); - assert one.hashCode() != two.hashCode(); + Assert.assertFalse(one.equals(two)); + Assert.assertFalse(two.equals(one)); + Assert.assertFalse(one.equals(new Object())); + Assert.assertNotEquals(one.hashCode(), two.hashCode()); } @Test public void whenCallToString_thenAllIsFine() { - final String humidityString = new Humidity((byte) 44).toString(); - assert humidityString != null; - assert !"".equals(humidityString); + final String humidityString = Humidity.withValue((byte) 44).toString(); + Assert.assertNotNull(humidityString); + Assert.assertNotEquals("", humidityString); } } diff --git a/src/test/java/com/github/prominence/openweathermap/api/model/LocationUnitTest.java b/src/test/java/com/github/prominence/openweathermap/api/model/LocationUnitTest.java deleted file mode 100644 index 2f54a36..0000000 --- a/src/test/java/com/github/prominence/openweathermap/api/model/LocationUnitTest.java +++ /dev/null @@ -1,177 +0,0 @@ -package com.github.prominence.openweathermap.api.model; - -import org.junit.Test; - -import java.time.LocalDateTime; -import java.time.ZoneOffset; - -public class LocationUnitTest { - - @Test - public void whenCreateObjectWithValidArgs_thenObjectIsCreated() { - new Location(33, "test"); - } - - @Test(expected = IllegalArgumentException.class) - public void whenCreateObjectWithoutName_thenThrowAnException() { - new Location(33, null); - } - - @Test - public void whenSetId_thenValueIsSet() { - final Location location = new Location(33, "test"); - location.setId(55); - - assert location.getId() == 55; - } - - @Test - public void whenSetName_thenValueIsSet() { - final Location location = new Location(33, "test"); - location.setName("city"); - - assert "city".equals(location.getName()); - } - - @Test - public void whenSetCountryCode_thenValueIsSet() { - final Location location = new Location(33, "test"); - location.setCountryCode("by"); - - assert "by".equals(location.getCountryCode()); - } - - @Test - public void whenSetSunrise_thenValueIsSet() { - final Location location = new Location(33, "test"); - final LocalDateTime now = LocalDateTime.now(); - location.setSunrise(now); - - assert now.equals(location.getSunrise()); - } - - @Test - public void whenSetSunset_thenValueIsSet() { - final Location location = new Location(33, "test"); - final LocalDateTime now = LocalDateTime.now(); - location.setSunset(now); - - assert now.equals(location.getSunset()); - } - - @Test - public void whenSetZoneOffset_thenValueIsSet() { - final Location location = new Location(33, "test"); - final ZoneOffset offset = ZoneOffset.UTC; - location.setZoneOffset(offset); - - assert offset.equals(location.getZoneOffset()); - } - - @Test - public void whenSetCoordinate_thenValueIsSet() { - final Location location = new Location(33, "test"); - final Coordinate coordinate = new Coordinate(33.2, 64.2); - location.setCoordinate(coordinate); - - assert coordinate.equals(location.getCoordinate()); - } - - @Test - public void whenCallToString_thenAllIsFine() { - final Location location = new Location(44, "test"); - - assert !"".equals(location.toString()); - - location.setCoordinate(new Coordinate(33.2, 56.3)); - - assert !"".equals(location.toString()); - - location.setCountryCode("TN"); - - assert !"".equals(location.toString()); - } - - @Test - public void whenCallHashCode_thenAllIsFine() { - final Location one = new Location(44, "test"); - final Location two = new Location(44, "test"); - - assert one.hashCode() == two.hashCode(); - - two.setName("112"); - - assert one.hashCode() != two.hashCode(); - } - - @Test - public void whenCheckEquality_thenAllIsFine() { - final Location one = new Location(44, "test"); - final Location two = new Location(44, "test"); - - assert one.equals(one); - assert !one.equals(new Object()); - - assert one.equals(two); - - two.setId(23); - - assert !one.equals(two); - - one.setId(23); - - assert one.equals(two); - - one.setName("23"); - - assert !one.equals(two); - - two.setName("23"); - - assert one.equals(two); - - one.setCountryCode("11"); - - assert !one.equals(two); - - two.setCountryCode("11"); - - assert one.equals(two); - - final LocalDateTime now = LocalDateTime.now(); - - one.setSunrise(now); - - assert !one.equals(two); - - two.setSunrise(now); - - assert one.equals(two); - - one.setSunset(now); - - assert !one.equals(two); - - two.setSunset(now); - - assert one.equals(two); - - one.setZoneOffset(ZoneOffset.UTC); - - assert !one.equals(two); - - two.setZoneOffset(ZoneOffset.UTC); - - assert one.equals(two); - - final Coordinate coordinate = new Coordinate(33.5, -22.4); - - one.setCoordinate(coordinate); - - assert !one.equals(two); - - two.setCoordinate(coordinate); - - assert one.equals(two); - } -} diff --git a/src/test/java/com/github/prominence/openweathermap/api/model/PressureUnitTest.java b/src/test/java/com/github/prominence/openweathermap/api/model/PressureUnitTest.java deleted file mode 100644 index 312e3cc..0000000 --- a/src/test/java/com/github/prominence/openweathermap/api/model/PressureUnitTest.java +++ /dev/null @@ -1,104 +0,0 @@ -package com.github.prominence.openweathermap.api.model; - -import org.junit.Test; - -public class PressureUnitTest { - - @Test - public void whenCreatePressureWithArgs_thenValueIsSet() { - Pressure pressure = new Pressure(100); - assert pressure.getValue() == 100; - - assert new Pressure(0).getValue() == 0; - assert new Pressure(100).getValue() == 100; - assert new Pressure(55).getValue() == 55; - } - - @Test - public void whenCreateTwoIdenticalInstances_thenWheyAreEquals() { - Pressure one = new Pressure(22); - Pressure two = new Pressure(22); - - assert one.equals(two); - assert one.equals(one); - assert one.hashCode() == two.hashCode(); - - one.setSeaLevelValue(333); - one.setGroundLevelValue(555); - - two.setSeaLevelValue(333); - two.setGroundLevelValue(555); - - assert one.equals(two); - assert two.equals(one); - assert one.hashCode() == two.hashCode(); - } - - @Test - public void whenCreateTwoDifferentInstances_thenWheyAreNotEquals() { - Pressure one = new Pressure(5); - Pressure two = new Pressure(88); - - assert !one.equals(two); - assert !two.equals(one); - assert !one.equals(new Object()); - assert one.hashCode() != two.hashCode(); - - one = new Pressure(44); - one.setSeaLevelValue(44); - two = new Pressure(44); - two.setGroundLevelValue(22); - - assert !one.equals(two); - assert !two.equals(one); - - two.setSeaLevelValue(44); - - assert !one.equals(two); - assert !two.equals(one); - } - - @Test - public void whenSetValidValues_thenAllIsFine() { - Pressure pressure = new Pressure(14); - pressure.setValue(0); - pressure.setValue(15); - pressure.setValue(100); - - pressure.setGroundLevelValue(222); - assert pressure.getGroundLevelValue() == 222; - - pressure.setSeaLevelValue(4232); - assert pressure.getSeaLevelValue() == 4232; - } - - @Test - public void whenCallToString_thenAllIsFine() { - final String pressureString = new Pressure(44).toString(); - assert pressureString != null; - assert !"".equals(pressureString); - } - - @Test(expected = IllegalArgumentException.class) - public void whenCreatePressureByConstructorWithInvalidDataNegative_thenThrowAnException() { - new Pressure(-33); - } - - @Test(expected = IllegalArgumentException.class) - public void whenCreatePressureAndSetInvalidDataNegative_thenThrowAnException() { - Pressure pressure = new Pressure(88); - pressure.setValue(-89); - } - - @Test(expected = IllegalArgumentException.class) - public void whenSetInvalidSeaLevelPressure_thenThrowAnException() { - Pressure pressure = new Pressure(88); - pressure.setSeaLevelValue(-89); - } - - @Test(expected = IllegalArgumentException.class) - public void whenSetInvalidGroundLevelPressure_thenThrowAnException() { - Pressure pressure = new Pressure(88); - pressure.setGroundLevelValue(-223); - } -} diff --git a/src/test/java/com/github/prominence/openweathermap/api/model/RainUnitTest.java b/src/test/java/com/github/prominence/openweathermap/api/model/RainUnitTest.java deleted file mode 100644 index e0fa944..0000000 --- a/src/test/java/com/github/prominence/openweathermap/api/model/RainUnitTest.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.github.prominence.openweathermap.api.model; - -import org.junit.Test; - -public class RainUnitTest { - - @Test - public void whenCreateRainWithValidArgs_thenObjectIsCreated() { - new Rain(2222.3, 324234.3); - new Rain(null, -213123.4); - new Rain(-123123.123, null); - new Rain(null, null); - } - - @Test - public void whenSetValues_thenTheyAreSet() { - final Rain snow = new Rain(null, null); - - assert snow.getOneHourRainLevel() == null; - assert snow.getThreeHourRainLevel() == null; - - snow.setOneHourRainLevel(33.3); - assert snow.getOneHourRainLevel() == 33.3; - - snow.setThreeHourRainLevel(55.5); - assert snow.getThreeHourRainLevel() == 55.5; - } - - @Test - public void whenCallToString_thenAllIsFine() { - final Rain snow = new Rain(); - - assert snow.toString() != null; - assert "unknown".equals(snow.toString()); - - snow.setThreeHourRainLevel(33.5); - - assert snow.toString() != null; - assert !"unknown".equals(snow.toString()); - - snow.setOneHourRainLevel(22.2); - - assert snow.toString() != null; - assert !"unknown".equals(snow.toString()); - - snow.setThreeHourRainLevel(null); - - assert snow.toString() != null; - assert !"unknown".equals(snow.toString()); - } - - @Test - public void whenCallHashCode_thenAllIsFine() { - final Rain first = new Rain(); - final Rain second = new Rain(); - - assert first.hashCode() == second.hashCode(); - - second.setThreeHourRainLevel(11.0); - - assert first.hashCode() != second.hashCode(); - - first.setThreeHourRainLevel(11.0); - - assert first.hashCode() == second.hashCode(); - - first.setOneHourRainLevel(333.2); - - assert first.hashCode() != second.hashCode(); - - second.setOneHourRainLevel(333.2); - - assert first.hashCode() == second.hashCode(); - } - - @Test - public void whenCheckEquality_thenAllIsFine() { - final Rain first = new Rain(); - final Rain second = new Rain(); - - assert first.equals(second); - assert first.equals(first); - assert !first.equals(new Object()); - - first.setOneHourRainLevel(0.34); - - assert !first.equals(second); - - second.setOneHourRainLevel(0.34); - - assert first.equals(second); - - second.setThreeHourRainLevel(66.7); - - assert !first.equals(second); - - first.setThreeHourRainLevel(66.7); - - assert first.equals(second); - } -} diff --git a/src/test/java/com/github/prominence/openweathermap/api/model/SnowUnitTest.java b/src/test/java/com/github/prominence/openweathermap/api/model/SnowUnitTest.java deleted file mode 100644 index a012e08..0000000 --- a/src/test/java/com/github/prominence/openweathermap/api/model/SnowUnitTest.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.github.prominence.openweathermap.api.model; - -import org.junit.Test; - -public class SnowUnitTest { - - @Test - public void whenCreateSnowWithValidArgs_ObjectIsCreated() { - new Snow(2222.3, 324234.3); - new Snow(null, -213123.4); - new Snow(-123123.123, null); - new Snow(null, null); - } - - @Test - public void whenSetValues_thenTheyAreSet() { - final Snow snow = new Snow(null, null); - - assert snow.getOneHourSnowLevel() == null; - assert snow.getThreeHourSnowLevel() == null; - - snow.setOneHourSnowLevel(33.3); - assert snow.getOneHourSnowLevel() == 33.3; - - snow.setThreeHourSnowLevel(55.5); - assert snow.getThreeHourSnowLevel() == 55.5; - } - - @Test - public void whenCallToString_thenAllIsFine() { - final Snow snow = new Snow(); - - assert snow.toString() != null; - assert "unknown".equals(snow.toString()); - - snow.setThreeHourSnowLevel(33.5); - - assert snow.toString() != null; - assert !"unknown".equals(snow.toString()); - - snow.setOneHourSnowLevel(22.2); - - assert snow.toString() != null; - assert !"unknown".equals(snow.toString()); - - snow.setThreeHourSnowLevel(null); - - assert snow.toString() != null; - assert !"unknown".equals(snow.toString()); - } - - @Test - public void RainwhenCallHashCode_thenAllIsFine() { - final Snow first = new Snow(); - final Snow second = new Snow(); - - assert first.hashCode() == second.hashCode(); - - second.setThreeHourSnowLevel(11.0); - - assert first.hashCode() != second.hashCode(); - - first.setThreeHourSnowLevel(11.0); - - assert first.hashCode() == second.hashCode(); - - first.setOneHourSnowLevel(333.2); - - assert first.hashCode() != second.hashCode(); - - second.setOneHourSnowLevel(333.2); - - assert first.hashCode() == second.hashCode(); - } - - @Test - public void whenCheckEquality_thenAllIsFine() { - final Snow first = new Snow(); - final Snow second = new Snow(); - - assert first.equals(second); - assert first.equals(first); - assert !first.equals(new Object()); - - first.setOneHourSnowLevel(0.34); - - assert !first.equals(second); - - second.setOneHourSnowLevel(0.34); - - assert first.equals(second); - - second.setThreeHourSnowLevel(66.7); - - assert !first.equals(second); - - first.setThreeHourSnowLevel(66.7); - - assert first.equals(second); - } -} diff --git a/src/test/java/com/github/prominence/openweathermap/api/model/TemperatureUnitTest.java b/src/test/java/com/github/prominence/openweathermap/api/model/TemperatureUnitTest.java index 198412c..aee2034 100644 --- a/src/test/java/com/github/prominence/openweathermap/api/model/TemperatureUnitTest.java +++ b/src/test/java/com/github/prominence/openweathermap/api/model/TemperatureUnitTest.java @@ -1,121 +1,174 @@ +/* + * Copyright (c) 2021 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 org.junit.Assert; import org.junit.Test; public class TemperatureUnitTest { - @Test public void whenCreateObjectWithValidArgs_thenObjectIsCreated() { - new Temperature(22.2, "K"); + Temperature.withValue(22.2, "K"); } @Test(expected = IllegalArgumentException.class) public void whenCreateObjectWithEmptyUnit_thenThrowAnException() { - new Temperature(22.2, null); + Temperature.withValue(22.2, null); } @Test public void whenSetValue_thenAllIsFine() { - final Temperature temperature = new Temperature(22.2, "K"); + final Temperature temperature = Temperature.withValue(22.2, "K"); temperature.setValue(55.44); - assert temperature.getValue() == 55.44; + Assert.assertEquals(55.44, temperature.getValue(), 0.00001); } @Test public void whenSetMaximumTemperature_thenAllIsOk() { - final Temperature temperature = new Temperature(22.2, "K"); + final Temperature temperature = Temperature.withValue(22.2, "K"); temperature.setMaxTemperature(44.4); - assert temperature.getMaxTemperature() == 44.4; + Assert.assertEquals(44.4, temperature.getMaxTemperature(), 0.00001); temperature.setMaxTemperature(null); - assert temperature.getMaxTemperature() == null; + Assert.assertNull(temperature.getMaxTemperature()); } @Test public void whenSetMinimumTemperature_thenAllIsOk() { - final Temperature temperature = new Temperature(22.2, "K"); + final Temperature temperature = Temperature.withValue(22.2, "K"); temperature.setMinTemperature(33.2); - assert temperature.getMinTemperature() == 33.2; + Assert.assertEquals(33.2, temperature.getMinTemperature(), 0.00001); temperature.setMinTemperature(null); - assert temperature.getMinTemperature() == null; + Assert.assertNull(temperature.getMinTemperature()); + } + + @Test + public void whenSetFeelsLikeTemperature_thenAllIsOk() { + final Temperature temperature = Temperature.withValue(22.2, "K"); + temperature.setFeelsLike(22.3); + + Assert.assertEquals(22.3, temperature.getFeelsLike(), 0.00001); + + temperature.setFeelsLike(null); + + Assert.assertNull(temperature.getFeelsLike()); } @Test public void whenSetNonNullUnit_thenAllIsOk() { - final Temperature temperature = new Temperature(22.2, "K"); + final Temperature temperature = Temperature.withValue(22.2, "K"); temperature.setUnit("test"); - assert "test".equals(temperature.getUnit()); + Assert.assertTrue("test".equals(temperature.getUnit())); } @Test(expected = IllegalArgumentException.class) public void whenSetNullUnit_thenThrowAnException() { - final Temperature temperature = new Temperature(22.2, "K"); + final Temperature temperature = Temperature.withValue(22.2, "K"); temperature.setUnit(null); } @Test public void whenCallToString_thenAllIsFine() { - final Temperature temperature = new Temperature(22.2, "K"); + final Temperature temperature = Temperature.withValue(22.2, "K"); - assert !"".equals(temperature.toString()); + Assert.assertNotNull(temperature.toString()); + Assert.assertNotEquals("", temperature.toString()); temperature.setMinTemperature(11.2); - assert !"".equals(temperature.toString()); + Assert.assertNotNull(temperature.toString()); + Assert.assertNotEquals("", temperature.toString()); temperature.setMaxTemperature(44.3); - assert !"".equals(temperature.toString()); + Assert.assertNotNull(temperature.toString()); + Assert.assertNotEquals("", temperature.toString()); + + temperature.setFeelsLike(22.4); + + Assert.assertNotNull(temperature.toString()); + Assert.assertNotEquals("", temperature.toString()); } @Test public void whenCallHashCode_thenAllIsFine() { - final Temperature one = new Temperature(22.2, "K"); - final Temperature two = new Temperature(22.2, "K"); + final Temperature one = Temperature.withValue(22.2, "K"); + final Temperature two = Temperature.withValue(22.2, "K"); - assert one.hashCode() == two.hashCode(); + Assert.assertEquals(one.hashCode(), two.hashCode()); } @Test public void whenCheckEquality_thenAllIsFine() { - final Temperature one = new Temperature(22.2, "K"); - final Temperature two = new Temperature(21.2, "K"); + final Temperature one = Temperature.withValue(22.2, "K"); + final Temperature two = Temperature.withValue(21.2, "K"); - assert one.equals(one); - assert !one.equals(new Object()); - - assert !one.equals(two); + Assert.assertTrue(one.equals(one)); + Assert.assertFalse(one.equals(new Object())); + Assert.assertFalse(one.equals(two)); one.setValue(21.2); - assert one.equals(two); + Assert.assertTrue(one.equals(two)); one.setMaxTemperature(33.56); - assert !one.equals(two); + Assert.assertFalse(one.equals(two)); two.setMaxTemperature(33.56); - assert one.equals(two); + Assert.assertTrue(one.equals(two)); one.setMinTemperature(11.54); - assert !one.equals(two); + Assert.assertFalse(one.equals(two)); two.setMinTemperature(11.54); - assert one.equals(two); + Assert.assertTrue(one.equals(two)); two.setUnit("U"); - assert !one.equals(two); + Assert.assertFalse(one.equals(two)); + + one.setUnit("U"); + + Assert.assertTrue(one.equals(two)); + + one.setFeelsLike(22.3); + + Assert.assertFalse(one.equals(two)); + + two.setFeelsLike(22.3); + + Assert.assertTrue(one.equals(two)); } } diff --git a/src/test/java/com/github/prominence/openweathermap/api/model/WeatherUnitTest.java b/src/test/java/com/github/prominence/openweathermap/api/model/WeatherUnitTest.java deleted file mode 100644 index 4a5ea73..0000000 --- a/src/test/java/com/github/prominence/openweathermap/api/model/WeatherUnitTest.java +++ /dev/null @@ -1,287 +0,0 @@ -package com.github.prominence.openweathermap.api.model; - -import org.junit.Test; - -import java.time.LocalDateTime; - -public class WeatherUnitTest { - - @Test - public void whenCreateObjectWithValidArgs_thenObjectIsCreated() { - new Weather("state", "desc"); - } - - @Test(expected = IllegalArgumentException.class) - public void whenCreateObjectWithoutState_thenThrowAnException() { - new Weather(null, "desc"); - } - - @Test(expected = IllegalArgumentException.class) - public void whenCreateObjectWithoutDescription_thenThrowAnException() { - new Weather("state", null); - } - - @Test - public void whenSetState_thenValueIsSet() { - final Weather weather = new Weather("state", "desc"); - weather.setState("test"); - - assert "test".equals(weather.getState()); - } - - @Test(expected = IllegalArgumentException.class) - public void whenSetNullState_thenThrowAnException() { - final Weather weather = new Weather("state", "desc"); - weather.setState(null); - } - - @Test - public void whenSetDescription_thenValueIsSet() { - final Weather weather = new Weather("state", "desc"); - weather.setDescription("test"); - - assert "test".equals(weather.getDescription()); - } - - @Test(expected = IllegalArgumentException.class) - public void whenSetNullDescription_thenThrowAnException() { - final Weather weather = new Weather("state", "desc"); - weather.setDescription(null); - } - - @Test - public void whenSetIconUrl_thenValueIsSet() { - final Weather weather = new Weather("state", "desc"); - weather.setWeatherIconUrl("test"); - - assert "test".equals(weather.getWeatherIconUrl()); - } - - @Test - public void whenSetRequestedOn_thenValueIsSet() { - final Weather weather = new Weather("state", "desc"); - final LocalDateTime now = LocalDateTime.now(); - weather.setRequestedOn(now); - - assert now.equals(weather.getRequestedOn()); - } - - @Test - public void whenSetTemperature_thenValueIsSet() { - final Weather weather = new Weather("state", "desc"); - final Temperature temperature = new Temperature(22.3, "a"); - weather.setTemperature(temperature); - - assert temperature.equals(weather.getTemperature()); - } - - @Test - public void whenSetPressure_thenValueIsSet() { - final Weather weather = new Weather("state", "desc"); - final Pressure pressure = new Pressure(33.2); - weather.setPressure(pressure); - - assert pressure.equals(weather.getPressure()); - } - - @Test - public void whenSetHumidity_thenValueIsSet() { - final Weather weather = new Weather("state", "desc"); - final Humidity humidity = new Humidity((byte) 44); - weather.setHumidity(humidity); - - assert humidity.equals(weather.getHumidity()); - } - - @Test - public void whenSetWind_thenValueIsSet() { - final Weather weather = new Weather("state", "desc"); - final Wind wind = new Wind(22.2, "a"); - weather.setWind(wind); - - assert wind.equals(weather.getWind()); - } - - @Test - public void whenSetRain_thenValueIsSet() { - final Weather weather = new Weather("state", "desc"); - final Rain rain = new Rain(); - weather.setRain(rain); - - assert rain.equals(weather.getRain()); - } - - @Test - public void whenSetSnow_thenValueIsSet() { - final Weather weather = new Weather("state", "desc"); - final Snow snow = new Snow(); - weather.setSnow(snow); - - assert snow.equals(weather.getSnow()); - } - - @Test - public void whenSetClouds_thenValueIsSet() { - final Weather weather = new Weather("state", "desc"); - final Clouds clouds = new Clouds((byte) 33); - weather.setClouds(clouds); - - assert clouds.equals(weather.getClouds()); - } - - @Test - public void whenSetLocation_thenValueIsSet() { - final Weather weather = new Weather("state", "desc"); - final Location location = new Location(22, "asd"); - weather.setLocation(location); - - assert location.equals(weather.getLocation()); - } - - @Test - public void whenCallToString_thenAllIsFine() { - final Weather weather = new Weather("state", "desc"); - final Location location = new Location(12312, "asd"); - final Temperature temperature = new Temperature(33.2, "asd"); - final Pressure pressure = new Pressure(44.4); - final Clouds clouds = new Clouds((byte) 55); - final Rain rain = new Rain(33.2, null); - final Snow snow = new Snow(33.1, null); - - assert !"".equals(weather.toString()); - weather.setLocation(location); - assert !"".equals(weather.toString()); - location.setCountryCode("3d"); - assert !"".equals(weather.toString()); - weather.setTemperature(temperature); - assert !"".equals(weather.toString()); - weather.setPressure(pressure); - assert !"".equals(weather.toString()); - weather.setClouds(clouds); - assert !"".equals(weather.toString()); - weather.setRain(rain); - assert !"".equals(weather.toString()); - weather.setSnow(snow); - assert !"".equals(weather.toString()); - } - - @Test - public void whenCallHashCode_thenAllIsFine() { - final Weather one = new Weather("state", "desc"); - final Weather two = new Weather("state", "desc"); - - assert one.hashCode() == two.hashCode(); - - two.setDescription("112"); - - assert one.hashCode() != two.hashCode(); - } - - @Test - public void whenCheckEquality_thenAllIsFine() { - final Weather one = new Weather("state", "desc"); - final Weather two = new Weather("state1", "desc1"); - - assert one.equals(one); - assert !one.equals(new Object()); - - assert !one.equals(two); - - two.setState("state"); - - assert !one.equals(two); - - two.setDescription("desc"); - - assert one.equals(two); - - one.setWeatherIconUrl("1"); - - assert !one.equals(two); - - two.setWeatherIconUrl("1"); - - assert one.equals(two); - - final LocalDateTime now = LocalDateTime.now(); - one.setRequestedOn(now); - - assert !one.equals(two); - - two.setRequestedOn(now); - - assert one.equals(two); - - final Temperature temperature = new Temperature(33.2, "as"); - one.setTemperature(temperature); - - assert !one.equals(two); - - two.setTemperature(temperature); - - assert one.equals(two); - - final Pressure pressure = new Pressure(33.33); - one.setPressure(pressure); - - assert !one.equals(two); - - two.setPressure(pressure); - - assert one.equals(two); - - final Humidity humidity = new Humidity((byte) 33); - one.setHumidity(humidity); - - assert !one.equals(two); - - two.setHumidity(humidity); - - assert one.equals(two); - - final Wind wind = new Wind(33.6, "asd"); - one.setWind(wind); - - assert !one.equals(two); - - two.setWind(wind); - - assert one.equals(two); - - final Rain rain = new Rain(); - one.setRain(rain); - - assert !one.equals(two); - - two.setRain(rain); - - assert one.equals(two); - - final Snow snow = new Snow(); - one.setSnow(snow); - - assert !one.equals(two); - - two.setSnow(snow); - - assert one.equals(two); - - final Clouds clouds = new Clouds((byte) 33); - one.setClouds(clouds); - - assert !one.equals(two); - - two.setClouds(clouds); - - assert one.equals(two); - - final Location location = new Location(231, "asda"); - one.setLocation(location); - - assert !one.equals(two); - - two.setLocation(location); - - assert one.equals(two); - } -} diff --git a/src/test/java/com/github/prominence/openweathermap/api/model/WindUnitTest.java b/src/test/java/com/github/prominence/openweathermap/api/model/WindUnitTest.java deleted file mode 100644 index bf46150..0000000 --- a/src/test/java/com/github/prominence/openweathermap/api/model/WindUnitTest.java +++ /dev/null @@ -1,157 +0,0 @@ -package com.github.prominence.openweathermap.api.model; - -import org.junit.Test; - -public class WindUnitTest { - @Test - public void whenCreateWindWithValidArgs_thenValueIsSet() { - assert new Wind(44, "ms").getSpeed() == 44.0; - } - - @Test(expected = IllegalArgumentException.class) - public void whenCreateWindWithInvalidSpeedArg_thenThrowAnException() { - new Wind(-21, "a"); - } - - @Test(expected = IllegalArgumentException.class) - public void whenCreateWindWithInvalidUnitArg_thenThrowAnException() { - new Wind(342, null); - } - - @Test - public void whenSetValidSpeed_thenValueIsSet() { - final Wind wind = new Wind(33, "as"); - - assert wind.getSpeed() == 33; - - wind.setSpeed(0); - - assert wind.getSpeed() == 0; - - wind.setSpeed(3656); - - assert wind.getSpeed() == 3656; - } - - @Test(expected = IllegalArgumentException.class) - public void whenSetInvalidSpeedBelow0_thenThrowAnException() { - final Wind wind = new Wind(33, "as"); - - assert wind.getSpeed() == 33; - - wind.setSpeed(-22); - - assert false; - } - - @Test - public void whenSetValidDegrees_thenValueIsSet() { - final Wind wind = new Wind(33, "as"); - - assert wind.getDegrees() == null; - - wind.setDegrees(22); - - assert wind.getDegrees() == 22; - - wind.setDegrees(0); - - assert wind.getDegrees() == 0; - - wind.setDegrees(360); - - assert wind.getDegrees() == 360; - } - - @Test(expected = IllegalArgumentException.class) - public void whenSetInvalidDegreesBelow0_thenThrowAnException() { - final Wind wind = new Wind(33, "as"); - wind.setDegrees(-32); - } - - @Test(expected = IllegalArgumentException.class) - public void whenSetInvalidDegreesAbove360_thenThrowAnException() { - final Wind wind = new Wind(33, "as"); - wind.setDegrees(378); - } - - @Test - public void whenSetNonNullUnit_thenValueIsSet() { - final Wind wind = new Wind(33, "as"); - - assert "as".equals(wind.getUnit()); - - wind.setUnit("myUnit"); - - assert "myUnit".equals(wind.getUnit()); - } - - @Test(expected = IllegalArgumentException.class) - public void whenSetNullUnit_thenThrowAnException() { - final Wind wind = new Wind(33, "as"); - - wind.setUnit(null); - } - - @Test - public void whenCallToString_thenAllIsFine() { - final Wind wind = new Wind(302, "a"); - - assert wind.toString() != null; - - wind.setDegrees(22); - - assert wind.toString() != null && !"".equals(wind.toString()); - } - - @Test - public void RainwhenCallHashCode_thenAllIsFine() { - final Wind first = new Wind(22, "a"); - final Wind second = new Wind(22, "b"); - - assert first.hashCode() != second.hashCode(); - - second.setUnit("a"); - - assert first.hashCode() == second.hashCode(); - - second.setSpeed(33); - - assert first.hashCode() != second.hashCode(); - - first.setSpeed(333); - - assert first.hashCode() != second.hashCode(); - - first.setSpeed(33); - - assert first.hashCode() == second.hashCode(); - } - - @Test - public void whenCheckEquality_thenAllIsFine() { - final Wind first = new Wind(11, "a"); - final Wind second = new Wind(11, "a"); - - assert first.equals(second); - assert first.equals(first); - assert !first.equals(new Object()); - - first.setDegrees(34); - - assert !first.equals(second); - - second.setDegrees(34); - - assert first.equals(second); - - second.setUnit("v"); - - assert !first.equals(second); - - first.setUnit("v"); - first.setSpeed(second.getSpeed() + 4); - - assert !first.equals(second); - } -} diff --git a/src/test/java/com/github/prominence/openweathermap/api/model/forecast/ForecastUnitTest.java b/src/test/java/com/github/prominence/openweathermap/api/model/forecast/ForecastUnitTest.java new file mode 100644 index 0000000..dd360b1 --- /dev/null +++ b/src/test/java/com/github/prominence/openweathermap/api/model/forecast/ForecastUnitTest.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2021 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.forecast; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.ArrayList; + +public class ForecastUnitTest { + @Test + public void whenLocationIsSet_thenAllIsOk() { + final Forecast forecast = new Forecast(); + forecast.setLocation(Location.withValues(2, "asd")); + + Assert.assertNotNull(forecast.getLocation()); + } + + @Test + public void whenWeatherForecastsAreSet_thenAllIsOk() { + final Forecast forecast = new Forecast(); + forecast.setWeatherForecasts(new ArrayList<>()); + + Assert.assertNotNull(forecast.getWeatherForecasts()); + } + + @Test + public void whenCalculateHashCode_thenAllIsOk() { + final Forecast one = new Forecast(); + final Forecast two = new Forecast(); + + Assert.assertEquals(one.hashCode(), two.hashCode()); + + one.setLocation(Location.withValues(22, "444")); + + Assert.assertNotEquals(one.hashCode(), two.hashCode()); + } + + @Test + public void whenCheckEquality_thenAllIsOk() { + final Forecast one = new Forecast(); + final Forecast two = new Forecast(); + + Assert.assertTrue(one.equals(one)); + Assert.assertFalse(one.equals(null)); + Assert.assertTrue(one.equals(two)); + Assert.assertFalse(one.equals(new Object())); + + one.setLocation(Location.withValues(22, "234")); + + Assert.assertFalse(one.equals(two)); + + two.setLocation(one.getLocation()); + + Assert.assertTrue(one.equals(two)); + + one.setWeatherForecasts(new ArrayList<>()); + + Assert.assertFalse(one.equals(two)); + } +} diff --git a/src/test/java/com/github/prominence/openweathermap/api/model/forecast/LocationUnitTest.java b/src/test/java/com/github/prominence/openweathermap/api/model/forecast/LocationUnitTest.java new file mode 100644 index 0000000..3aba580 --- /dev/null +++ b/src/test/java/com/github/prominence/openweathermap/api/model/forecast/LocationUnitTest.java @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2021 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.forecast; + +import com.github.prominence.openweathermap.api.model.Coordinate; +import org.junit.Assert; +import org.junit.Test; + +import java.time.LocalDateTime; +import java.time.ZoneOffset; + +public class LocationUnitTest { + @Test + public void whenCreateObjectWithValidArgs_thenObjectIsCreated() { + Location.withValues(33, "test"); + } + + @Test(expected = IllegalArgumentException.class) + public void whenCreateObjectWithoutName_thenThrowAnException() { + Location.withValues(33, null); + } + + @Test + public void whenSetId_thenValueIsSet() { + final Location location = Location.withValues(33, "test"); + location.setId(55); + + Assert.assertEquals(55, location.getId()); + } + + @Test + public void whenSetName_thenValueIsSet() { + final Location location = Location.withValues(33, "test"); + location.setName("city"); + + Assert.assertEquals("city", location.getName()); + } + + @Test + public void whenSetCountryCode_thenValueIsSet() { + final Location location = Location.withValues(33, "test"); + location.setCountryCode("by"); + + Assert.assertEquals("by", location.getCountryCode()); + } + + @Test + public void whenSetSunrise_thenValueIsSet() { + final Location location = Location.withValues(33, "test"); + final LocalDateTime now = LocalDateTime.now(); + location.setSunrise(now); + + Assert.assertEquals(now, location.getSunrise()); + } + + @Test + public void whenSetSunset_thenValueIsSet() { + final Location location = Location.withValues(33, "test"); + final LocalDateTime now = LocalDateTime.now(); + location.setSunset(now); + + Assert.assertEquals(now, location.getSunset()); + } + + @Test + public void whenSetZoneOffset_thenValueIsSet() { + final Location location = Location.withValues(33, "test"); + final ZoneOffset offset = ZoneOffset.UTC; + location.setZoneOffset(offset); + + Assert.assertEquals(offset, location.getZoneOffset()); + } + + @Test + public void whenSetCoordinate_thenValueIsSet() { + final Location location = Location.withValues(33, "test"); + final Coordinate coordinate = Coordinate.withValues(33.2, 64.2); + location.setCoordinate(coordinate); + + Assert.assertEquals(coordinate, location.getCoordinate()); + } + + @Test + public void whenSetPopulation_thenValueIsSet() { + final Location location = Location.withValues(33, "test"); + location.setPopulation(3444L); + + Assert.assertEquals(3444L, location.getPopulation().longValue()); + } + + @Test + public void whenCallToString_thenAllIsFine() { + final Location location = Location.withValues(44, "test"); + + Assert.assertNotEquals("", location.toString()); + + location.setCoordinate(Coordinate.withValues(33.2, 56.3)); + + Assert.assertNotEquals("", location.toString()); + + location.setCountryCode("TN"); + + Assert.assertNotEquals("", location.toString()); + Assert.assertNotNull(location.toString()); + + location.setPopulation(34343L); + Assert.assertNotEquals("", location.toString()); + Assert.assertNotNull(location.toString()); + } + + @Test + public void whenCallHashCode_thenAllIsFine() { + final Location one = Location.withValues(44, "test"); + final Location two = Location.withValues(44, "test"); + + Assert.assertEquals(one.hashCode(), two.hashCode()); + + two.setName("112"); + + Assert.assertNotEquals(one.hashCode(), two.hashCode()); + } + + @Test + public void whenCheckEquality_thenAllIsFine() { + final Location one = Location.withValues(44, "test"); + final Location two = Location.withValues(44, "test"); + + Assert.assertTrue(one.equals(one)); + Assert.assertFalse(one.equals(new Object())); + + Assert.assertTrue(one.equals(two)); + + two.setId(23); + + Assert.assertFalse(one.equals(two)); + + one.setId(23); + + Assert.assertTrue(one.equals(two)); + + one.setName("23"); + + Assert.assertFalse(one.equals(two)); + + two.setName("23"); + + Assert.assertTrue(one.equals(two)); + + one.setCountryCode("11"); + + Assert.assertFalse(one.equals(two)); + + two.setCountryCode("11"); + + Assert.assertTrue(one.equals(two)); + + final LocalDateTime now = LocalDateTime.now(); + + one.setSunrise(now); + + Assert.assertFalse(one.equals(two)); + + two.setSunrise(now); + + Assert.assertTrue(one.equals(two)); + + one.setSunset(now); + + Assert.assertFalse(one.equals(two)); + + two.setSunset(now); + + Assert.assertTrue(one.equals(two)); + + one.setZoneOffset(ZoneOffset.UTC); + + Assert.assertFalse(one.equals(two)); + + two.setZoneOffset(ZoneOffset.UTC); + + Assert.assertTrue(one.equals(two)); + + final Coordinate coordinate = Coordinate.withValues(33.5, -22.4); + + one.setCoordinate(coordinate); + + Assert.assertFalse(one.equals(two)); + + two.setCoordinate(coordinate); + + Assert.assertTrue(one.equals(two)); + + one.setPopulation(20000L); + + Assert.assertFalse(one.equals(two)); + + two.setPopulation(20000L); + + Assert.assertTrue(one.equals(two)); + } +} diff --git a/src/test/java/com/github/prominence/openweathermap/api/model/forecast/RainUnitTest.java b/src/test/java/com/github/prominence/openweathermap/api/model/forecast/RainUnitTest.java new file mode 100644 index 0000000..3105dd1 --- /dev/null +++ b/src/test/java/com/github/prominence/openweathermap/api/model/forecast/RainUnitTest.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2021 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.forecast; + +import org.junit.Assert; +import org.junit.Test; + +public class RainUnitTest { + @Test + public void whenCreateRainWithValidArgs_thenObjectIsCreated() { + Rain.withThreeHourLevelValue(2222.3); + Rain.withThreeHourLevelValue(0); + } + + @Test(expected = IllegalArgumentException.class) + public void whenCreateWithInvalidData_thenFail() { + Rain.withThreeHourLevelValue(-20); + } + + @Test + public void whenSetValues_thenTheyAreSet() { + final Rain rain = Rain.withThreeHourLevelValue(0); + + Assert.assertEquals(0, rain.getThreeHourRainLevel(), 0.00001); + + rain.setThreeHourRainLevel(55.5); + Assert.assertEquals(55.5, rain.getThreeHourRainLevel(), 0.00001); + } + + @Test(expected = IllegalArgumentException.class) + public void whenSetInvalidValue_thenFail() { + final Rain rain = Rain.withThreeHourLevelValue(0); + + rain.setThreeHourRainLevel(-20); + } + + @Test + public void whenCallToString_thenAllIsFine() { + final Rain rain = Rain.withThreeHourLevelValue(33.5); + + Assert.assertNotNull(rain.toString()); + Assert.assertNotEquals("", rain.toString()); + } + + @Test + public void whenCallHashCode_thenAllIsFine() { + final Rain first = Rain.withThreeHourLevelValue(0); + final Rain second = Rain.withThreeHourLevelValue(0); + + Assert.assertEquals(first.hashCode(), second.hashCode()); + + second.setThreeHourRainLevel(11.0); + + Assert.assertNotEquals(first.hashCode(), second.hashCode()); + + first.setThreeHourRainLevel(11.0); + + Assert.assertEquals(first.hashCode(), second.hashCode()); + } + + @Test + public void whenCheckEquality_thenAllIsFine() { + final Rain first = Rain.withThreeHourLevelValue(0); + final Rain second = Rain.withThreeHourLevelValue(0); + + Assert.assertTrue(first.equals(second)); + Assert.assertTrue(first.equals(first)); + Assert.assertFalse(first.equals(new Object())); + + second.setThreeHourRainLevel(66.7); + + Assert.assertFalse(first.equals(second)); + + first.setThreeHourRainLevel(66.7); + + Assert.assertTrue(first.equals(second)); + } +} diff --git a/src/test/java/com/github/prominence/openweathermap/api/model/forecast/SnowUnitTest.java b/src/test/java/com/github/prominence/openweathermap/api/model/forecast/SnowUnitTest.java new file mode 100644 index 0000000..6b5bf8d --- /dev/null +++ b/src/test/java/com/github/prominence/openweathermap/api/model/forecast/SnowUnitTest.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2021 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.forecast; + +import org.junit.Assert; +import org.junit.Test; + +public class SnowUnitTest { + @Test + public void whenCreateSnowWithValidArgs_ObjectIsCreated() { + Snow.withThreeHourLevelValue(2222.3); + Snow.withThreeHourLevelValue(0); + } + @Test(expected = IllegalArgumentException.class) + public void whenCreateWithInvalidData_thenFail() { + Snow.withThreeHourLevelValue(-20); + } + + @Test + public void whenSetValues_thenTheyAreSet() { + final Snow snow = Snow.withThreeHourLevelValue(0); + + Assert.assertEquals(0, snow.getThreeHourSnowLevel(), 0.00001); + + snow.setThreeHourSnowLevel(55.5); + Assert.assertEquals(55.5, snow.getThreeHourSnowLevel(), 0.00001); + } + + @Test(expected = IllegalArgumentException.class) + public void whenSetInvalidValue_thenFail() { + final Snow snow = Snow.withThreeHourLevelValue(0); + + snow.setThreeHourSnowLevel(-20); + } + + @Test + public void whenCallToString_thenAllIsFine() { + final Snow snow = Snow.withThreeHourLevelValue(33.5); + + Assert.assertNotNull(snow.toString()); + Assert.assertNotEquals("", snow.toString()); + } + + @Test + public void whenCallHashCode_thenAllIsFine() { + final Snow first = Snow.withThreeHourLevelValue(0); + final Snow second = Snow.withThreeHourLevelValue(0); + + Assert.assertEquals(first.hashCode(), second.hashCode()); + + second.setThreeHourSnowLevel(11.0); + + Assert.assertNotEquals(first.hashCode(), second.hashCode()); + + first.setThreeHourSnowLevel(11.0); + + Assert.assertEquals(first.hashCode(), second.hashCode()); + } + + @Test + public void whenCheckEquality_thenAllIsFine() { + final Snow first = Snow.withThreeHourLevelValue(0); + final Snow second = Snow.withThreeHourLevelValue(0); + + Assert.assertTrue(first.equals(second)); + Assert.assertTrue(first.equals(first)); + Assert.assertFalse(first.equals(new Object())); + + second.setThreeHourSnowLevel(66.7); + + Assert.assertFalse(first.equals(second)); + + first.setThreeHourSnowLevel(66.7); + + Assert.assertTrue(first.equals(second)); + } +} diff --git a/src/test/java/com/github/prominence/openweathermap/api/model/forecast/WeatherForecastUnitTest.java b/src/test/java/com/github/prominence/openweathermap/api/model/forecast/WeatherForecastUnitTest.java new file mode 100644 index 0000000..0204f5c --- /dev/null +++ b/src/test/java/com/github/prominence/openweathermap/api/model/forecast/WeatherForecastUnitTest.java @@ -0,0 +1,361 @@ +/* + * Copyright (c) 2021 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.forecast; + +import com.github.prominence.openweathermap.api.model.*; +import org.junit.Assert; +import org.junit.Test; + +import java.time.LocalDateTime; + +public class WeatherForecastUnitTest { + @Test + public void whenCreateObjectWithValidArgs_thenObjectIsCreated() { + WeatherForecast.forValue("state", "desc"); + } + + @Test(expected = IllegalArgumentException.class) + public void whenCreateObjectWithoutState_thenThrowAnException() { + WeatherForecast.forValue(null, "desc"); + } + + @Test(expected = IllegalArgumentException.class) + public void whenCreateObjectWithoutDescription_thenThrowAnException() { + WeatherForecast.forValue("state", null); + } + + @Test + public void whenSetState_thenValueIsSet() { + final WeatherForecast weatherForecast = WeatherForecast.forValue("state", "desc"); + weatherForecast.setState("test"); + + Assert.assertEquals("test", weatherForecast.getState()); + } + + @Test(expected = IllegalArgumentException.class) + public void whenSetNullState_thenThrowAnException() { + final WeatherForecast weather = WeatherForecast.forValue("state", "desc"); + weather.setState(null); + } + + @Test + public void whenSetDescription_thenValueIsSet() { + final WeatherForecast weatherForecast = WeatherForecast.forValue("state", "desc"); + weatherForecast.setDescription("test"); + + Assert.assertEquals("test", weatherForecast.getDescription()); + } + + @Test(expected = IllegalArgumentException.class) + public void whenSetNullDescription_thenThrowAnException() { + final WeatherForecast weatherForecast = WeatherForecast.forValue("state", "desc"); + weatherForecast.setDescription(null); + } + + @Test + public void whenSetIconUrl_thenValueIsSet() { + final WeatherForecast weatherForecast = WeatherForecast.forValue("state", "desc"); + weatherForecast.setWeatherIconUrl("test"); + + Assert.assertEquals("test", weatherForecast.getWeatherIconUrl()); + } + + @Test + public void whenSetForecastTime_thenValueIsSet() { + final WeatherForecast weatherForecast = WeatherForecast.forValue("state", "desc"); + final LocalDateTime now = LocalDateTime.now(); + weatherForecast.setForecastTime(now); + + Assert.assertEquals(now, weatherForecast.getForecastTime()); + } + + @Test + public void whenSetTemperature_thenValueIsSet() { + final WeatherForecast weatherForecast = WeatherForecast.forValue("state", "desc"); + final Temperature temperature = Temperature.withValue(22.3, "a"); + weatherForecast.setTemperature(temperature); + + Assert.assertEquals(temperature, weatherForecast.getTemperature()); + } + + @Test + public void whenSetPressure_thenValueIsSet() { + final WeatherForecast weatherForecast = WeatherForecast.forValue("state", "desc"); + final AtmosphericPressure atmosphericPressure = AtmosphericPressure.withValue(33.2); + weatherForecast.setAtmosphericPressure(atmosphericPressure); + + Assert.assertEquals(atmosphericPressure, weatherForecast.getAtmosphericPressure()); + } + + @Test + public void whenSetHumidity_thenValueIsSet() { + final WeatherForecast weatherForecast = WeatherForecast.forValue("state", "desc"); + final Humidity humidity = Humidity.withValue((byte) 44); + weatherForecast.setHumidity(humidity); + + Assert.assertEquals(humidity, weatherForecast.getHumidity()); + } + + @Test + public void whenSetWind_thenValueIsSet() { + final WeatherForecast weatherForecast = WeatherForecast.forValue("state", "desc"); + final Wind wind = Wind.withValue(22.2, "a"); + weatherForecast.setWind(wind); + + Assert.assertEquals(wind, weatherForecast.getWind()); + } + + @Test + public void whenSetRain_thenValueIsSet() { + final WeatherForecast weatherForecast = WeatherForecast.forValue("state", "desc"); + final Rain rain = Rain.withThreeHourLevelValue(0); + weatherForecast.setRain(rain); + + Assert.assertEquals(rain, weatherForecast.getRain()); + } + + @Test + public void whenSetSnow_thenValueIsSet() { + final WeatherForecast weatherForecast = WeatherForecast.forValue("state", "desc"); + final Snow snow = Snow.withThreeHourLevelValue(0); + weatherForecast.setSnow(snow); + + Assert.assertEquals(snow, weatherForecast.getSnow()); + } + + @Test + public void whenSetClouds_thenValueIsSet() { + final WeatherForecast weatherForecast = WeatherForecast.forValue("state", "desc"); + final Clouds clouds = Clouds.withValue((byte) 33); + weatherForecast.setClouds(clouds); + + Assert.assertEquals(clouds, weatherForecast.getClouds()); + } + + @Test + public void whenSetForecastTimeISO_thenValueIsSet() { + final WeatherForecast weatherForecast = WeatherForecast.forValue("state", "desc"); + + Assert.assertNull(weatherForecast.getForecastTimeISO()); + + weatherForecast.setForecastTimeISO("1994-2-3"); + + Assert.assertEquals("1994-2-3", weatherForecast.getForecastTimeISO()); + } + + @Test + public void whenSetDayTime_thenValueIsSet() { + final WeatherForecast weatherForecast = WeatherForecast.forValue("state", "desc"); + + Assert.assertNull(weatherForecast.getDayTime()); + + weatherForecast.setDayTime(DayTime.DAY); + + Assert.assertEquals(DayTime.DAY, weatherForecast.getDayTime()); + } + + @Test + public void whenCallToString_thenAllIsFine() { + final WeatherForecast weatherForecast = WeatherForecast.forValue("state", "desc"); + final Location location = Location.withValues(12312, "asd"); + final Temperature temperature = Temperature.withValue(33.2, "asd"); + final AtmosphericPressure atmosphericPressure = AtmosphericPressure.withValue(44.4); + final Clouds clouds = Clouds.withValue((byte) 55); + final Rain rain = Rain.withThreeHourLevelValue(33.2); + final Snow snow = Snow.withThreeHourLevelValue(33.1); + + Assert.assertNotEquals("", weatherForecast.toString()); + Assert.assertNotNull(weatherForecast.toString()); + + location.setCountryCode("3d"); + Assert.assertNotEquals("", weatherForecast.toString()); + Assert.assertNotNull(weatherForecast.toString()); + + weatherForecast.setTemperature(temperature); + Assert.assertNotEquals("", weatherForecast.toString()); + Assert.assertNotNull(weatherForecast.toString()); + + weatherForecast.setAtmosphericPressure(atmosphericPressure); + Assert.assertNotEquals("", weatherForecast.toString()); + Assert.assertNotNull(weatherForecast.toString()); + + weatherForecast.setClouds(clouds); + Assert.assertNotEquals("", weatherForecast.toString()); + Assert.assertNotNull(weatherForecast.toString()); + + weatherForecast.setRain(rain); + Assert.assertNotEquals("", weatherForecast.toString()); + Assert.assertNotNull(weatherForecast.toString()); + + weatherForecast.setSnow(snow); + Assert.assertNotEquals("", weatherForecast.toString()); + Assert.assertNotNull(weatherForecast.toString()); + + weatherForecast.setRain(null); + Assert.assertNotEquals("", weatherForecast.toString()); + Assert.assertNotNull(weatherForecast.toString()); + + weatherForecast.setSnow(null); + Assert.assertNotEquals("", weatherForecast.toString()); + Assert.assertNotNull(weatherForecast.toString()); + + weatherForecast.setRain(Rain.withThreeHourLevelValue(0)); + Assert.assertNotEquals("", weatherForecast.toString()); + Assert.assertNotNull(weatherForecast.toString()); + + weatherForecast.setSnow(Snow.withThreeHourLevelValue(0)); + Assert.assertNotEquals("", weatherForecast.toString()); + Assert.assertNotNull(weatherForecast.toString()); + } + + @Test + public void whenCallHashCode_thenAllIsFine() { + final WeatherForecast one = WeatherForecast.forValue("state", "desc"); + final WeatherForecast two = WeatherForecast.forValue("state", "desc"); + + Assert.assertEquals(one.hashCode(), two.hashCode()); + + two.setDescription("112"); + + Assert.assertNotEquals(one.hashCode(), two.hashCode()); + } + + @Test + public void whenCheckEquality_thenAllIsFine() { + final WeatherForecast one = WeatherForecast.forValue("state", "desc"); + final WeatherForecast two = WeatherForecast.forValue("state1", "desc1"); + + Assert.assertTrue(one.equals(one)); + Assert.assertFalse(one.equals(null)); + Assert.assertFalse(one.equals(new Object())); + Assert.assertFalse(one.equals(two)); + + two.setState("state"); + + Assert.assertFalse(one.equals(two)); + + two.setDescription("desc"); + + Assert.assertTrue(one.equals(two)); + + one.setWeatherIconUrl("1"); + + Assert.assertFalse(one.equals(two)); + + two.setWeatherIconUrl("1"); + + Assert.assertTrue(one.equals(two)); + + final LocalDateTime now = LocalDateTime.now(); + one.setForecastTime(now); + + Assert.assertFalse(one.equals(two)); + + two.setForecastTime(now); + + Assert.assertTrue(one.equals(two)); + + final Temperature temperature = Temperature.withValue(33.2, "as"); + one.setTemperature(temperature); + + Assert.assertFalse(one.equals(two)); + + two.setTemperature(temperature); + + Assert.assertTrue(one.equals(two)); + + final AtmosphericPressure atmosphericPressure = AtmosphericPressure.withValue(33.33); + one.setAtmosphericPressure(atmosphericPressure); + + Assert.assertFalse(one.equals(two)); + + two.setAtmosphericPressure(atmosphericPressure); + + Assert.assertTrue(one.equals(two)); + + final Humidity humidity = Humidity.withValue((byte) 33); + one.setHumidity(humidity); + + Assert.assertFalse(one.equals(two)); + + two.setHumidity(humidity); + + Assert.assertTrue(one.equals(two)); + + final Wind wind = Wind.withValue(33.6, "asd"); + one.setWind(wind); + + Assert.assertFalse(one.equals(two)); + + two.setWind(wind); + + Assert.assertTrue(one.equals(two)); + + final Rain rain = Rain.withThreeHourLevelValue(0); + one.setRain(rain); + + Assert.assertFalse(one.equals(two)); + + two.setRain(rain); + + Assert.assertTrue(one.equals(two)); + + final Snow snow = Snow.withThreeHourLevelValue(0); + one.setSnow(snow); + + Assert.assertFalse(one.equals(two)); + + two.setSnow(snow); + + Assert.assertTrue(one.equals(two)); + + final Clouds clouds = Clouds.withValue((byte) 33); + one.setClouds(clouds); + + Assert.assertFalse(one.equals(two)); + + two.setClouds(clouds); + + Assert.assertTrue(one.equals(two)); + + one.setForecastTimeISO("test"); + + Assert.assertFalse(one.equals(two)); + + two.setForecastTimeISO("test"); + + Assert.assertTrue(one.equals(two)); + + one.setDayTime(DayTime.NIGHT); + + Assert.assertFalse(one.equals(two)); + + two.setDayTime(DayTime.DAY); + + Assert.assertFalse(one.equals(two)); + + one.setDayTime(DayTime.DAY); + + Assert.assertTrue(one.equals(two)); + } +} diff --git a/src/test/java/com/github/prominence/openweathermap/api/model/forecast/WindUnitTest.java b/src/test/java/com/github/prominence/openweathermap/api/model/forecast/WindUnitTest.java new file mode 100644 index 0000000..41697c4 --- /dev/null +++ b/src/test/java/com/github/prominence/openweathermap/api/model/forecast/WindUnitTest.java @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2021 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.forecast; + +import org.junit.Assert; +import org.junit.Test; + +public class WindUnitTest { + @Test + public void whenCreateWindWithValidArgs_thenValueIsSet() { + Assert.assertEquals(44.0, Wind.withValue(44, "ms").getSpeed(), 0.00001); + } + + @Test(expected = IllegalArgumentException.class) + public void whenCreateWindWithInvalidSpeedArg_thenThrowAnException() { + Wind.withValue(-21, "a"); + } + + @Test(expected = IllegalArgumentException.class) + public void whenCreateWindWithInvalidUnitArg_thenThrowAnException() { + Wind.withValue(342, null); + } + + @Test + public void whenSetValidSpeed_thenValueIsSet() { + final Wind wind = Wind.withValue(33, "as"); + + Assert.assertEquals(33, wind.getSpeed(), 0.00001); + + wind.setSpeed(0); + + Assert.assertEquals(0, wind.getSpeed(), 0.00001); + + wind.setSpeed(3656); + + Assert.assertEquals(3656, wind.getSpeed(), 0.00001); + } + + @Test(expected = IllegalArgumentException.class) + public void whenSetInvalidSpeedBelow0_thenThrowAnException() { + final Wind wind = Wind.withValue(33, "as"); + + Assert.assertEquals(33, wind.getSpeed(), 0.00001); + + wind.setSpeed(-22); + } + + @Test + public void whenSetValidDegrees_thenValueIsSet() { + final Wind wind = Wind.withValue(33, "as"); + + Assert.assertNull(wind.getDegrees()); + + wind.setDegrees(22); + + Assert.assertEquals(22, wind.getDegrees(), 0.00001); + + wind.setDegrees(0); + + Assert.assertEquals(0, wind.getDegrees(), 0.00001); + + wind.setDegrees(360); + + Assert.assertEquals(360, wind.getDegrees(), 0.00001); + } + + @Test(expected = IllegalArgumentException.class) + public void whenSetInvalidDegreesBelow0_thenThrowAnException() { + final Wind wind = Wind.withValue(33, "as"); + wind.setDegrees(-32); + } + + @Test(expected = IllegalArgumentException.class) + public void whenSetInvalidDegreesAbove360_thenThrowAnException() { + final Wind wind = Wind.withValue(33, "as"); + wind.setDegrees(378); + } + + @Test + public void whenSetNonNullUnit_thenValueIsSet() { + final Wind wind = Wind.withValue(33, "as"); + + Assert.assertEquals(wind.getUnit(), "as"); + + wind.setUnit("myUnit"); + + Assert.assertEquals(wind.getUnit(), "myUnit"); + } + + @Test(expected = IllegalArgumentException.class) + public void whenSetNullUnit_thenThrowAnException() { + final Wind wind = Wind.withValue(33, "as"); + + wind.setUnit(null); + } + + @Test + public void whenCallToString_thenAllIsFine() { + final Wind wind = Wind.withValue(302, "a"); + + Assert.assertNotNull(wind.toString()); + + wind.setDegrees(22); + + Assert.assertNotNull(wind.toString()); + Assert.assertNotEquals("", wind.toString()); + } + + @Test + public void whenCallHashCode_thenAllIsFine() { + final Wind first = Wind.withValue(22, "a"); + final Wind second = Wind.withValue(22, "b"); + + Assert.assertNotEquals(first.hashCode(), second.hashCode()); + + second.setUnit("a"); + + Assert.assertEquals(first.hashCode(), second.hashCode()); + + second.setSpeed(33); + + Assert.assertNotEquals(first.hashCode(), second.hashCode()); + + first.setSpeed(333); + + Assert.assertNotEquals(first.hashCode(), second.hashCode()); + + first.setSpeed(33); + + Assert.assertEquals(first.hashCode(), second.hashCode()); + } + + @Test + public void whenCheckEquality_thenAllIsFine() { + final Wind first = Wind.withValue(11, "a"); + final Wind second = Wind.withValue(11, "a"); + + Assert.assertTrue(first.equals(second)); + Assert.assertTrue(first.equals(first)); + Assert.assertFalse(first.equals(new Object())); + + first.setDegrees(34); + + Assert.assertFalse(first.equals(second)); + + second.setDegrees(34); + + Assert.assertTrue(first.equals(second)); + + second.setUnit("v"); + + Assert.assertFalse(first.equals(second)); + + first.setUnit("v"); + first.setSpeed(second.getSpeed() + 4); + + Assert.assertFalse(first.equals(second)); + } +} diff --git a/src/test/java/com/github/prominence/openweathermap/api/model/weather/LocationUnitTest.java b/src/test/java/com/github/prominence/openweathermap/api/model/weather/LocationUnitTest.java new file mode 100644 index 0000000..9f0e505 --- /dev/null +++ b/src/test/java/com/github/prominence/openweathermap/api/model/weather/LocationUnitTest.java @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2021 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.weather; + +import com.github.prominence.openweathermap.api.model.Coordinate; +import org.junit.Assert; +import org.junit.Test; + +import java.time.LocalDateTime; +import java.time.ZoneOffset; + +public class LocationUnitTest { + @Test + public void whenCreateObjectWithValidArgs_thenObjectIsCreated() { + Location.withValues(33, "test"); + } + + @Test(expected = IllegalArgumentException.class) + public void whenCreateObjectWithoutName_thenThrowAnException() { + Location.withValues(33, null); + } + + @Test + public void whenSetId_thenValueIsSet() { + final Location location = Location.withValues(33, "test"); + location.setId(55); + + Assert.assertEquals(55, location.getId()); + } + + @Test + public void whenSetName_thenValueIsSet() { + final Location location = Location.withValues(33, "test"); + location.setName("city"); + + Assert.assertEquals("city", location.getName()); + } + + @Test + public void whenSetCountryCode_thenValueIsSet() { + final Location location = Location.withValues(33, "test"); + location.setCountryCode("by"); + + Assert.assertEquals("by", location.getCountryCode()); + } + + @Test + public void whenSetSunrise_thenValueIsSet() { + final Location location = Location.withValues(33, "test"); + final LocalDateTime now = LocalDateTime.now(); + location.setSunrise(now); + + Assert.assertEquals(now, location.getSunrise()); + } + + @Test + public void whenSetSunset_thenValueIsSet() { + final Location location = Location.withValues(33, "test"); + final LocalDateTime now = LocalDateTime.now(); + location.setSunset(now); + + Assert.assertEquals(now, location.getSunset()); + } + + @Test + public void whenSetZoneOffset_thenValueIsSet() { + final Location location = Location.withValues(33, "test"); + final ZoneOffset offset = ZoneOffset.UTC; + location.setZoneOffset(offset); + + Assert.assertEquals(offset, location.getZoneOffset()); + } + + @Test + public void whenSetCoordinate_thenValueIsSet() { + final Location location = Location.withValues(33, "test"); + final Coordinate coordinate = Coordinate.withValues(33.2, 64.2); + location.setCoordinate(coordinate); + + Assert.assertEquals(coordinate, location.getCoordinate()); + } + + @Test + public void whenCallToString_thenAllIsFine() { + final Location location = Location.withValues(44, "test"); + + Assert.assertNotEquals("", location.toString()); + + location.setCoordinate(Coordinate.withValues(33.2, 56.3)); + + Assert.assertNotEquals("", location.toString()); + + location.setCountryCode("TN"); + + Assert.assertNotEquals("", location.toString()); + Assert.assertNotNull(location.toString()); + } + + @Test + public void whenCallHashCode_thenAllIsFine() { + final Location one = Location.withValues(44, "test"); + final Location two = Location.withValues(44, "test"); + + Assert.assertEquals(one.hashCode(), two.hashCode()); + + two.setName("112"); + + Assert.assertNotEquals(one.hashCode(), two.hashCode()); + } + + @Test + public void whenCheckEquality_thenAllIsFine() { + final Location one = Location.withValues(44, "test"); + final Location two = Location.withValues(44, "test"); + + Assert.assertTrue(one.equals(one)); + Assert.assertFalse(one.equals(new Object())); + + Assert.assertTrue(one.equals(two)); + + two.setId(23); + + Assert.assertFalse(one.equals(two)); + + one.setId(23); + + Assert.assertTrue(one.equals(two)); + + one.setName("23"); + + Assert.assertFalse(one.equals(two)); + + two.setName("23"); + + Assert.assertTrue(one.equals(two)); + + one.setCountryCode("11"); + + Assert.assertFalse(one.equals(two)); + + two.setCountryCode("11"); + + Assert.assertTrue(one.equals(two)); + + final LocalDateTime now = LocalDateTime.now(); + + one.setSunrise(now); + + Assert.assertFalse(one.equals(two)); + + two.setSunrise(now); + + Assert.assertTrue(one.equals(two)); + + one.setSunset(now); + + Assert.assertFalse(one.equals(two)); + + two.setSunset(now); + + Assert.assertTrue(one.equals(two)); + + one.setZoneOffset(ZoneOffset.UTC); + + Assert.assertFalse(one.equals(two)); + + two.setZoneOffset(ZoneOffset.UTC); + + Assert.assertTrue(one.equals(two)); + + final Coordinate coordinate = Coordinate.withValues(33.5, -22.4); + + one.setCoordinate(coordinate); + + Assert.assertFalse(one.equals(two)); + + two.setCoordinate(coordinate); + + Assert.assertTrue(one.equals(two)); + } +} diff --git a/src/test/java/com/github/prominence/openweathermap/api/model/weather/RainUnitTest.java b/src/test/java/com/github/prominence/openweathermap/api/model/weather/RainUnitTest.java new file mode 100644 index 0000000..accfa50 --- /dev/null +++ b/src/test/java/com/github/prominence/openweathermap/api/model/weather/RainUnitTest.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2021 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.weather; + +import org.junit.Assert; +import org.junit.Test; + +public class RainUnitTest { + @Test + public void whenCreateRainWithValidArgs_thenObjectIsCreated() { + Rain.withValues(2222.3, 324234.3); + Rain.withThreeHourLevelValue(213123.4); + Rain.withOneHourLevelValue(123123.123); + } + + @Test + public void whenSetValues_thenTheyAreSet() { + final Rain rain = Rain.withValues(0, 0); + + rain.setOneHourRainLevel(33.3); + Assert.assertEquals(33.3, rain.getOneHourRainLevel(), 0.00001); + + rain.setThreeHourRainLevel(55.5); + Assert.assertEquals(55.5, rain.getThreeHourRainLevel(), 0.00001); + } + + @Test + public void whenCallToString_thenAllIsFine() { + Rain rain = Rain.withThreeHourLevelValue(33.5); + + Assert.assertNotNull(rain.toString()); + Assert.assertNotEquals("", rain.toString()); + + rain.setOneHourRainLevel(22.2); + + Assert.assertNotNull(rain.toString()); + Assert.assertNotEquals("", rain.toString()); + } + + @Test(expected = IllegalArgumentException.class) + public void whenSetInvalidOneHourLevelValue_thenFail() { + final Rain rain = Rain.withValues(0, 0); + rain.setOneHourRainLevel(-20); + } + + @Test(expected = IllegalArgumentException.class) + public void whenSetInvalidThreeHourLevelValue_thenFail() { + final Rain rain = Rain.withValues(0, 0); + rain.setThreeHourRainLevel(-20); + } + + @Test + public void whenCallHashCode_thenAllIsFine() { + final Rain first = Rain.withValues(0, 0); + final Rain second = Rain.withValues(0, 0); + + Assert.assertEquals(first.hashCode(), second.hashCode()); + + second.setThreeHourRainLevel(11.0); + + Assert.assertNotEquals(first.hashCode(), second.hashCode()); + + first.setThreeHourRainLevel(11.0); + + Assert.assertEquals(first.hashCode(), second.hashCode()); + + first.setOneHourRainLevel(333.2); + + Assert.assertNotEquals(first.hashCode(), second.hashCode()); + + second.setOneHourRainLevel(333.2); + + Assert.assertEquals(first.hashCode(), second.hashCode()); + } + + @Test + public void whenCheckEquality_thenAllIsFine() { + final Rain first = Rain.withValues(0, 0); + final Rain second = Rain.withValues(0, 0); + + Assert.assertTrue(first.equals(second)); + Assert.assertTrue(first.equals(first)); + Assert.assertFalse(first.equals(new Object())); + + first.setOneHourRainLevel(0.34); + + Assert.assertFalse(first.equals(second)); + + second.setOneHourRainLevel(0.34); + + Assert.assertTrue(first.equals(second)); + + second.setThreeHourRainLevel(66.7); + + Assert.assertFalse(first.equals(second)); + + first.setThreeHourRainLevel(66.7); + + Assert.assertTrue(first.equals(second)); + } +} diff --git a/src/test/java/com/github/prominence/openweathermap/api/model/weather/SnowUnitTest.java b/src/test/java/com/github/prominence/openweathermap/api/model/weather/SnowUnitTest.java new file mode 100644 index 0000000..d0b4c92 --- /dev/null +++ b/src/test/java/com/github/prominence/openweathermap/api/model/weather/SnowUnitTest.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2021 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.weather; + +import org.junit.Assert; +import org.junit.Test; + +public class SnowUnitTest { + @Test + public void whenCreateSnowWithValidArgs_ObjectIsCreated() { + Snow.withValues(2222.3, 324234.3); + Snow.withThreeHourLevelValue(213123.4); + Snow.withOneHourLevelValue(123123.123); + } + + @Test + public void whenSetValues_thenTheyAreSet() { + final Snow snow = Snow.withValues(0, 0); + + snow.setOneHourSnowLevel(33.3); + Assert.assertEquals(33.3, snow.getOneHourSnowLevel(), 0.00001); + + snow.setThreeHourSnowLevel(55.5); + Assert.assertEquals(55.5, snow.getThreeHourSnowLevel(), 0.00001); + } + + @Test(expected = IllegalArgumentException.class) + public void whenSetInvalidOneHourLevelValue_thenFail() { + final Snow rain = Snow.withValues(0, 0); + rain.setOneHourSnowLevel(-20); + } + + @Test(expected = IllegalArgumentException.class) + public void whenSetInvalidThreeHourLevelValue_thenFail() { + final Snow rain = Snow.withValues(0, 0); + rain.setThreeHourSnowLevel(-20); + } + + @Test + public void whenCallToString_thenAllIsFine() { + final Snow snow = Snow.withOneHourLevelValue(33.5); + + Assert.assertNotNull(snow.toString()); + Assert.assertNotEquals("", snow.toString()); + + snow.setOneHourSnowLevel(22.2); + + Assert.assertNotNull(snow.toString()); + Assert.assertNotEquals("", snow.toString()); + + snow.setThreeHourSnowLevel(33.2); + + Assert.assertNotNull(snow.toString()); + Assert.assertNotEquals("", snow.toString()); + } + + @Test + public void whenCallHashCode_thenAllIsFine() { + final Snow first = Snow.withValues(0, 0); + final Snow second = Snow.withValues(0, 0); + + Assert.assertEquals(first.hashCode(), second.hashCode()); + + second.setThreeHourSnowLevel(11.0); + + Assert.assertNotEquals(first.hashCode(), second.hashCode()); + + first.setThreeHourSnowLevel(11.0); + + Assert.assertEquals(first.hashCode(), second.hashCode()); + + first.setOneHourSnowLevel(333.2); + + Assert.assertNotEquals(first.hashCode(), second.hashCode()); + + second.setOneHourSnowLevel(333.2); + + Assert.assertEquals(first.hashCode(), second.hashCode()); + } + + @Test + public void whenCheckEquality_thenAllIsFine() { + final Snow first = Snow.withValues(0, 0); + final Snow second = Snow.withValues(0, 0); + + Assert.assertTrue(first.equals(second)); + Assert.assertTrue(first.equals(first)); + Assert.assertFalse(first.equals(new Object())); + + first.setOneHourSnowLevel(0.34); + + Assert.assertFalse(first.equals(second)); + + second.setOneHourSnowLevel(0.34); + + Assert.assertTrue(first.equals(second)); + + second.setThreeHourSnowLevel(66.7); + + Assert.assertFalse(first.equals(second)); + + first.setThreeHourSnowLevel(66.7); + + Assert.assertTrue(first.equals(second)); + } +} diff --git a/src/test/java/com/github/prominence/openweathermap/api/model/weather/WeatherUnitTest.java b/src/test/java/com/github/prominence/openweathermap/api/model/weather/WeatherUnitTest.java new file mode 100644 index 0000000..10719bc --- /dev/null +++ b/src/test/java/com/github/prominence/openweathermap/api/model/weather/WeatherUnitTest.java @@ -0,0 +1,327 @@ +/* + * Copyright (c) 2021 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.weather; + +import com.github.prominence.openweathermap.api.model.AtmosphericPressure; +import com.github.prominence.openweathermap.api.model.Clouds; +import com.github.prominence.openweathermap.api.model.Humidity; +import com.github.prominence.openweathermap.api.model.Temperature; +import org.junit.Assert; +import org.junit.Test; + +import java.time.LocalDateTime; + +public class WeatherUnitTest { + @Test + public void whenCreateObjectWithValidArgs_thenObjectIsCreated() { + Weather.forValue("state", "desc"); + } + + @Test(expected = IllegalArgumentException.class) + public void whenCreateObjectWithoutState_thenThrowAnException() { + Weather.forValue(null, "desc"); + } + + @Test(expected = IllegalArgumentException.class) + public void whenCreateObjectWithoutDescription_thenThrowAnException() { + Weather.forValue("state", null); + } + + @Test + public void whenSetState_thenValueIsSet() { + final Weather weather = Weather.forValue("state", "desc"); + weather.setState("test"); + + Assert.assertEquals("test", weather.getState()); + } + + @Test(expected = IllegalArgumentException.class) + public void whenSetNullState_thenThrowAnException() { + final Weather weather = Weather.forValue("state", "desc"); + weather.setState(null); + } + + @Test + public void whenSetDescription_thenValueIsSet() { + final Weather weather = Weather.forValue("state", "desc"); + weather.setDescription("test"); + + Assert.assertEquals("test", weather.getDescription()); + } + + @Test(expected = IllegalArgumentException.class) + public void whenSetNullDescription_thenThrowAnException() { + final Weather weather = Weather.forValue("state", "desc"); + weather.setDescription(null); + } + + @Test + public void whenSetIconUrl_thenValueIsSet() { + final Weather weather = Weather.forValue("state", "desc"); + weather.setWeatherIconUrl("test"); + + Assert.assertEquals("test", weather.getWeatherIconUrl()); + } + + @Test + public void whenSetRequestedOn_thenValueIsSet() { + final Weather weather = Weather.forValue("state", "desc"); + final LocalDateTime now = LocalDateTime.now(); + weather.setCalculatedOn(now); + + Assert.assertEquals(now, weather.getCalculatedOn()); + } + + @Test + public void whenSetTemperature_thenValueIsSet() { + final Weather weather = Weather.forValue("state", "desc"); + final Temperature temperature = Temperature.withValue(22.3, "a"); + weather.setTemperature(temperature); + + Assert.assertEquals(temperature, weather.getTemperature()); + } + + @Test + public void whenSetPressure_thenValueIsSet() { + final Weather weather = Weather.forValue("state", "desc"); + final AtmosphericPressure atmosphericPressure = AtmosphericPressure.withValue(33.2); + weather.setAtmosphericPressure(atmosphericPressure); + + Assert.assertEquals(atmosphericPressure, weather.getAtmosphericPressure()); + } + + @Test + public void whenSetHumidity_thenValueIsSet() { + final Weather weather = Weather.forValue("state", "desc"); + final Humidity humidity = Humidity.withValue((byte) 44); + weather.setHumidity(humidity); + + Assert.assertEquals(humidity, weather.getHumidity()); + } + + @Test + public void whenSetWind_thenValueIsSet() { + final Weather weather = Weather.forValue("state", "desc"); + final Wind wind = Wind.withValue(22.2, "a"); + weather.setWind(wind); + + Assert.assertEquals(wind, weather.getWind()); + } + + @Test + public void whenSetRain_thenValueIsSet() { + final Weather weather = Weather.forValue("state", "desc"); + final Rain rain = Rain.withValues(0, 0); + weather.setRain(rain); + + Assert.assertEquals(rain, weather.getRain()); + } + + @Test + public void whenSetSnow_thenValueIsSet() { + final Weather weather = Weather.forValue("state", "desc"); + final Snow snow = Snow.withValues(0, 0); + weather.setSnow(snow); + + Assert.assertEquals(snow, weather.getSnow()); + } + + @Test + public void whenSetClouds_thenValueIsSet() { + final Weather weather = Weather.forValue("state", "desc"); + final Clouds clouds = Clouds.withValue((byte) 33); + weather.setClouds(clouds); + + Assert.assertEquals(clouds, weather.getClouds()); + } + + @Test + public void whenSetLocation_thenValueIsSet() { + final Weather weather = Weather.forValue("state", "desc"); + final Location location = Location.withValues(22, "asd"); + weather.setLocation(location); + + Assert.assertEquals(location, weather.getLocation()); + } + + @Test + public void whenCallToString_thenAllIsFine() { + final Weather weather = Weather.forValue("state", "desc"); + final Location location = Location.withValues(12312, "asd"); + final Temperature temperature = Temperature.withValue(33.2, "asd"); + final AtmosphericPressure atmosphericPressure = AtmosphericPressure.withValue(44.4); + final Clouds clouds = Clouds.withValue((byte) 55); + final Rain rain = Rain.withOneHourLevelValue(33.2); + final Snow snow = Snow.withOneHourLevelValue(33.1); + + Assert.assertNotEquals("", weather.toString()); + Assert.assertNotNull(weather.toString()); + + weather.setLocation(location); + Assert.assertNotEquals("", weather.toString()); + Assert.assertNotNull(weather.toString()); + + location.setCountryCode("3d"); + Assert.assertNotEquals("", weather.toString()); + Assert.assertNotNull(weather.toString()); + + weather.setTemperature(temperature); + Assert.assertNotEquals("", weather.toString()); + Assert.assertNotNull(weather.toString()); + + weather.setAtmosphericPressure(atmosphericPressure); + Assert.assertNotEquals("", weather.toString()); + Assert.assertNotNull(weather.toString()); + + weather.setClouds(clouds); + Assert.assertNotEquals("", weather.toString()); + Assert.assertNotNull(weather.toString()); + + weather.setRain(rain); + Assert.assertNotEquals("", weather.toString()); + Assert.assertNotNull(weather.toString()); + + weather.setSnow(snow); + Assert.assertNotEquals("", weather.toString()); + Assert.assertNotNull(weather.toString()); + } + + @Test + public void whenCallHashCode_thenAllIsFine() { + final Weather one = Weather.forValue("state", "desc"); + final Weather two = Weather.forValue("state", "desc"); + + Assert.assertEquals(one.hashCode(), two.hashCode()); + + two.setDescription("112"); + + Assert.assertNotEquals(one.hashCode(), two.hashCode()); + } + + @Test + public void whenCheckEquality_thenAllIsFine() { + final Weather one = Weather.forValue("state", "desc"); + final Weather two = Weather.forValue("state1", "desc1"); + + Assert.assertTrue(one.equals(one)); + Assert.assertFalse(one.equals(new Object())); + Assert.assertFalse(one.equals(two)); + + two.setState("state"); + + Assert.assertFalse(one.equals(two)); + + two.setDescription("desc"); + + Assert.assertTrue(one.equals(two)); + + one.setWeatherIconUrl("1"); + + Assert.assertFalse(one.equals(two)); + + two.setWeatherIconUrl("1"); + + Assert.assertTrue(one.equals(two)); + + final LocalDateTime now = LocalDateTime.now(); + one.setCalculatedOn(now); + + Assert.assertFalse(one.equals(two)); + + two.setCalculatedOn(now); + + Assert.assertTrue(one.equals(two)); + + final Temperature temperature = Temperature.withValue(33.2, "as"); + one.setTemperature(temperature); + + Assert.assertFalse(one.equals(two)); + + two.setTemperature(temperature); + + Assert.assertTrue(one.equals(two)); + + final AtmosphericPressure atmosphericPressure = AtmosphericPressure.withValue(33.33); + one.setAtmosphericPressure(atmosphericPressure); + + Assert.assertFalse(one.equals(two)); + + two.setAtmosphericPressure(atmosphericPressure); + + Assert.assertTrue(one.equals(two)); + + final Humidity humidity = Humidity.withValue((byte) 33); + one.setHumidity(humidity); + + Assert.assertFalse(one.equals(two)); + + two.setHumidity(humidity); + + Assert.assertTrue(one.equals(two)); + + final Wind wind = Wind.withValue(33.6, "asd"); + one.setWind(wind); + + Assert.assertFalse(one.equals(two)); + + two.setWind(wind); + + Assert.assertTrue(one.equals(two)); + + final Rain rain = Rain.withValues(0, 0); + one.setRain(rain); + + Assert.assertFalse(one.equals(two)); + + two.setRain(rain); + + Assert.assertTrue(one.equals(two)); + + final Snow snow = Snow.withValues(0, 0); + one.setSnow(snow); + + Assert.assertFalse(one.equals(two)); + + two.setSnow(snow); + + Assert.assertTrue(one.equals(two)); + + final Clouds clouds = Clouds.withValue((byte) 33); + one.setClouds(clouds); + + Assert.assertFalse(one.equals(two)); + + two.setClouds(clouds); + + Assert.assertTrue(one.equals(two)); + + final Location location = Location.withValues(231, "asda"); + one.setLocation(location); + + Assert.assertFalse(one.equals(two)); + + two.setLocation(location); + + Assert.assertTrue(one.equals(two)); + } +} diff --git a/src/test/java/com/github/prominence/openweathermap/api/model/weather/WindUnitTest.java b/src/test/java/com/github/prominence/openweathermap/api/model/weather/WindUnitTest.java new file mode 100644 index 0000000..3f57404 --- /dev/null +++ b/src/test/java/com/github/prominence/openweathermap/api/model/weather/WindUnitTest.java @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2021 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.weather; + +import org.junit.Assert; +import org.junit.Test; + +public class WindUnitTest { + @Test + public void whenCreateWindWithValidArgs_thenValueIsSet() { + Assert.assertEquals(44.0, Wind.withValue(44, "ms").getSpeed(), 0.00001); + } + + @Test(expected = IllegalArgumentException.class) + public void whenCreateWindWithInvalidSpeedArg_thenThrowAnException() { + Wind.withValue(-21, "a"); + } + + @Test(expected = IllegalArgumentException.class) + public void whenCreateWindWithInvalidUnitArg_thenThrowAnException() { + Wind.withValue(342, null); + } + + @Test + public void whenSetValidSpeed_thenValueIsSet() { + final Wind wind = Wind.withValue(33, "as"); + + Assert.assertEquals(33, wind.getSpeed(), 0.00001); + + wind.setSpeed(0); + + Assert.assertEquals(0, wind.getSpeed(), 0.00001); + + wind.setSpeed(3656); + + Assert.assertEquals(3656, wind.getSpeed(), 0.00001); + } + + @Test(expected = IllegalArgumentException.class) + public void whenSetInvalidSpeedBelow0_thenThrowAnException() { + final Wind wind = Wind.withValue(33, "as"); + + Assert.assertEquals(33, wind.getSpeed(), 0.00001); + + wind.setSpeed(-22); + } + + @Test + public void whenSetValidDegrees_thenValueIsSet() { + final Wind wind = Wind.withValue(33, "as"); + + Assert.assertNull(wind.getDegrees()); + + wind.setDegrees(22); + + Assert.assertEquals(22, wind.getDegrees(), 0.00001); + + wind.setDegrees(0); + + Assert.assertEquals(0, wind.getDegrees(), 0.00001); + + wind.setDegrees(360); + + Assert.assertEquals(360, wind.getDegrees(), 0.00001); + } + + @Test(expected = IllegalArgumentException.class) + public void whenSetInvalidDegreesBelow0_thenThrowAnException() { + final Wind wind = Wind.withValue(33, "as"); + wind.setDegrees(-32); + } + + @Test(expected = IllegalArgumentException.class) + public void whenSetInvalidDegreesAbove360_thenThrowAnException() { + final Wind wind = Wind.withValue(33, "as"); + wind.setDegrees(378); + } + + @Test + public void whenSetNonNullUnit_thenValueIsSet() { + final Wind wind = Wind.withValue(33, "as"); + + Assert.assertEquals(wind.getUnit(), "as"); + + wind.setUnit("myUnit"); + + Assert.assertEquals(wind.getUnit(), "myUnit"); + } + + @Test(expected = IllegalArgumentException.class) + public void whenSetNullUnit_thenThrowAnException() { + final Wind wind = Wind.withValue(33, "as"); + + wind.setUnit(null); + } + + @Test(expected = IllegalArgumentException.class) + public void whenSetInvalidGustValue_thenThrowAnException() { + final Wind wind = Wind.withValue(33, "as"); + + wind.setGust(-50); + } + + @Test + public void whenSetValidGustValue_thenAllIsFine() { + final Wind wind = Wind.withValue(33, "as"); + + wind.setGust(30); + + Assert.assertEquals(30, wind.getGust(), 0.00001); + } + + @Test + public void whenCallToString_thenAllIsFine() { + final Wind wind = Wind.withValue(302, "a"); + + Assert.assertNotNull(wind.toString()); + + wind.setDegrees(22); + + Assert.assertNotNull(wind.toString()); + Assert.assertNotEquals("", wind.toString()); + + wind.setGust(20); + Assert.assertNotNull(wind.toString()); + Assert.assertNotEquals("", wind.toString()); + } + + @Test + public void whenCallHashCode_thenAllIsFine() { + final Wind first = Wind.withValue(22, "a"); + final Wind second = Wind.withValue(22, "b"); + + Assert.assertNotEquals(first.hashCode(), second.hashCode()); + + second.setUnit("a"); + + Assert.assertEquals(first.hashCode(), second.hashCode()); + + second.setSpeed(33); + + Assert.assertNotEquals(first.hashCode(), second.hashCode()); + + first.setSpeed(333); + + Assert.assertNotEquals(first.hashCode(), second.hashCode()); + + first.setSpeed(33); + + Assert.assertEquals(first.hashCode(), second.hashCode()); + } + + @Test + public void whenCheckEquality_thenAllIsFine() { + final Wind first = Wind.withValue(11, "a"); + final Wind second = Wind.withValue(11, "a"); + + Assert.assertTrue(first.equals(second)); + Assert.assertTrue(first.equals(first)); + Assert.assertFalse(first.equals(new Object())); + + first.setDegrees(34); + + Assert.assertFalse(first.equals(second)); + + second.setDegrees(34); + + Assert.assertTrue(first.equals(second)); + + second.setUnit("v"); + + Assert.assertFalse(first.equals(second)); + + first.setUnit("v"); + + Assert.assertTrue(first.equals(second)); + + first.setGust(4); + + Assert.assertFalse(first.equals(second)); + + second.setGust(4); + + Assert.assertTrue(first.equals(second)); + } +} diff --git a/src/test/java/com/github/prominence/openweathermap/api/request/forecast/free/FiveDayThreeHourStepForecastIntegrationTest.java b/src/test/java/com/github/prominence/openweathermap/api/request/forecast/free/FiveDayThreeHourStepForecastIntegrationTest.java new file mode 100644 index 0000000..f085210 --- /dev/null +++ b/src/test/java/com/github/prominence/openweathermap/api/request/forecast/free/FiveDayThreeHourStepForecastIntegrationTest.java @@ -0,0 +1,470 @@ +/* + * Copyright (c) 2021 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.request.forecast.free; + +import com.github.prominence.openweathermap.api.ApiTest; +import com.github.prominence.openweathermap.api.OpenWeatherMapClient; +import com.github.prominence.openweathermap.api.enums.Language; +import com.github.prominence.openweathermap.api.enums.UnitSystem; +import com.github.prominence.openweathermap.api.exception.InvalidAuthTokenException; +import com.github.prominence.openweathermap.api.exception.NoDataFoundException; +import com.github.prominence.openweathermap.api.model.Coordinate; +import com.github.prominence.openweathermap.api.model.forecast.Forecast; +import com.github.prominence.openweathermap.api.model.forecast.WeatherForecast; +import org.junit.Assert; +import org.junit.Test; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +public class FiveDayThreeHourStepForecastIntegrationTest extends ApiTest { + @Test + public void whenGetForecastByCityNameRequestAsJava_thenReturnNotNull() { + final Forecast forecast = getClient() + .forecast5Day3HourStep() + .byCityName("Minsk") + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .count(15) + .retrieve() + .asJava(); + + Assert.assertNotNull(forecast); + Assert.assertNotNull(forecast.getLocation()); + Assert.assertNotNull(forecast.getWeatherForecasts()); + for (WeatherForecast weatherForecast : forecast.getWeatherForecasts()) { + Assert.assertNotNull(weatherForecast.getState()); + Assert.assertNotNull(weatherForecast.getDescription()); + Assert.assertNotNull(weatherForecast.getForecastTime()); + Assert.assertNotNull(weatherForecast.getTemperature()); + Assert.assertNotNull(weatherForecast.getAtmosphericPressure()); + Assert.assertNotNull(weatherForecast.getHumidity()); + Assert.assertNotNull(weatherForecast.getWind()); + } + } + + @Test + public void whenGetForecastByCityNameRequestAsJSON_thenReturnNotNull() { + final String forecastJson = getClient() + .forecast5Day3HourStep() + .byCityName("Minsk") + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .count(15) + .retrieve() + .asJSON(); + + Assert.assertTrue(forecastJson.startsWith("{")); + } + + @Test + public void whenGetForecastByCityNameRequestAsXML_thenReturnNotNull() { + final String forecastXml = getClient() + .forecast5Day3HourStep() + .byCityName("Minsk") + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .count(15) + .retrieve() + .asXML(); + + Assert.assertTrue(forecastXml.startsWith("<")); + } + + @Test + public void whenGetForecastByCityNameAndCountryCodeRequestAsJava_thenReturnNotNull() { + final Forecast forecast = getClient() + .forecast5Day3HourStep() + .byCityName("Minsk", "BY") + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .count(15) + .retrieve() + .asJava(); + + Assert.assertNotNull(forecast); + Assert.assertNotNull(forecast.getLocation()); + Assert.assertNotNull(forecast.getWeatherForecasts()); + for (WeatherForecast weatherForecast : forecast.getWeatherForecasts()) { + Assert.assertNotNull(weatherForecast.getState()); + Assert.assertNotNull(weatherForecast.getDescription()); + Assert.assertNotNull(weatherForecast.getForecastTime()); + Assert.assertNotNull(weatherForecast.getTemperature()); + Assert.assertNotNull(weatherForecast.getAtmosphericPressure()); + Assert.assertNotNull(weatherForecast.getHumidity()); + Assert.assertNotNull(weatherForecast.getWind()); + } + } + + @Test + public void whenGetForecastByCityNameAndCountryCodeRequestAsJSON_thenReturnNotNull() { + final String forecastJson = getClient() + .forecast5Day3HourStep() + .byCityName("Minsk", "by") + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .count(15) + .retrieve() + .asJSON(); + + Assert.assertTrue(forecastJson.startsWith("{")); + } + + @Test + public void whenGetForecastByCityNameAndCountryCodeRequestAsXML_thenReturnNotNull() { + final String forecastXml = getClient() + .forecast5Day3HourStep() + .byCityName("Minsk", "by") + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .count(15) + .retrieve() + .asXML(); + + Assert.assertTrue(forecastXml.startsWith("<")); + } + + @Test + public void whenGetForecastByCityNameAndStateCodeAndCountryCodeRequestAsJava_thenReturnNotNull() { + final Forecast forecast = getClient() + .forecast5Day3HourStep() + .byCityName("New York", "NY", "US") + .language(Language.CHINESE_TRADITIONAL) + .unitSystem(UnitSystem.STANDARD) + .count(15) + .retrieve() + .asJava(); + + Assert.assertNotNull(forecast); + Assert.assertNotNull(forecast.getLocation()); + Assert.assertNotNull(forecast.getWeatherForecasts()); + for (WeatherForecast weatherForecast : forecast.getWeatherForecasts()) { + Assert.assertNotNull(weatherForecast.getState()); + Assert.assertNotNull(weatherForecast.getDescription()); + Assert.assertNotNull(weatherForecast.getForecastTime()); + Assert.assertNotNull(weatherForecast.getTemperature()); + Assert.assertNotNull(weatherForecast.getAtmosphericPressure()); + Assert.assertNotNull(weatherForecast.getHumidity()); + Assert.assertNotNull(weatherForecast.getWind()); + } + } + + @Test + public void whenGetForecastByCityNameAndStateCodeAndCountryCodeRequestAsJSON_thenReturnNotNull() { + final String forecastJson = getClient() + .forecast5Day3HourStep() + .byCityName("New York", "NY", "US") + .language(Language.SPANISH) + .unitSystem(UnitSystem.IMPERIAL) + .count(15) + .retrieve() + .asJSON(); + + Assert.assertTrue(forecastJson.startsWith("{")); + } + + @Test + public void whenGetForecastByCityNameAndStateCodeAndCountryCodeRequestAsXML_thenReturnNotNull() { + final String forecastXml = getClient() + .forecast5Day3HourStep() + .byCityName("New York", "NY", "US") + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asXML(); + + Assert.assertTrue(forecastXml.startsWith("<")); + } + + @Test + public void whenGetForecastByCityIdRequestAsJava_thenReturnNotNull() { + final Forecast forecast = getClient() + .forecast5Day3HourStep() + .byCityId(350001514) + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .count(15) + .retrieve() + .asJava(); + + Assert.assertNotNull(forecast); + Assert.assertNotNull(forecast.getLocation()); + Assert.assertNotNull(forecast.getWeatherForecasts()); + for (WeatherForecast weatherForecast : forecast.getWeatherForecasts()) { + Assert.assertNotNull(weatherForecast.getState()); + Assert.assertNotNull(weatherForecast.getDescription()); + Assert.assertNotNull(weatherForecast.getForecastTime()); + Assert.assertNotNull(weatherForecast.getTemperature()); + Assert.assertNotNull(weatherForecast.getAtmosphericPressure()); + Assert.assertNotNull(weatherForecast.getHumidity()); + Assert.assertNotNull(weatherForecast.getWind()); + } + } + + @Test + public void whenGetForecastByCityIdRequestAsJSON_thenReturnNotNull() { + final String forecastJson = getClient() + .forecast5Day3HourStep() + .byCityId(350001514) + .language(Language.SPANISH) + .unitSystem(UnitSystem.IMPERIAL) + .count(15) + .retrieve() + .asJSON(); + + Assert.assertTrue(forecastJson.startsWith("{")); + } + + @Test + public void whenGetForecastByCityIdRequestAsXML_thenReturnNotNull() { + final String forecastXml = getClient() + .forecast5Day3HourStep() + .byCityId(350001514) + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asXML(); + + Assert.assertTrue(forecastXml.startsWith("<")); + } + + @Test + public void whenGetForecastByCoordinatesRequestAsJava_thenReturnNotNull() { + final Forecast forecast = getClient() + .forecast5Day3HourStep() + .byCoordinate(Coordinate.withValues(5, 5)) + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .count(15) + .retrieve() + .asJava(); + + Assert.assertNotNull(forecast); + Assert.assertNotNull(forecast.getLocation()); + Assert.assertNotNull(forecast.getWeatherForecasts()); + for (WeatherForecast weatherForecast : forecast.getWeatherForecasts()) { + Assert.assertNotNull(weatherForecast.getState()); + Assert.assertNotNull(weatherForecast.getDescription()); + Assert.assertNotNull(weatherForecast.getForecastTime()); + Assert.assertNotNull(weatherForecast.getTemperature()); + Assert.assertNotNull(weatherForecast.getAtmosphericPressure()); + Assert.assertNotNull(weatherForecast.getHumidity()); + Assert.assertNotNull(weatherForecast.getWind()); + } + } + + @Test + public void whenGetForecastByCoordinatesRequestAsJSON_thenReturnNotNull() { + final String forecastJson = getClient() + .forecast5Day3HourStep() + .byCoordinate(Coordinate.withValues(5, 5)) + .language(Language.SPANISH) + .unitSystem(UnitSystem.IMPERIAL) + .count(15) + .retrieve() + .asJSON(); + + Assert.assertTrue(forecastJson.startsWith("{")); + } + + @Test + public void whenGetForecastByCoordinatesRequestAsXML_thenReturnNotNull() { + final String forecastXml = getClient() + .forecast5Day3HourStep() + .byCoordinate(Coordinate.withValues(5, 5)) + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asXML(); + + Assert.assertTrue(forecastXml.startsWith("<")); + } + + @Test + public void whenGetForecastByZipCodeInUSARequestAsJava_thenReturnNotNull() { + final Forecast forecast = getClient() + .forecast5Day3HourStep() + .byZipCodeInUSA("10005") + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .count(15) + .retrieve() + .asJava(); + + Assert.assertNotNull(forecast); + Assert.assertNotNull(forecast.getLocation()); + Assert.assertNotNull(forecast.getWeatherForecasts()); + for (WeatherForecast weatherForecast : forecast.getWeatherForecasts()) { + Assert.assertNotNull(weatherForecast.getState()); + Assert.assertNotNull(weatherForecast.getDescription()); + Assert.assertNotNull(weatherForecast.getForecastTime()); + Assert.assertNotNull(weatherForecast.getTemperature()); + Assert.assertNotNull(weatherForecast.getAtmosphericPressure()); + Assert.assertNotNull(weatherForecast.getHumidity()); + Assert.assertNotNull(weatherForecast.getWind()); + } + } + + @Test + public void whenGetForecastByZipCodeInUSARequestAsJSON_thenReturnNotNull() { + final String forecastJson = getClient() + .forecast5Day3HourStep() + .byZipCodeInUSA("10005") + .language(Language.SPANISH) + .unitSystem(UnitSystem.IMPERIAL) + .count(15) + .retrieve() + .asJSON(); + + Assert.assertTrue(forecastJson.startsWith("{")); + } + + @Test + public void whenGetForecastByZipCodeInUSARequestAsXML_thenReturnNotNull() { + final String forecastXml = getClient() + .forecast5Day3HourStep() + .byZipCodeInUSA("10005") + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asXML(); + + Assert.assertTrue(forecastXml.startsWith("<")); + } + + @Test + public void whenGetForecastByZipCodeAndCountryCodeRequestAsJava_thenReturnNotNull() { + final Forecast forecast = getClient() + .forecast5Day3HourStep() + .byZipCodeAndCountry("220015", "by") + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .count(15) + .retrieve() + .asJava(); + + Assert.assertNotNull(forecast); + Assert.assertNotNull(forecast.getLocation()); + Assert.assertNotNull(forecast.getWeatherForecasts()); + for (WeatherForecast weatherForecast : forecast.getWeatherForecasts()) { + Assert.assertNotNull(weatherForecast.getState()); + Assert.assertNotNull(weatherForecast.getDescription()); + Assert.assertNotNull(weatherForecast.getForecastTime()); + Assert.assertNotNull(weatherForecast.getTemperature()); + Assert.assertNotNull(weatherForecast.getAtmosphericPressure()); + Assert.assertNotNull(weatherForecast.getHumidity()); + Assert.assertNotNull(weatherForecast.getWind()); + } + } + + @Test + public void whenGetForecastByZipCodeAndCountryCodeRequestAsJSON_thenReturnNotNull() { + final String forecastJson = getClient() + .forecast5Day3HourStep() + .byZipCodeAndCountry("220015", "by") + .language(Language.SPANISH) + .unitSystem(UnitSystem.IMPERIAL) + .count(15) + .retrieve() + .asJSON(); + + Assert.assertTrue(forecastJson.startsWith("{")); + } + + @Test + public void whenGetForecastByZipCodeAndCountryCodeRequestAsXML_thenReturnNotNull() { + final String forecastXml = getClient() + .forecast5Day3HourStep() + .byZipCodeAndCountry("220015", "by") + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asXML(); + + Assert.assertTrue(forecastXml.startsWith("<")); + } + + @Test + public void whenGetForecastByCityNameAsyncRequestAsJava_thenReturnNotNull() throws ExecutionException, InterruptedException { + final CompletableFuture forecastFuture = getClient() + .forecast5Day3HourStep() + .byCityName("Minsk") + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .count(15) + .retrieveAsync() + .asJava(); + + Assert.assertNotNull(forecastFuture); + System.out.println(forecastFuture.get()); + } + + @Test + public void whenGetForecastByCityNameAsyncRequestAsJSON_thenReturnNotNull() throws ExecutionException, InterruptedException { + final CompletableFuture forecastFuture = getClient() + .forecast5Day3HourStep() + .byCityId(350001514) + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .count(15) + .retrieveAsync() + .asJSON(); + + Assert.assertNotNull(forecastFuture); + System.out.println(forecastFuture.get()); + } + + @Test + public void whenGetForecastByCityNameAsyncRequestAsXML_thenReturnNotNull() throws ExecutionException, InterruptedException { + final CompletableFuture forecastFuture = getClient() + .forecast5Day3HourStep() + .byCityId(350001514) + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .count(15) + .retrieveAsync() + .asXML(); + + Assert.assertNotNull(forecastFuture); + System.out.println(forecastFuture.get()); + } + + @Test(expected = InvalidAuthTokenException.class) + public void whenRequestCurrentWeatherWithInvalidApiKey_thenThrowAnException() { + OpenWeatherMapClient client = new OpenWeatherMapClient("invalidKey"); + client + .forecast5Day3HourStep() + .byCityId(350001514) + .retrieve() + .asJSON(); + } + + @Test(expected = NoDataFoundException.class) + public void whenRequestCurrentWeatherForInvalidLocation_thenThrowAnException() { + getClient() + .forecast5Day3HourStep() + .byCityName("invalidCity") + .retrieve() + .asJava(); + } +} diff --git a/src/test/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCurrentWeatherIntegrationTest.java b/src/test/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCurrentWeatherIntegrationTest.java new file mode 100644 index 0000000..2fb20a9 --- /dev/null +++ b/src/test/java/com/github/prominence/openweathermap/api/request/weather/multiple/MultipleResultCurrentWeatherIntegrationTest.java @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2021 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.request.weather.multiple; + +import com.github.prominence.openweathermap.api.ApiTest; +import com.github.prominence.openweathermap.api.enums.Language; +import com.github.prominence.openweathermap.api.enums.UnitSystem; +import com.github.prominence.openweathermap.api.exception.InvalidAuthTokenException; +import com.github.prominence.openweathermap.api.exception.NoDataFoundException; +import com.github.prominence.openweathermap.api.model.Coordinate; +import com.github.prominence.openweathermap.api.model.CoordinateRectangle; +import com.github.prominence.openweathermap.api.model.weather.Weather; +import com.github.prominence.openweathermap.api.OpenWeatherMapClient; +import org.junit.Assert; +import org.junit.Test; + +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +public class MultipleResultCurrentWeatherIntegrationTest extends ApiTest { + @Test + public void whenGetMultipleCurrentWeatherByCoordinateRectangleRequestAsJava_thenReturnNotNull() { + final List weatherList = getClient() + .currentWeather() + .multiple() + .byRectangle( + new CoordinateRectangle.Builder() + .setLongitudeLeft(12) + .setLatitudeBottom(32) + .setLongitudeRight(15) + .setLatitudeTop(37) + .build(), + 10 + ) + .language(Language.ROMANIAN) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asJava(); + + Assert.assertNotNull(weatherList); + for (Weather weather : weatherList) { + Assert.assertNotNull(weather); + Assert.assertNotNull(weather.getState()); + Assert.assertNotNull(weather.getDescription()); + Assert.assertNotNull(weather.getCalculatedOn()); + Assert.assertNotNull(weather.getTemperature()); + Assert.assertNotNull(weather.getLocation()); + Assert.assertNotNull(weather.getAtmosphericPressure()); + Assert.assertNotNull(weather.getHumidity()); + Assert.assertNotNull(weather.getWind()); + } + } + + @Test + public void whenGetMultipleCurrentWeatherByCoordinateRectangleRequestAsJSON_thenReturnNotNull() { + final String weatherJson = getClient() + .currentWeather() + .multiple() + .byRectangle(CoordinateRectangle.withValues(12, 32, 15, 37), 10) + .language(Language.ROMANIAN) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asJSON(); + + Assert.assertTrue(weatherJson.startsWith("{")); + } + + @Test + public void whenGetMultipleCurrentWeatherByCitiesInCycleRequestAsJava_thenReturnNotNull() { + final List weatherList = getClient() + .currentWeather() + .multiple() + .byCitiesInCycle(Coordinate.withValues(55.5, 37.5)) + .language(Language.GERMAN) + .unitSystem(UnitSystem.IMPERIAL) + .retrieve() + .asJava(); + + Assert.assertNotNull(weatherList); + for (Weather weather : weatherList) { + System.out.println(weather); + Assert.assertNotNull(weather); + Assert.assertNotNull(weather.getState()); + Assert.assertNotNull(weather.getDescription()); + Assert.assertNotNull(weather.getCalculatedOn()); + Assert.assertNotNull(weather.getTemperature()); + Assert.assertNotNull(weather.getLocation()); + Assert.assertNotNull(weather.getAtmosphericPressure()); + Assert.assertNotNull(weather.getHumidity()); + Assert.assertNotNull(weather.getWind()); + } + } + + @Test + public void whenGetMultipleCurrentWeatherByCitiesInCycleRequestAsJSON_thenReturnNotNull() { + final String weatherJson = getClient() + .currentWeather() + .multiple() + .byCitiesInCycle(Coordinate.withValues(55.5, 37.5)) + .language(Language.GERMAN) + .unitSystem(UnitSystem.IMPERIAL) + .retrieve() + .asJSON(); + + Assert.assertTrue(weatherJson.startsWith("{")); + } + + @Test + public void whenGetMultipleCurrentWeatherByCitiesInCycleRequestAsXML_thenReturnNotNull() { + final String weatherXml = getClient() + .currentWeather() + .multiple() + .byCitiesInCycle(Coordinate.withValues(55.5, 37.5)) + .language(Language.GERMAN) + .unitSystem(UnitSystem.IMPERIAL) + .retrieve() + .asXML(); + + Assert.assertTrue(weatherXml.startsWith("<")); + System.out.println(weatherXml); + } + + @Test + public void whenGetMultipleCurrentWeatherByCitiesInCycleAndCountRequestAsJava_thenReturnNotNull() { + final List weatherList = getClient() + .currentWeather() + .multiple() + .byCitiesInCycle(Coordinate.withValues(55.5, 37.5), 10) + .language(Language.GERMAN) + .unitSystem(UnitSystem.IMPERIAL) + .retrieve() + .asJava(); + + Assert.assertNotNull(weatherList); + for (Weather weather : weatherList) { + System.out.println(weather); + Assert.assertNotNull(weather); + Assert.assertNotNull(weather.getState()); + Assert.assertNotNull(weather.getDescription()); + Assert.assertNotNull(weather.getCalculatedOn()); + Assert.assertNotNull(weather.getTemperature()); + Assert.assertNotNull(weather.getLocation()); + Assert.assertNotNull(weather.getAtmosphericPressure()); + Assert.assertNotNull(weather.getHumidity()); + Assert.assertNotNull(weather.getWind()); + } + } + + @Test + public void whenGetMultipleCurrentWeatherByCitiesInCycleAndCountRequestAsJSON_thenReturnNotNull() { + final String weatherJson = getClient() + .currentWeather() + .multiple() + .byCitiesInCycle(Coordinate.withValues(55.5, 37.5), 10) + .language(Language.GERMAN) + .unitSystem(UnitSystem.IMPERIAL) + .retrieve() + .asJSON(); + + Assert.assertTrue(weatherJson.startsWith("{")); + } + + @Test + public void whenGetMultipleCurrentWeatherByCitiesInCycleAndCountRequestAsXML_thenReturnNotNull() { + final String weatherXml = getClient() + .currentWeather() + .multiple() + .byCitiesInCycle(Coordinate.withValues(55.5, 37.5), 10) + .language(Language.GERMAN) + .unitSystem(UnitSystem.IMPERIAL) + .retrieve() + .asXML(); + + Assert.assertTrue(weatherXml.startsWith("<")); + } + + @Test + public void whenGetMultipleCurrentWeatherByCoordinateAsyncRequestAsJava_thenReturnNotNull() throws ExecutionException, InterruptedException { + final CompletableFuture> weatherListFuture = getClient() + .currentWeather() + .multiple() + .byCitiesInCycle(Coordinate.withValues(55.5, 37.5), 10) + .language(Language.GERMAN) + .unitSystem(UnitSystem.IMPERIAL) + .retrieveAsync() + .asJava(); + + Assert.assertNotNull(weatherListFuture); + List weatherList = weatherListFuture.get(); + Assert.assertTrue(weatherList.size() > 0); + System.out.println(weatherList); + } + + @Test + public void whenGetMultipleCurrentWeatherByCoordinateAsyncRequestAsJson_thenReturnNotNull() throws ExecutionException, InterruptedException { + final CompletableFuture weatherFuture = getClient() + .currentWeather() + .multiple() + .byCitiesInCycle(Coordinate.withValues(55.5, 37.5), 10) + .language(Language.GERMAN) + .unitSystem(UnitSystem.IMPERIAL) + .retrieveAsync() + .asJSON(); + + Assert.assertNotNull(weatherFuture); + System.out.println(weatherFuture.get()); + } + + @Test(expected = InvalidAuthTokenException.class) + public void whenRequestCurrentWeatherWithInvalidApiKey_thenThrowAnException() { + OpenWeatherMapClient client = new OpenWeatherMapClient("invalidKey"); + client + .currentWeather() + .single() + .byCityName("London") + .retrieve() + .asJSON(); + } + + @Test(expected = NoDataFoundException.class) + public void whenRequestCurrentWeatherForInvalidLocation_thenThrowAnException() { + getClient() + .currentWeather() + .single() + .byCityName("InvalidCity") + .retrieve() + .asJava(); + } +} diff --git a/src/test/java/com/github/prominence/openweathermap/api/request/weather/single/SingleResultCurrentWeatherIntegrationTest.java b/src/test/java/com/github/prominence/openweathermap/api/request/weather/single/SingleResultCurrentWeatherIntegrationTest.java new file mode 100644 index 0000000..671fbac --- /dev/null +++ b/src/test/java/com/github/prominence/openweathermap/api/request/weather/single/SingleResultCurrentWeatherIntegrationTest.java @@ -0,0 +1,567 @@ +/* + * Copyright (c) 2021 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.request.weather.single; + +import com.github.prominence.openweathermap.api.ApiTest; +import com.github.prominence.openweathermap.api.enums.Language; +import com.github.prominence.openweathermap.api.enums.UnitSystem; +import com.github.prominence.openweathermap.api.exception.InvalidAuthTokenException; +import com.github.prominence.openweathermap.api.exception.NoDataFoundException; +import com.github.prominence.openweathermap.api.model.Coordinate; +import com.github.prominence.openweathermap.api.model.weather.Weather; +import com.github.prominence.openweathermap.api.OpenWeatherMapClient; +import org.junit.Assert; +import org.junit.Test; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +public class SingleResultCurrentWeatherIntegrationTest extends ApiTest { + @Test + public void whenGetSingleCurrentWeatherByCityNameRequestAsJava_thenReturnNotNull() { + final Weather weather = getClient() + .currentWeather() + .single() + .byCityName("Minsk") + .language(Language.RUSSIAN) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asJava(); + + Assert.assertNotNull(weather); + Assert.assertNotNull(weather.getState()); + Assert.assertNotNull(weather.getDescription()); + Assert.assertNotNull(weather.getCalculatedOn()); + Assert.assertNotNull(weather.getTemperature()); + Assert.assertNotNull(weather.getLocation()); + Assert.assertNotNull(weather.getAtmosphericPressure()); + Assert.assertNotNull(weather.getHumidity()); + Assert.assertNotNull(weather.getWind()); + System.out.println(weather); + } + + @Test + public void whenGetSingleCurrentWeatherByCityNameRequestAsJSON_thenReturnNotNull() { + final String weatherJson = getClient() + .currentWeather() + .single() + .byCityName("Minsk") + .language(Language.RUSSIAN) + .unitSystem(UnitSystem.IMPERIAL) + .retrieve() + .asJSON(); + + Assert.assertTrue(weatherJson.startsWith("{")); + } + + @Test + public void whenGetSingleCurrentWeatherByCityNameRequestAsXML_thenReturnNotNull() { + final String weatherXml = getClient() + .currentWeather() + .single() + .byCityName("Minsk") + .language(Language.RUSSIAN) + .unitSystem(UnitSystem.STANDARD) + .retrieve() + .asXML(); + + Assert.assertTrue(weatherXml.startsWith("<")); + } + + @Test + public void whenGetSingleCurrentWeatherByCityNameRequestAsHTML_thenReturnNotNull() { + final String weatherHtml = getClient() + .currentWeather() + .single() + .byCityName("Minsk") + .language(Language.RUSSIAN) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asHTML(); + + Assert.assertTrue(weatherHtml.startsWith("<")); + } + + @Test + public void whenGetSingleCurrentWeatherByCityNameAndCountryCodeRequestAsJava_thenReturnNotNull() { + final Weather weather = getClient() + .currentWeather() + .single() + .byCityName("Minsk", "BY") + .language(Language.RUSSIAN) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asJava(); + + Assert.assertNotNull(weather); + Assert.assertNotNull(weather.getState()); + Assert.assertNotNull(weather.getDescription()); + Assert.assertNotNull(weather.getCalculatedOn()); + Assert.assertNotNull(weather.getTemperature()); + Assert.assertNotNull(weather.getLocation()); + Assert.assertNotNull(weather.getAtmosphericPressure()); + Assert.assertNotNull(weather.getHumidity()); + Assert.assertNotNull(weather.getWind()); + System.out.println(weather); + } + + @Test + public void whenGetSingleCurrentWeatherByCityNameAndCountryCodeRequestAsJSON_thenReturnNotNull() { + final String weatherJson = getClient() + .currentWeather() + .single() + .byCityName("Minsk", "by") + .language(Language.RUSSIAN) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asJSON(); + + Assert.assertTrue(weatherJson.startsWith("{")); + } + + @Test + public void whenGetSingleCurrentWeatherByCityNameAndCountryCodeRequestAsXML_thenReturnNotNull() { + final String weatherXml = getClient() + .currentWeather() + .single() + .byCityName("Minsk", "by") + .language(Language.RUSSIAN) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asXML(); + + Assert.assertTrue(weatherXml.startsWith("<")); + } + + @Test + public void whenGetSingleCurrentWeatherByCityNameAndCountryCodeRequestAsHTML_thenReturnNotNull() { + final String weatherHtml = getClient() + .currentWeather() + .single() + .byCityName("Minsk", "by") + .language(Language.RUSSIAN) + .unitSystem(UnitSystem.STANDARD) + .retrieve() + .asHTML(); + + Assert.assertTrue(weatherHtml.startsWith("<")); + } + + @Test + public void whenGetSingleCurrentWeatherByCityNameAndStateCodeAndCountryCodeRequestAsJava_thenReturnNotNull() { + final Weather weather = getClient() + .currentWeather() + .single() + .byCityName("New York", "ny", "us") + .language(Language.SLOVAK) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asJava(); + + Assert.assertNotNull(weather); + Assert.assertNotNull(weather.getState()); + Assert.assertNotNull(weather.getDescription()); + Assert.assertNotNull(weather.getCalculatedOn()); + Assert.assertNotNull(weather.getTemperature()); + Assert.assertNotNull(weather.getLocation()); + Assert.assertNotNull(weather.getAtmosphericPressure()); + Assert.assertNotNull(weather.getHumidity()); + Assert.assertNotNull(weather.getWind()); + System.out.println(weather); + } + + @Test + public void whenGetSingleCurrentWeatherByCityNameAndStateCodeAndCountryCodeRequestAsJSON_thenReturnNotNull() { + final String weatherJson = getClient() + .currentWeather() + .single() + .byCityName("New York", "ny", "us") + .language(Language.HUNGARIAN) + .unitSystem(UnitSystem.IMPERIAL) + .retrieve() + .asJSON(); + + Assert.assertTrue(weatherJson.startsWith("{")); + } + + @Test + public void whenGetSingleCurrentWeatherByCityNameAndStateCodeAndCountryCodeRequestAsXML_thenReturnNotNull() { + final String weatherXml = getClient() + .currentWeather() + .single() + .byCityName("New York", "ny", "us") + .language(Language.ROMANIAN) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asXML(); + + Assert.assertTrue(weatherXml.startsWith("<")); + } + + @Test + public void whenGetSingleCurrentWeatherByCityNameAndStateCodeAndCountryCodeRequestAsHTML_thenReturnNotNull() { + final String weatherHtml = getClient() + .currentWeather() + .single() + .byCityName("New York", "ny", "us") + .language(Language.ARABIC) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asHTML(); + + Assert.assertTrue(weatherHtml.startsWith("<")); + } + + @Test + public void whenGetSingleCurrentWeatherByCityIdRequestAsJava_thenReturnNotNull() { + final Weather weather = getClient() + .currentWeather() + .single() + .byCityId(350001514) + .language(Language.GERMAN) + .retrieve() + .asJava(); + + Assert.assertNotNull(weather); + Assert.assertNotNull(weather.getState()); + Assert.assertNotNull(weather.getDescription()); + Assert.assertNotNull(weather.getCalculatedOn()); + Assert.assertNotNull(weather.getTemperature()); + Assert.assertNotNull(weather.getLocation()); + Assert.assertNotNull(weather.getAtmosphericPressure()); + Assert.assertNotNull(weather.getHumidity()); + Assert.assertNotNull(weather.getWind()); + System.out.println(weather); + } + + @Test + public void whenGetSingleCurrentWeatherByCityIdRequestAsJSON_thenReturnNotNull() { + final String weatherJson = getClient() + .currentWeather() + .single() + .byCityId(350001514) + .language(Language.GERMAN) + .retrieve() + .asJSON(); + + Assert.assertTrue(weatherJson.startsWith("{")); + } + + @Test + public void whenGetSingleCurrentWeatherByCityIdRequestAsXML_thenReturnNotNull() { + final String weatherXml = getClient() + .currentWeather() + .single() + .byCityId(350001514) + .language(Language.GERMAN) + .retrieve() + .asXML(); + + Assert.assertTrue(weatherXml.startsWith("<")); + } + + @Test + public void whenGetSingleCurrentWeatherByCityIdRequestAsHTML_thenReturnNotNull() { + final String weatherHtml = getClient() + .currentWeather() + .single() + .byCityId(350001514) + .language(Language.GERMAN) + .retrieve() + .asXML(); + + Assert.assertTrue(weatherHtml.startsWith("<")); + } + + @Test + public void whenGetSingleCurrentWeatherByCoordinateRequestAsJava_thenReturnNotNull() { + final Weather weather = getClient() + .currentWeather() + .single() + .byCoordinate(Coordinate.withValues(5, 5)) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asJava(); + + Assert.assertNotNull(weather); + Assert.assertNotNull(weather.getState()); + Assert.assertNotNull(weather.getDescription()); + Assert.assertNotNull(weather.getCalculatedOn()); + Assert.assertNotNull(weather.getTemperature()); + Assert.assertNotNull(weather.getLocation()); + Assert.assertNotNull(weather.getAtmosphericPressure()); + Assert.assertNotNull(weather.getHumidity()); + Assert.assertNotNull(weather.getWind()); + System.out.println(weather); + } + + @Test + public void whenGetSingleCurrentWeatherByCoordinateRequestAsJSON_thenReturnNotNull() { + final String weatherJson = getClient() + .currentWeather() + .single() + .byCoordinate(Coordinate.withValues(5, 5)) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asJSON(); + + Assert.assertTrue(weatherJson.startsWith("{")); + } + + @Test + public void whenGetSingleCurrentWeatherByCoordinateRequestAsXML_thenReturnNotNull() { + final String weatherXml = getClient() + .currentWeather() + .single() + .byCoordinate(Coordinate.withValues(5, 5)) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asXML(); + + Assert.assertTrue(weatherXml.startsWith("<")); + } + + @Test + public void whenGetSingleCurrentWeatherByCoordinateRequestAsHTML_thenReturnNotNull() { + final String weatherHtml = getClient() + .currentWeather() + .single() + .byCoordinate(Coordinate.withValues(5, 5)) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asHTML(); + + Assert.assertTrue(weatherHtml.startsWith("<")); + } + + @Test + public void whenGetSingleCurrentWeatherByZipCodeAndCountryRequestAsJava_thenReturnNotNull() { + final Weather weather = getClient() + .currentWeather() + .single() + .byZipCodeAndCountry("220015", "by") + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asJava(); + + Assert.assertNotNull(weather); + Assert.assertNotNull(weather.getState()); + Assert.assertNotNull(weather.getDescription()); + Assert.assertNotNull(weather.getCalculatedOn()); + Assert.assertNotNull(weather.getTemperature()); + Assert.assertNotNull(weather.getLocation()); + Assert.assertNotNull(weather.getAtmosphericPressure()); + Assert.assertNotNull(weather.getHumidity()); + Assert.assertNotNull(weather.getWind()); + System.out.println(weather); + } + + @Test + public void whenGetSingleCurrentWeatherByZipCodeAndCountryRequestAsJSON_thenReturnNotNull() { + final String weatherJson = getClient() + .currentWeather() + .single() + .byZipCodeAndCountry("220015", "by") + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asJSON(); + + Assert.assertTrue(weatherJson.startsWith("{")); + } + + @Test + public void whenGetSingleCurrentWeatherByZipCodeAndCountryRequestAsXML_thenReturnNotNull() { + final String weatherXml = getClient() + .currentWeather() + .single() + .byZipCodeAndCountry("220015", "by") + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asXML(); + + Assert.assertTrue(weatherXml.startsWith("<")); + } + + @Test + public void whenGetSingleCurrentWeatherByZipCodeAndCountryRequestAsHTML_thenReturnNotNull() { + final String weatherHtml = getClient() + .currentWeather() + .single() + .byZipCodeAndCountry("220015", "by") + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asHTML(); + + Assert.assertTrue(weatherHtml.startsWith("<")); + } + + @Test + public void whenGetSingleCurrentWeatherByZipCodeInUSARequestAsJava_thenReturnNotNull() { + final Weather weather = getClient() + .currentWeather() + .single() + .byZipCodeInUSA("10006") + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asJava(); + + Assert.assertNotNull(weather); + Assert.assertNotNull(weather.getState()); + Assert.assertNotNull(weather.getDescription()); + Assert.assertNotNull(weather.getCalculatedOn()); + Assert.assertNotNull(weather.getTemperature()); + Assert.assertNotNull(weather.getLocation()); + Assert.assertNotNull(weather.getAtmosphericPressure()); + Assert.assertNotNull(weather.getHumidity()); + Assert.assertNotNull(weather.getWind()); + System.out.println(weather); + } + + @Test + public void whenGetSingleCurrentWeatherByZipCodeInUSARequestAsJSON_thenReturnNotNull() { + final String weatherJson = getClient() + .currentWeather() + .single() + .byZipCodeInUSA("10006") + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asJSON(); + + Assert.assertTrue(weatherJson.startsWith("{")); + } + + @Test + public void whenGetSingleCurrentWeatherByZipCodeInUSARequestAsXML_thenReturnNotNull() { + final String weatherXml = getClient() + .currentWeather() + .single() + .byZipCodeInUSA("10006") + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asXML(); + + Assert.assertTrue(weatherXml.startsWith("<")); + } + + @Test + public void whenGetSingleCurrentWeatherByZipCodeInUSARequestAsHTML_thenReturnNotNull() { + final String weatherHtml = getClient() + .currentWeather() + .single() + .byZipCodeInUSA("10006") + .language(Language.ENGLISH) + .unitSystem(UnitSystem.METRIC) + .retrieve() + .asHTML(); + + Assert.assertTrue(weatherHtml.startsWith("<")); + } + + @Test + public void whenGetAnySingleCurrentWeatherAsyncRequestAsJava_thenReturnNotNull() throws ExecutionException, InterruptedException { + final CompletableFuture weatherFuture = getClient() + .currentWeather() + .single() + .byZipCodeAndCountry("220015", "by") + .language(Language.RUSSIAN) + .unitSystem(UnitSystem.METRIC) + .retrieveAsync() + .asJava(); + + Assert.assertNotNull(weatherFuture); + System.out.println(weatherFuture.get()); + } + + @Test + public void whenGetAnySingleCurrentWeatherAsyncRequestAsJson_thenReturnNotNull() throws ExecutionException, InterruptedException { + final CompletableFuture weatherFuture = getClient() + .currentWeather() + .single() + .byZipCodeAndCountry("220015", "by") + .language(Language.RUSSIAN) + .unitSystem(UnitSystem.METRIC) + .retrieveAsync() + .asJSON(); + + Assert.assertNotNull(weatherFuture); + System.out.println(weatherFuture.get()); + } + + @Test + public void whenGetAnySingleCurrentWeatherAsyncRequestAsXml_thenReturnNotNull() throws ExecutionException, InterruptedException { + final CompletableFuture weatherXmlFuture = getClient() + .currentWeather() + .single() + .byZipCodeAndCountry("220015", "by") + .language(Language.RUSSIAN) + .unitSystem(UnitSystem.METRIC) + .retrieveAsync() + .asXML(); + + Assert.assertNotNull(weatherXmlFuture); + System.out.println(weatherXmlFuture.get()); + } + + @Test + public void whenGetAnySingleCurrentWeatherAsyncRequestAsHtml_thenReturnNotNull() throws ExecutionException, InterruptedException { + final CompletableFuture weatherFuture = getClient() + .currentWeather() + .single() + .byZipCodeAndCountry("220015", "by") + .language(Language.RUSSIAN) + .unitSystem(UnitSystem.METRIC) + .retrieveAsync() + .asHTML(); + + Assert.assertNotNull(weatherFuture); + System.out.println(weatherFuture.get()); + } + + @Test(expected = InvalidAuthTokenException.class) + public void whenRequestCurrentWeatherWithInvalidApiKey_thenThrowAnException() { + OpenWeatherMapClient client = new OpenWeatherMapClient("invalidKey"); + client + .currentWeather() + .multiple() + .byCitiesInCycle(Coordinate.withValues(34.53, 66.74), 10) + .retrieve() + .asJSON(); + } + + @Test(expected = NoDataFoundException.class) + public void whenRequestCurrentWeatherForInvalidLocation_thenThrowAnException() { + getClient() + .currentWeather() + .multiple() + .byCitiesInCycle(Coordinate.withValues(90.00, 66.74), 10) + .retrieve() + .asJava(); + } +} diff --git a/src/test/java/com/github/prominence/openweathermap/api/utils/RequestUtilsUnitTest.java b/src/test/java/com/github/prominence/openweathermap/api/utils/RequestUtilsUnitTest.java index 3f4247a..763f8f7 100644 --- a/src/test/java/com/github/prominence/openweathermap/api/utils/RequestUtilsUnitTest.java +++ b/src/test/java/com/github/prominence/openweathermap/api/utils/RequestUtilsUnitTest.java @@ -1,3 +1,25 @@ +/* + * Copyright (c) 2021 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.github.prominence.openweathermap.api.exception.NoDataFoundException;