57 Commits

Author SHA1 Message Date
Esta Nagy a2b0360e4b New mapping approach (#41)
* New mapping approach
- Refreshes license information in file headers
- Rewrites API models to eliminate most of the custom mapping code
- Redefines API configuration options
- Simplifies fetching and mapping logic
- Updates dependency versions
- Reduces Java source level to 8 everywhere to eliminate JavaDoc warnings related to generated code
- Moves some in-line JSONs to class path resources to make tests more clean
- Adds assumptions to skip integration tests if API key is not set
- Adds assumptions to skip One Call API tests unless RUN_ONE_CALL env var is set
- Solves issue around UnsupportedOperationExceptions in certain terminators
- Adds option to use secure channel for picture URLs
- Adds new tests

Signed-off-by: Esta Nagy <nagyesta@gmail.com>

* New mapping approach - Code review
- Minor fixes
- Adds new tests

Signed-off-by: Esta Nagy <nagyesta@gmail.com>

* New mapping approach - Code review
- Add more tests

Signed-off-by: Esta Nagy <nagyesta@gmail.com>

* New mapping approach - Code review
- Unified coordinate and time period usage
- Fixed local system dependent test

Signed-off-by: Esta Nagy <nagyesta@gmail.com>

* New mapping approach - Code review
- Fixed line separator issue in response processing
- Changed how unitSystem can be defined by moving this parameter to the JSON/XML/HTML terminator methods

Signed-off-by: Esta Nagy <nagyesta@gmail.com>

Signed-off-by: Esta Nagy <nagyesta@gmail.com>
2022-10-01 00:57:01 +03:00
Prominence b83b121e90 Adjusted to use HTTPS protocol by default. Added possibility to change request protocol. 2022-08-13 16:08:35 +03:00
Prominence fb2e0e01be Updated README. 2022-05-03 15:01:05 +03:00
Prominence 2d81dadfad Fixed javadoc layout. 2022-05-02 22:35:52 +03:00
Prominence 5e4b34632e Reimplemented request executor. Added possibility to test requests with mocked http requests. 2022-05-02 20:12:34 +03:00
Prominence 6c1a1642f1 Implemented first part of Road Risk API. 2022-05-02 01:19:19 +03:00
Prominence 8a1daa0fe2 Updated 5 Day / 3 Hour Forecast functionality. 2022-05-01 21:21:24 +03:00
Prominence 7e88fe597c Updated javadocs. 2022-05-01 18:23:17 +03:00
Prominence aa48ac3aa0 Implemented Solar Radiation API functionality. Small refactoring. 2022-05-01 18:19:33 +03:00
Prominence 7f0866ffa2 Implemented climatic forecast for 30 days. Some refactoring. 2022-05-01 01:23:51 +03:00
Prominence 4fdb48986e A bunch of global refactoring and improvements.
Improved coverage reports generation.
Updated docs.
Moved logic out of large mappers into small deserializers.
Implemented Geocoding API functionality.
Implemented Hourly forecast functionality.
Implemented Daily forecast functionality.
Renamed Coordinate class.
Reimplemented Current Weather API: removed multiple locations requests. Marked officially deprecated methods as @Deprecated.
Updated tests.
2022-04-30 01:35:45 +03:00
Prominence 8ca55b15f7 Adjusted to use 17 source and 8 target version. Code refactoring. Docs improvements. 2022-04-19 22:15:19 +03:00
Prominence 5ca31780da Updated badges. 2022-04-19 00:03:42 +03:00
Prominence 91a5acdb43 Adjusted jacoco settings. 2022-04-18 23:42:58 +03:00
Prominence 3f5b7f6649 Updated script. 2022-04-18 23:36:42 +03:00
Prominence 9c2a127703 Renamed key. 2022-04-18 23:33:06 +03:00
Prominence e6833c3007 Added jacoco test coverage report generation. 2022-04-18 23:24:16 +03:00
Prominence d1bac609e8 Test commit for cirrus. 2022-04-18 21:55:11 +03:00
Prominence a17f687976 Test commit for cirrus. 2022-04-18 21:51:59 +03:00
Prominence 1ae02e0e49 Test commit for cirrus. 2022-04-18 21:49:06 +03:00
Prominence 46602e1f93 Test commit for cirrus. 2022-04-18 20:58:22 +03:00
Prominence 2553f13fbe Updated docs. 2022-04-18 11:44:54 +03:00
Prominence 905d3876c3 Merge remote-tracking branch 'origin/master' into dev 2022-04-18 11:43:01 +03:00
Prominence 45f0b494b3 Switched from maven to gradle 7.4.2 build tool. 2022-04-18 11:41:02 +03:00
Prominence 93b6b357c1 Switching to 17 version of java. 2022-04-17 01:13:11 +03:00
dependabot[bot] c0dd184965 Bump jacoco-maven-plugin from 0.8.7 to 0.8.8 (#32)
Bumps [jacoco-maven-plugin](https://github.com/jacoco/jacoco) from 0.8.7 to 0.8.8.
- [Release notes](https://github.com/jacoco/jacoco/releases)
- [Commits](https://github.com/jacoco/jacoco/compare/v0.8.7...v0.8.8)

---
updated-dependencies:
- dependency-name: org.jacoco:jacoco-maven-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-17 01:05:54 +03:00
dependabot[bot] 08d0aa091d Bump maven-jar-plugin from 3.2.0 to 3.2.2 (#33)
Bumps [maven-jar-plugin](https://github.com/apache/maven-jar-plugin) from 3.2.0 to 3.2.2.
- [Release notes](https://github.com/apache/maven-jar-plugin/releases)
- [Commits](https://github.com/apache/maven-jar-plugin/compare/maven-jar-plugin-3.2.0...maven-jar-plugin-3.2.2)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-jar-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-17 01:05:36 +03:00
dependabot[bot] 93ae514550 Bump maven-compiler-plugin from 3.8.1 to 3.10.1 (#35)
Bumps [maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.8.1 to 3.10.1.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.8.1...maven-compiler-plugin-3.10.1)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-compiler-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-17 01:05:17 +03:00
Alexey Zinchenko 47d52d953a Delete dependabot.yml 2022-04-17 01:05:06 +03:00
dependabot[bot] 2a15788569 Bump maven-javadoc-plugin from 3.3.0 to 3.3.2 (#36)
Bumps [maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.3.0 to 3.3.2.
- [Release notes](https://github.com/apache/maven-javadoc-plugin/releases)
- [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.3.0...maven-javadoc-plugin-3.3.2)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-javadoc-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-17 01:04:27 +03:00
Prominence 37d7a2b3f5 Merge remote-tracking branch 'origin/master' into dev 2022-04-17 00:59:49 +03:00
dependabot[bot] 6790848c32 Bump nexus-staging-maven-plugin from 1.6.8 to 1.6.12 (#34)
* Merged changes from dev branch.

* Updated README.md

* Releasing 2.3.0 version.

* Bump nexus-staging-maven-plugin from 1.6.8 to 1.6.12

Bumps nexus-staging-maven-plugin from 1.6.8 to 1.6.12.

---
updated-dependencies:
- dependency-name: org.sonatype.plugins:nexus-staging-maven-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: Alexey Zinchenko <Prominence@users.noreply.github.com>
Co-authored-by: Prominence <alexey.zinchenko@protonmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-17 00:49:21 +03:00
Prominence ec988c5f26 Releasing 2.3.0 version. 2022-04-17 00:41:54 +03:00
Prominence 7b8d46bb7a Updated README.md 2022-04-17 00:26:38 +03:00
Alexey Zinchenko 6ae281af0d Merged changes from dev branch. 2022-04-17 00:25:07 +03:00
Prominence 23a1fa5a7b Preparing for merge. 2022-04-17 00:23:16 +03:00
Prominence 1cac951aaa Preparing for merge. 2022-04-17 00:20:23 +03:00
Prominence 58e648be42 Updated SNAPSHOT version. 2022-04-16 22:32:10 +03:00
Prominence f30bcad5dc Updated SNAPSHOT version. 2022-04-16 22:26:32 +03:00
Prominence 5793722181 Updated docs about timeout settings. 2022-04-15 00:40:51 +03:00
Prominence 40462397c1 Added methods and fields to represent daily moonrise/moonset information. Added tests. Fixed UKRAINIAN language constant name. Updated docs. 2022-04-15 00:37:04 +03:00
Prominence 44b543e65c Another portion of refactoring. Updated dependencies. 2022-04-14 23:30:44 +03:00
Prominence 13b20fc7e9 Moved mappers into separate package. 2022-04-14 20:28:23 +03:00
Prominence 2a531dd683 Started global refactoring. Added timeout parameters for requests. 2022-04-13 00:13:27 +03:00
dependabot-preview[bot] 1e1054903e Bump slf4j-api from 1.7.31 to 1.7.32 (#30)
Bumps [slf4j-api](https://github.com/qos-ch/slf4j) from 1.7.31 to 1.7.32.
- [Release notes](https://github.com/qos-ch/slf4j/releases)
- [Commits](https://github.com/qos-ch/slf4j/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-07-21 11:00:43 +03:00
dependabot-preview[bot] ff5b6c7a33 Bump jackson-databind from 2.12.3 to 2.12.4 (#29)
Bumps [jackson-databind](https://github.com/FasterXML/jackson) from 2.12.3 to 2.12.4.
- [Release notes](https://github.com/FasterXML/jackson/releases)
- [Commits](https://github.com/FasterXML/jackson/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-07-07 10:55:04 +03:00
dependabot-preview[bot] db1cf858d8 Bump slf4j-api from 1.7.30 to 1.7.31 (#28)
Bumps [slf4j-api](https://github.com/qos-ch/slf4j) from 1.7.30 to 1.7.31.
- [Release notes](https://github.com/qos-ch/slf4j/releases)
- [Commits](https://github.com/qos-ch/slf4j/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-06-21 09:13:57 +03:00
dependabot-preview[bot] c2cc110dab Bump maven-javadoc-plugin from 3.2.0 to 3.3.0 (#27)
Bumps [maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.2.0 to 3.3.0.
- [Release notes](https://github.com/apache/maven-javadoc-plugin/releases)
- [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.2.0...maven-javadoc-plugin-3.3.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-05-24 10:58:02 +03:00
dependabot-preview[bot] d4c2472254 Bump junit-jupiter-engine from 5.7.1 to 5.7.2 (#26)
Bumps [junit-jupiter-engine](https://github.com/junit-team/junit5) from 5.7.1 to 5.7.2.
- [Release notes](https://github.com/junit-team/junit5/releases)
- [Commits](https://github.com/junit-team/junit5/compare/r5.7.1...r5.7.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-05-17 11:01:01 +03:00
dependabot-preview[bot] 380e3e458b Bump junit-platform-runner from 1.7.1 to 1.7.2 (#25)
Bumps [junit-platform-runner](https://github.com/junit-team/junit5) from 1.7.1 to 1.7.2.
- [Release notes](https://github.com/junit-team/junit5/releases)
- [Commits](https://github.com/junit-team/junit5/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-05-17 11:00:48 +03:00
dependabot-preview[bot] 246c07db97 Bump maven-gpg-plugin from 1.6 to 3.0.1 (#24)
Bumps [maven-gpg-plugin](https://github.com/apache/maven-gpg-plugin) from 1.6 to 3.0.1.
- [Release notes](https://github.com/apache/maven-gpg-plugin/releases)
- [Commits](https://github.com/apache/maven-gpg-plugin/compare/maven-gpg-plugin-1.6...maven-gpg-plugin-3.0.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-05-10 18:40:15 +03:00
dependabot-preview[bot] f19a627313 Bump jacoco-maven-plugin from 0.8.6 to 0.8.7 (#23)
Bumps [jacoco-maven-plugin](https://github.com/jacoco/jacoco) from 0.8.6 to 0.8.7.
- [Release notes](https://github.com/jacoco/jacoco/releases)
- [Commits](https://github.com/jacoco/jacoco/compare/v0.8.6...v0.8.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-05-05 11:03:47 +03:00
dependabot-preview[bot] 6438c323ff Upgrade to GitHub-native Dependabot (#22)
Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-04-29 01:49:29 +03:00
dependabot-preview[bot] 1cbff68338 Bump jackson-databind from 2.12.2 to 2.12.3 (#21)
Bumps [jackson-databind](https://github.com/FasterXML/jackson) from 2.12.2 to 2.12.3.
- [Release notes](https://github.com/FasterXML/jackson/releases)
- [Commits](https://github.com/FasterXML/jackson/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-04-22 11:05:09 +03:00
Prominence 1e08f4f8ae Switched to snapshot version. 2021-04-17 17:23:57 +03:00
Prominence bfa15fd9fe Made rebase onto master branch.
Implemented Air Pollution API functionality.

Preparing for merge.
2021-04-17 17:22:12 +03:00
Alexey Zinchenko 3c8b00eae1 Releasing 2.2.0 version. 2021-04-17 17:14:51 +03:00
417 changed files with 20069 additions and 16222 deletions
+13
View File
@@ -0,0 +1,13 @@
container:
image: gradle:jdk8
testCoverage_task:
gradle_cache:
folder: ~/.gradle/caches
testCoverage_script: gradle jacocoTestReport && bash <(curl -s https://codecov.io/bash)
cleanup_before_cache_script:
- rm -rf ~/.gradle/caches/$GRADLE_VERSION/
- rm -rf ~/.gradle/caches/transforms-1
- rm -rf ~/.gradle/caches/journal-1
- rm -rf ~/.gradle/caches/jars-3/*/buildSrc.jar
- find ~/.gradle/caches/ -name "*.lock" -type f -delete
+9
View File
@@ -0,0 +1,9 @@
version: 2
updates:
- package-ecosystem: maven
directory: "/"
schedule:
interval: daily
time: "03:00"
open-pull-requests-limit: 10
target-branch: dev
+2 -2
View File
@@ -13,10 +13,10 @@ name: "CodeQL"
on: on:
push: push:
branches: [ master ] branches: [ dev ]
pull_request: pull_request:
# The branches below must be a subset of the branches above # The branches below must be a subset of the branches above
branches: [ master ] branches: [ dev ]
schedule: schedule:
- cron: '27 20 * * 1' - cron: '27 20 * * 1'
+5 -23
View File
@@ -1,24 +1,6 @@
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
*.iml *.iml
.idea/ .idea
target/ .gradle
build
target
out
-11
View File
@@ -1,11 +0,0 @@
language: java
jdk:
- openjdk8
- openjdk11
install: mvn install -DskipTests -Dgpg.skip -B
script: mvn test -Dmaven.skip.deploy=true -B
after_success:
- bash <(curl -s https://codecov.io/bash)
+66 -13
View File
@@ -1,4 +1,4 @@
# OpenWeatherMap Java API [![Build Status][ci-shield]][ci-link] [![codecov][codecov-shield]][codecov-link] # OpenWeatherMap Java API [![Build Status][ci-shield]][ci-link] [![codecov][codecov-shield]][codecov-link] [![FOSSA Status][FOSSA-shield]][FOSSA-link]
Java API for OpenWeatherMap services. Java API for OpenWeatherMap services.
### Implemented features: ### Implemented features:
@@ -6,34 +6,82 @@ Free:
* Current weather data * Current weather data
* 5 day / 3-hour forecast * 5 day / 3-hour forecast
* One Call API * One Call API
* Air pollution
* Geocoding API
Paid:
* Hourly Forecast 4 days
* Daily Forecast 16 days
* Climatic Forecast 30 days
* Solar Radiation API
* Road Risk API
Other:
* Request timeout settings
### Will be implemented later: ### Will be implemented later:
Free: Free:
* Air pollution
* Geocoding API
* Weather Stations * Weather Stations
* Weather Triggers * Weather Triggers
Paid: Paid:
* Daily Forecast 16 days * Bulk Downloading
* Hourly Forecast 4 days * Historical Weather API
* probably others... * Historical Weather API 40 years by timestamp
* Historical Weather API 40 years full archive
* History Bulk
* History Forecast Bulk
* Statistical Weather Data API
* Accumulated Parameters
* Historical Weather Data by State for all ZIP codes, USA
### Maven coordinates: ### Maven coordinates:
```xml ```xml
<dependency> <dependency>
<groupId>com.github.prominence</groupId> <groupId>com.github.prominence</groupId>
<artifactId>openweathermap-api</artifactId> <artifactId>openweathermap-api</artifactId>
<version>2.1.1</version> <version>3.0.0-SNAPSHOT</version>
</dependency> </dependency>
``` ```
```xml
<repositories>
...
<!-- Repository for snapshot versions -->
<repository>
<id>oss.sonatype.org-snapshot</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
...
</repositories>
```
### Gradle coordinates: ### Gradle coordinates:
```groovy ```groovy
compile('com.github.prominence:openweathermap-api:2.1.1') implementation 'com.github.prominence:openweathermap-api:3.0.0-SNAPSHOT'
```
```groovy
repositories {
...
// Repository for snapshot versions
maven {
url "https://oss.sonatype.org/content/repositories/snapshots"
mavenContent {
snapshotsOnly()
}
}
...
}
``` ```
### Documentation ### Documentation
@@ -44,14 +92,19 @@ compile('com.github.prominence:openweathermap-api:2.1.1')
* [OpenWeatherMap Java API - 2.0.1](docs/Release_2.0.1.md) * [OpenWeatherMap Java API - 2.0.1](docs/Release_2.0.1.md)
* [OpenWeatherMap Java API - 2.1.0](docs/Release_2.1.0.md) * [OpenWeatherMap Java API - 2.1.0](docs/Release_2.1.0.md)
* [OpenWeatherMap Java API - 2.1.1](docs/Release_2.1.1.md) * [OpenWeatherMap Java API - 2.1.1](docs/Release_2.1.1.md)
* [OpenWeatherMap Java API - 2.2.0](docs/Release_2.2.0.md)
* [OpenWeatherMap Java API - 2.3.0](docs/Release_2.3.0.md)
* [OpenWeatherMap Java API - SNAPSHOT](docs/SNAPSHOT.md) * [OpenWeatherMap Java API - SNAPSHOT](docs/SNAPSHOT.md)
### License ### License
MIT MIT
[ci-shield]: https://travis-ci.org/Prominence/openweathermap-java-api.svg?branch=master [ci-shield]: https://api.cirrus-ci.com/github/Prominence/openweathermap-java-api.svg?branch=dev
[ci-link]: https://travis-ci.org/Prominence/openweathermap-java-api [ci-link]: https://api.cirrus-ci.com/github/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 [codecov-link]: https://codecov.io/gh/Prominence/openweathermap-java-api
[FOSSA-shield]: https://app.fossa.com/api/projects/git%2Bgithub.com%2FProminence%2Fopenweathermap-java-api.svg?type=shield
[FOSSA-link]: https://app.fossa.com/projects/git%2Bgithub.com%2FProminence%2Fopenweathermap-java-api?ref=badge_shield
+118
View File
@@ -0,0 +1,118 @@
plugins {
id 'java-library'
id 'maven-publish'
id 'signing'
id 'jacoco'
id 'io.freefair.lombok' version '6.5.0.3'
}
repositories {
mavenCentral()
}
dependencies {
implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.4'
implementation 'org.slf4j:slf4j-api:1.7.36'
testImplementation 'org.junit.platform:junit-platform-runner:1.9.0'
testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.9.0'
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.9.0'
testImplementation 'ch.qos.logback:logback-classic:1.2.11'
testImplementation 'commons-io:commons-io:2.11.0'
testImplementation 'org.mockito:mockito-core:4.8.0'
}
group = 'com.github.prominence'
version = '3.0.0-SNAPSHOT'
description = 'Java OpenWeatherMap API'
configure([tasks.compileJava]) {
sourceCompatibility = 8
}
ext {
isReleaseVersion = !version.endsWith("SNAPSHOT")
}
java {
withSourcesJar()
withJavadocJar()
}
test {
useJUnitPlatform()
}
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
pom {
name = 'Java OpenWeatherMap API'
description = 'Java API for OpenWeatherMap services.'
url = 'https://github.com/Prominence/openweathermap-java-api'
licenses {
license {
name = 'MIT License'
url = 'https://www.opensource.org/licenses/mit-license.php'
}
}
developers {
developer {
id = 'Prominence'
name = 'Alexey Zinchenko'
email = 'alexey.zinchenko@protonmail.com'
url = 'https://github.com/prominence'
}
}
scm {
connection = 'scm:git:git://github.com/Prominence/openweathermap-java-api.git'
developerConnection = 'scm:git:git@github.com:prominence/openweathermap-java-api.git'
url = 'https://github.com/Prominence/openweathermap-java-api'
}
issueManagement {
url = 'https://github.com/Prominence/openweathermap-java-api/issues'
system = 'GitHub Issues'
}
}
}
}
repositories {
maven {
credentials {
username = project.findProperty('ossrhUsername')
password = project.findProperty('ossrhPassword')
}
url = isReleaseVersion ?
'https://oss.sonatype.org/service/local/staging/deploy/maven2/' :
'https://oss.sonatype.org/content/repositories/snapshots/'
}
}
}
signing {
sign publishing.publications.mavenJava
}
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
tasks.withType(GenerateModuleMetadata) {
enabled = false
}
jacocoTestReport {
dependsOn test // tests are required to run before generating the report
reports {
csv.required = false
xml.required = true
xml.outputLocation = layout.buildDirectory.file('reports/jacoco/report.xml')
html.outputLocation = layout.buildDirectory.dir('jacocoHtml')
}
}
+1 -1
View File
@@ -15,7 +15,7 @@
### Gradle coordinates: ### Gradle coordinates:
```groovy ```groovy
compile('com.github.prominence:openweathermap-api:1.0') implementation 'com.github.prominence:openweathermap-api:1.0'
``` ```
### How to use: ### How to use:
+1 -1
View File
@@ -18,7 +18,7 @@
### Gradle coordinates: ### Gradle coordinates:
```groovy ```groovy
compile('com.github.prominence:openweathermap-api:1.1') implementation 'com.github.prominence:openweathermap-api:1.1'
``` ```
### How to use: ### How to use:
+1 -1
View File
@@ -18,7 +18,7 @@
### Gradle coordinates: ### Gradle coordinates:
```groovy ```groovy
compile('com.github.prominence:openweathermap-api:1.2') implementation 'com.github.prominence:openweathermap-api:1.2'
``` ```
### How to use: ### How to use:
+1 -1
View File
@@ -15,7 +15,7 @@
### Gradle coordinates: ### Gradle coordinates:
```groovy ```groovy
compile('com.github.prominence:openweathermap-api:2.0.0') implementation 'com.github.prominence:openweathermap-api:2.0.0'
``` ```
### How to use: ### How to use:
+1 -1
View File
@@ -15,7 +15,7 @@
### Gradle coordinates: ### Gradle coordinates:
```groovy ```groovy
compile('com.github.prominence:openweathermap-api:2.0.1') implementation 'com.github.prominence:openweathermap-api:2.0.1'
``` ```
### How to use: ### How to use:
+1 -1
View File
@@ -16,7 +16,7 @@
### Gradle coordinates: ### Gradle coordinates:
```groovy ```groovy
compile('com.github.prominence:openweathermap-api:2.1.0') implementation 'com.github.prominence:openweathermap-api:2.1.0'
``` ```
### How to use: ### How to use:
+1 -1
View File
@@ -16,7 +16,7 @@
### Gradle coordinates: ### Gradle coordinates:
```groovy ```groovy
compile('com.github.prominence:openweathermap-api:2.1.1') implementation 'com.github.prominence:openweathermap-api:2.1.1'
``` ```
### How to use: ### How to use:
+538
View File
@@ -0,0 +1,538 @@
### Implemented features:
* Current weather data
* 5 day / 3-hour forecast
* One Call API
* Air Pollution
### Maven coordinates:
```xml
<dependency>
<groupId>com.github.prominence</groupId>
<artifactId>openweathermap-api</artifactId>
<version>2.2.0</version>
</dependency>
```
### Gradle coordinates:
```groovy
implementation 'com.github.prominence:openweathermap-api:2.2.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()`
* `oneCall()`
* `airPollution()`
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<Weather> weatherList = openWeatherClient
.currentWeather()
.multiple()
.byCitiesInCycle(Coordinate.of(55.5, 37.5))
.language(Language.GERMAN)
.unitSystem(UnitSystem.IMPERIAL)
.retrieve()
.asJava();
```
```java
final CompletableFuture<String> 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 |
|---------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `getCalculationTime()` | Returns `LocalDateTime` object with data calculation time. |
| `getWeatherState()` | Returns `WeatherState` object with basic weather state information. |
| `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<String> 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.model.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 |
|-------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `getForecastTime()` | Returns `LocalDateTime` object with weather forecast time. |
| `getWeatherState()` | Returns `WeatherState` object with basic weather state information. |
| `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. |
#### One Call API
Examples:
```java
final CurrentWeatherData currentWeatherData = openWeatherClient
.oneCall()
.current()
.byCoordinate(Coordinate.of(53.54, 27.34))
.language(Language.ENGLISH)
.unitSystem(UnitSystem.METRIC)
.retrieve()
.asJava();
```
```java
final CurrentWeatherData currentWeatherData = openWeatherClient
.oneCall()
.current()
.byCoordinate(Coordinate.of(53.54, 27.34))
.language(Language.ENGLISH)
.unitSystem(UnitSystem.METRIC)
.exclude(OneCallResultOptions.CURRENT, OneCallResultOptions.MINUTELY)
.retrieve()
.asJava();
```
```java
final CompletableFuture<CurrentWeatherData> currentWeatherDataFuture = openWeatherClient
.oneCall()
.current()
.byCoordinate(Coordinate.of(53.54, 27.34))
.language(Language.ENGLISH)
.unitSystem(UnitSystem.METRIC)
.retrieveAsync()
.asJava();
```
```java
final String responseJson = openWeatherClient
.oneCall()
.current()
.byCoordinate(Coordinate.of(53.54, 27.34))
.language(Language.ENGLISH)
.unitSystem(UnitSystem.METRIC)
.retrieve()
.asJSON();
```
```java
final HistoricalWeatherData historicalWeatherData = openWeatherClient
.oneCall()
.historical()
.byCoordinateAndTimestamp(Coordinate.of(60.99, 30.9), LocalDateTime.now().minusDays(5).toEpochSecond(ZoneOffset.UTC))
.language(Language.ENGLISH)
.unitSystem(UnitSystem.METRIC)
.retrieve()
.asJava();
```
```java
final String responseJson = openWeatherClient
.oneCall()
.historical()
.byCoordinateAndTimestamp(Coordinate.of(60.99, 30.9), LocalDateTime.now().minusDays(5).toEpochSecond(ZoneOffset.UTC))
.language(Language.ENGLISH)
.unitSystem(UnitSystem.METRIC)
.retrieve()
.asJSON();
```
```java
final CompletableFuture<HistoricalWeatherData> historicalWeatherDataFuture = openWeatherClient
.oneCall()
.historical()
.byCoordinateAndTimestamp(Coordinate.of(60.99, 30.9), LocalDateTime.now().minusDays(5).toEpochSecond(ZoneOffset.UTC))
.language(Language.ENGLISH)
.unitSystem(UnitSystem.METRIC)
.retrieveAsync()
.asJava();
```
```java
final CompletableFuture<String> responseJsonFuture = openWeatherClient
.oneCall()
.historical()
.byCoordinateAndTimestamp(Coordinate.of(60.99, 30.9), LocalDateTime.now().minusDays(5).toEpochSecond(ZoneOffset.UTC))
.language(Language.ENGLISH)
.unitSystem(UnitSystem.METRIC)
.retrieveAsync()
.asJSON();
```
You are able to set preferable options(via chain methods) and execute appropriate request.
`com.github.prominence.openweathermap.api.model.onecall.current.CurrentWeatherData`'s useful public methods(setters are not listed):
| Method | Description |
|-------------------------------|--------------------------------------------------------------------------------|
| `getCoordinate()` | Returns `Coordinate` object. Available fields: `latitude`, `longitude`. |
| `getTimezone()` | Returns location timezone object. |
| `getTimezoneOffset()` | Returns zone offset. |
| `getCurrent()` | Returns `Current` object with current weather state if available. |
| `getMinutelyList()` | Returns list of `Minutely` objects if available. |
| `getHourlyList()` | Returns list of `Houlry` objects if available. |
| `getDailyList()` | Returns list of `Daily` objects if available. |
| `getAlerts()` | Returns list of `Alert` objects if available. |
`com.github.prominence.openweathermap.api.model.onecall.Current`'s useful public methods(setters are not listed):
| Method | Description |
|-------------------------------|-------------------------------------------------------------------------------------------------|
| `getForecastTime()` | Returns `LocalDateTime` object with weather forecast time. |
| `getSunriseTime()` | Returns `LocalDateTime` object with sunrise time. |
| `getSunsetTime()` | Returns `LocalDateTime` object with sunset time. |
| `getWeatherState()` | Returns `WeatherState` object with basic weather state information. |
| `getTemperature()` | Returns `Temperature` object. Available fields: `value`, `feelsLike`, `dewPoint` and `unit`. |
| `getAtmosphericPressure()` | Returns `AtmosphericPressure` object. Available fields: `seaLevelValue`. |
| `getHumidity()` | Returns `Humidity` object. Available fields: `value` and `unit`. |
| `getClouds()` | Returns `Clouds` object. Available fields: `value` and `unit`. |
| `getUvIndex()` | Returns UV index value. |
| `getVisibilityInMetres()` | Returns visibility in metres. |
| `getWind()` | Returns `Wind` object. Available fields: `speed`, `degrees`, `gust` and `unit`. |
| `getRain()` | Returns `Rain` object. Available fields: `oneHourLevel` and `unit`. |
| `getSnow()` | Returns `Snow` object. Available fields: `oneHourLevel` and `unit`. |
`com.github.prominence.openweathermap.api.model.onecall.current.Minutely`'s useful public methods(setters are not listed):
| Method | Description |
|-------------------------------|---------------------------------------------------------------|
| `getForecastTime()` | Returns `LocalDateTime` object with weather forecast time. |
| `getPrecipitationVolume()` | Returns precipitation volume. |
`com.github.prominence.openweathermap.api.model.onecall.current.Hourly`'s useful public methods(setters are not listed):
| Method | Description |
|-----------------------------------------------|---------------------------------------------------------------------------------------------------|
| `getForecastTime()` | Returns `LocalDateTime` object with weather forecast time. |
| `getWeatherState()` | Returns `WeatherState` object with basic weather state information. |
| `getTemperature()` | Returns `Temperature` object. Available fields: `value`, `feelsLike`, `dewPoint` and `unit`. |
| `getAtmosphericPressure()` | Returns `AtmosphericPressure` object. Available fields: `seaLevelValue`. |
| `getHumidity()` | Returns `Humidity` object. Available fields: `value` and `unit`. |
| `getClouds()` | Returns `Clouds` object. Available fields: `value` and `unit`. |
| `getUvIndex()` | Returns UV index value. |
| `getVisibilityInMetres()` | Returns visibility in metres. |
| `getWind()` | Returns `Wind` object. Available fields: `speed`, `degrees`, `gust` and `unit`. |
| `getProbabilityOfPrecipitation()` | Returns probability of precipitation(not percentage). |
| `getProbabilityOfPrecipitationPercentage()` | Returns probability of precipitation percentage. |
| `getRain()` | Returns `Rain` object. Available fields: `oneHourLevel` and `unit`. |
| `getSnow()` | Returns `Snow` object. Available fields: `oneHourLevel` and `unit`. |
`com.github.prominence.openweathermap.api.model.onecall.current.Daily`'s useful public methods(setters are not listed):
| Method | Description |
|-----------------------------------------------|---------------------------------------------------------------------------------------------------|
| `getForecastTime()` | Returns `LocalDateTime` object with weather forecast time. |
| `getSunriseTime()` | Returns `LocalDateTime` object with sunrise time. |
| `getSunsetTime()` | Returns `LocalDateTime` object with sunset time. |
| `getWeatherState()` | Returns `WeatherState` object with basic weather state information. |
| `getTemperature()` | Returns `DailyTemperature` object. Available fields: `value`, `feelsLike`, `dewPoint` and `unit`. |
| `getAtmosphericPressure()` | Returns `AtmosphericPressure` object. Available fields: `seaLevelValue`. |
| `getHumidity()` | Returns `Humidity` object. Available fields: `value` and `unit`. |
| `getWind()` | Returns `Wind` object. Available fields: `speed`, `degrees`, `gust` and `unit`. |
| `getClouds()` | Returns `Clouds` object. Available fields: `value` and `unit`. |
| `getUvIndex()` | Returns UV index value. |
| `getProbabilityOfPrecipitation()` | Returns probability of precipitation(not percentage). |
| `getProbabilityOfPrecipitationPercentage()` | Returns probability of precipitation percentage. |
| `getRain()` | Returns `DailyRain` object. Available fields: `value`. |
| `getSnow()` | Returns `DailySnow` object. Available fields: `value`. |
`com.github.prominence.openweathermap.api.model.onecall.current.Alert`'s useful public methods(setters are not listed):
| Method | Description |
|------------------------------|--------------------------------------------------------|
| `getSenderName()` | Returns alert sender name. |
| `getEventName()` | Returns alert event name. |
| `getStartTime()` | Returns `LocalDateTime` when event should start. |
| `getEndTime()` | Returns `LocalDateTime` when event should end. |
| `getDescription()` | Returns alert description. |
`com.github.prominence.openweathermap.api.model.onecall.historical.HistoricalWeatherData`'s useful public methods(setters are not listed):
| Method | Description |
|-------------------------------|-------------------------------------------------------------------------------|
| `getCoordinate()` | Returns `Coordinate` object. Available fields: `latitude`, `longitude`. |
| `getTimezone()` | Returns location timezone object. |
| `getTimezoneOffset()` | Returns zone offset. |
| `getHistoricalWeather()` | Returns `HistoricalWeather` object with historical weather state. |
| `getHourlyList()` | Returns list of `HourlyHistorical` objects. |
`com.github.prominence.openweathermap.api.model.onecall.historical.HistoricalWeather`'s useful public methods(setters are not listed):
| Method | Description |
|-------------------------------|-------------------------------------------------------------------------------------------------|
| `getForecastTime()` | Returns `LocalDateTime` object with weather forecast time. |
| `getSunriseTime()` | Returns `LocalDateTime` object with sunrise time. |
| `getSunsetTime()` | Returns `LocalDateTime` object with sunset time. |
| `getWeatherState()` | Returns `WeatherState` object with basic weather state information. |
| `getTemperature()` | Returns `Temperature` object. Available fields: `value`, `feelsLike`, `dewPoint` and `unit`. |
| `getAtmosphericPressure()` | Returns `AtmosphericPressure` object. Available fields: `seaLevelValue`. |
| `getHumidity()` | Returns `Humidity` object. Available fields: `value` and `unit`. |
| `getClouds()` | Returns `Clouds` object. Available fields: `value` and `unit`. |
| `getUvIndex()` | Returns UV index value. |
| `getVisibilityInMetres()` | Returns visibility in metres. |
| `getWind()` | Returns `Wind` object. Available fields: `speed`, `degrees`, `gust` and `unit`. |
| `getRain()` | Returns `Rain` object. Available fields: `oneHourLevel` and `unit`. |
| `getSnow()` | Returns `Snow` object. Available fields: `oneHourLevel` and `unit`. |
`com.github.prominence.openweathermap.api.model.onecall.historical.HourlyHistorical`'s useful public methods(setters are not listed):
| Method | Description |
|-----------------------------------|---------------------------------------------------------------------------------------------------|
| `getForecastTime()` | Returns `LocalDateTime` object with weather forecast time. |
| `getWeatherState()` | Returns `WeatherState` object with basic weather state information. |
| `getTemperature()` | Returns `Temperature` object. Available fields: `value`, `feelsLike`, `dewPoint` and `unit`. |
| `getAtmosphericPressure()` | Returns `AtmosphericPressure` object. Available fields: `seaLevelValue`. |
| `getHumidity()` | Returns `Humidity` object. Available fields: `value` and `unit`. |
| `getClouds()` | Returns `Clouds` object. Available fields: `value` and `unit`. |
| `getVisibilityInMetres()` | Returns visibility in metres. |
| `getWind()` | Returns `Wind` object. Available fields: `speed`, `degrees`, `gust` and `unit`. |
| `getRain()` | Returns `Rain` object. Available fields: `oneHourLevel` and `unit`. |
| `getSnow()` | Returns `Snow` object. Available fields: `oneHourLevel` and `unit`. |
#### Air Pollution API
Examples:
```java
final AirPollutionDetails airPollutionDetails = openWeatherClient
.airPollution()
.current()
.byCoordinate(Coordinate.of(53.54, 27.34))
.retrieve()
.asJava();
```
```java
final AirPollutionDetails airPollutionDetails = openWeatherClient
.airPollution()
.historical()
.byCoordinateAndPeriod(Coordinate.of(53.54, 27.34), 1606223802, 1606482999)
.retrieve()
.asJava();
```
`com.github.prominence.openweathermap.api.model.air.pollution.AirPollutionDetails`'s useful public methods(setters are not listed):
| Method | Description |
|-------------------------------|---------------------------------------------------------------------------|
| `getCoordinate()` | Returns `Coordinate` object. Available fields: `latitude`, `longitude`. |
| `getAirPollutionRecords()` | Returns list of `AirPollutionRecord` objects. |
`com.github.prominence.openweathermap.api.model.air.pollution.AirPollutionRecord`'s useful public methods(setters are not listed):
| Method | Description |
|-------------------------------|---------------------------------------------------------------------------|
| `getForecastTime()` | Returns `LocalDateTime` object with air pollution forecast time. |
| `getAirQualityIndex()` | Returns `AirQualityIndex` object. |
| `getCO()` | Returns carbon monoxide concentration value in μg/m^3.s. |
| `getCarbonMonoxide()` | An alias for `getCO()` method. |
| `getNO()` | Returns nitrogen monoxide concentration value in μg/m^3. |
| `getNitrogenMonoxide()` | An alias for `getNO()` method. |
| `getNO2()` | Returns nitrogen dioxide concentration value in μg/m^3. |
| `getNitrogenDioxide()` | An alias for `getNO2()` method. |
| `getO3()` | Returns ozone concentration value in μg/m^3. |
| `getOzone()` | An alias for `getO3()` method. |
| `getSO2()` | Returns sulphur dioxide concentration value in μg/m^3. |
| `getSulphurDioxide()` | An alias for `getSO2()` method. |
| `getPM2_5()` | Returns fine particles matter concentration value in μg/m^3. |
| `getFineParticlesMatter()` | An alias for `getPM2_5()` method. |
| `getPM10()` | Returns coarse particulate matter concentration value in μg/m^3. |
| `getCoarseParticulateMatter()`| An alias for `getPM10()` method. |
| `getNH3()` | Returns ammonia concentration value in μg/m^3. |
| `getAmmonia()` | An alias for `getNH3()` method. |
### Constants and options
#### Language
| Constant | Description |
|-----------------------------------|-------------------------------|
| Language.AFRIKAANS | Afrikaans language. |
| Language.ALBANIAN | ALBANIAN language. |
| Language.ARABIC | Arabic language. |
| Language.AZERBAIJANI | Azerbaijani language. |
| Language.BULGARIAN | Bulgarian language. |
| Language.CATALAN | Catalan language. |
| Language.CZECH | Czech language. |
| Language.DANISH | Danish language. |
| Language.GERMAN | German language. |
| Language.GREEK | Greek language. |
| Language.ENGLISH | English language. |
| Language.BASQUE | Basque language. |
| Language.PERSIAN | Persian (Farsi) language. |
| Language.FINNISH | Finnish language. |
| Language.FRENCH | French language. |
| Language.GALICIAN | Galician language. |
| Language.HEBREW | Hebrew language. |
| Language.HINDI | Hindi language. |
| Language.CROATIAN | Croatian language. |
| Language.HUNGARIAN | Hungarian language. |
| Language.INDONESIAN | Indonesian 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.NORWEGIAN | Norwegian language. |
| Language.DUTCH | Dutch language. |
| Language.POLISH | Polish language. |
| Language.PORTUGUESE | Portuguese language. |
| Language.PORTUGUES_BRAZIL | Português Brasil 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.SERBIAN | Serbian language. |
| Language.THAI | Thai 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. |
| Language.ZULU | Zulu 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*)
* org.junit.jupiter:junit-jupiter-engine:5.7.1 (*test*)
* org.junit.platform:junit-platform-runner:1.7.1 (*test*)
+552
View File
@@ -0,0 +1,552 @@
### Implemented features:
* Current weather data
* 5 day / 3-hour forecast
* One Call API
* Air Pollution
Other:
* Request timeout settings
### Maven coordinates:
```xml
<dependency>
<groupId>com.github.prominence</groupId>
<artifactId>openweathermap-api</artifactId>
<version>2.3.0</version>
</dependency>
```
### Gradle coordinates:
```groovy
implementation 'com.github.prominence:openweathermap-api:2.3.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()`
* `oneCall()`
* `airPollution()`
Also, it is possible to set timeouts for the requests on `openWeatherClient` object:
```java
openWeatherClient.setReadTimeout(1000);
openWeatherClient.setConnectTimeout(1000);
```
Timeout settings are passed to the requesters as a copy.
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<Weather> weatherList = openWeatherClient
.currentWeather()
.multiple()
.byCitiesInCycle(Coordinate.of(55.5, 37.5))
.language(Language.GERMAN)
.unitSystem(UnitSystem.IMPERIAL)
.retrieve()
.asJava();
```
```java
final CompletableFuture<String> 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 |
|---------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `getCalculationTime()` | Returns `LocalDateTime` object with data calculation time. |
| `getWeatherState()` | Returns `WeatherState` object with basic weather state information. |
| `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<String> 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.model.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 |
|-------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `getForecastTime()` | Returns `LocalDateTime` object with weather forecast time. |
| `getWeatherState()` | Returns `WeatherState` object with basic weather state information. |
| `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. |
#### One Call API
Examples:
```java
final CurrentWeatherData currentWeatherData = openWeatherClient
.oneCall()
.current()
.byCoordinate(Coordinate.of(53.54, 27.34))
.language(Language.ENGLISH)
.unitSystem(UnitSystem.METRIC)
.retrieve()
.asJava();
```
```java
final CurrentWeatherData currentWeatherData = openWeatherClient
.oneCall()
.current()
.byCoordinate(Coordinate.of(53.54, 27.34))
.language(Language.ENGLISH)
.unitSystem(UnitSystem.METRIC)
.exclude(OneCallResultOptions.CURRENT, OneCallResultOptions.MINUTELY)
.retrieve()
.asJava();
```
```java
final CompletableFuture<CurrentWeatherData> currentWeatherDataFuture = openWeatherClient
.oneCall()
.current()
.byCoordinate(Coordinate.of(53.54, 27.34))
.language(Language.ENGLISH)
.unitSystem(UnitSystem.METRIC)
.retrieveAsync()
.asJava();
```
```java
final String responseJson = openWeatherClient
.oneCall()
.current()
.byCoordinate(Coordinate.of(53.54, 27.34))
.language(Language.ENGLISH)
.unitSystem(UnitSystem.METRIC)
.retrieve()
.asJSON();
```
```java
final HistoricalWeatherData historicalWeatherData = openWeatherClient
.oneCall()
.historical()
.byCoordinateAndTimestamp(Coordinate.of(60.99, 30.9), LocalDateTime.now().minusDays(5).toEpochSecond(ZoneOffset.UTC))
.language(Language.ENGLISH)
.unitSystem(UnitSystem.METRIC)
.retrieve()
.asJava();
```
```java
final String responseJson = openWeatherClient
.oneCall()
.historical()
.byCoordinateAndTimestamp(Coordinate.of(60.99, 30.9), LocalDateTime.now().minusDays(5).toEpochSecond(ZoneOffset.UTC))
.language(Language.ENGLISH)
.unitSystem(UnitSystem.METRIC)
.retrieve()
.asJSON();
```
```java
final CompletableFuture<HistoricalWeatherData> historicalWeatherDataFuture = openWeatherClient
.oneCall()
.historical()
.byCoordinateAndTimestamp(Coordinate.of(60.99, 30.9), LocalDateTime.now().minusDays(5).toEpochSecond(ZoneOffset.UTC))
.language(Language.ENGLISH)
.unitSystem(UnitSystem.METRIC)
.retrieveAsync()
.asJava();
```
```java
final CompletableFuture<String> responseJsonFuture = openWeatherClient
.oneCall()
.historical()
.byCoordinateAndTimestamp(Coordinate.of(60.99, 30.9), LocalDateTime.now().minusDays(5).toEpochSecond(ZoneOffset.UTC))
.language(Language.ENGLISH)
.unitSystem(UnitSystem.METRIC)
.retrieveAsync()
.asJSON();
```
You are able to set preferable options(via chain methods) and execute appropriate request.
`com.github.prominence.openweathermap.api.model.onecall.current.CurrentWeatherData`'s useful public methods(setters are not listed):
| Method | Description |
|-------------------------------|--------------------------------------------------------------------------------|
| `getCoordinate()` | Returns `Coordinate` object. Available fields: `latitude`, `longitude`. |
| `getTimezone()` | Returns location timezone object. |
| `getTimezoneOffset()` | Returns zone offset. |
| `getCurrent()` | Returns `Current` object with current weather state if available. |
| `getMinutelyList()` | Returns list of `Minutely` objects if available. |
| `getHourlyList()` | Returns list of `Houlry` objects if available. |
| `getDailyList()` | Returns list of `Daily` objects if available. |
| `getAlerts()` | Returns list of `Alert` objects if available. |
`com.github.prominence.openweathermap.api.model.onecall.Current`'s useful public methods(setters are not listed):
| Method | Description |
|-------------------------------|-------------------------------------------------------------------------------------------------|
| `getForecastTime()` | Returns `LocalDateTime` object with weather forecast time. |
| `getSunriseTime()` | Returns `LocalDateTime` object with sunrise time. |
| `getSunsetTime()` | Returns `LocalDateTime` object with sunset time. |
| `getWeatherState()` | Returns `WeatherState` object with basic weather state information. |
| `getTemperature()` | Returns `Temperature` object. Available fields: `value`, `feelsLike`, `dewPoint` and `unit`. |
| `getAtmosphericPressure()` | Returns `AtmosphericPressure` object. Available fields: `seaLevelValue`. |
| `getHumidity()` | Returns `Humidity` object. Available fields: `value` and `unit`. |
| `getClouds()` | Returns `Clouds` object. Available fields: `value` and `unit`. |
| `getUvIndex()` | Returns UV index value. |
| `getVisibilityInMetres()` | Returns visibility in metres. |
| `getWind()` | Returns `Wind` object. Available fields: `speed`, `degrees`, `gust` and `unit`. |
| `getRain()` | Returns `Rain` object. Available fields: `oneHourLevel` and `unit`. |
| `getSnow()` | Returns `Snow` object. Available fields: `oneHourLevel` and `unit`. |
`com.github.prominence.openweathermap.api.model.onecall.current.Minutely`'s useful public methods(setters are not listed):
| Method | Description |
|-------------------------------|---------------------------------------------------------------|
| `getForecastTime()` | Returns `LocalDateTime` object with weather forecast time. |
| `getPrecipitationVolume()` | Returns precipitation volume. |
`com.github.prominence.openweathermap.api.model.onecall.current.Hourly`'s useful public methods(setters are not listed):
| Method | Description |
|-----------------------------------------------|---------------------------------------------------------------------------------------------------|
| `getForecastTime()` | Returns `LocalDateTime` object with weather forecast time. |
| `getWeatherState()` | Returns `WeatherState` object with basic weather state information. |
| `getTemperature()` | Returns `Temperature` object. Available fields: `value`, `feelsLike`, `dewPoint` and `unit`. |
| `getAtmosphericPressure()` | Returns `AtmosphericPressure` object. Available fields: `seaLevelValue`. |
| `getHumidity()` | Returns `Humidity` object. Available fields: `value` and `unit`. |
| `getClouds()` | Returns `Clouds` object. Available fields: `value` and `unit`. |
| `getUvIndex()` | Returns UV index value. |
| `getVisibilityInMetres()` | Returns visibility in metres. |
| `getWind()` | Returns `Wind` object. Available fields: `speed`, `degrees`, `gust` and `unit`. |
| `getProbabilityOfPrecipitation()` | Returns probability of precipitation(not percentage). |
| `getProbabilityOfPrecipitationPercentage()` | Returns probability of precipitation percentage. |
| `getRain()` | Returns `Rain` object. Available fields: `oneHourLevel` and `unit`. |
| `getSnow()` | Returns `Snow` object. Available fields: `oneHourLevel` and `unit`. |
`com.github.prominence.openweathermap.api.model.onecall.current.Daily`'s useful public methods(setters are not listed):
| Method | Description |
|---------------------------------------------|---------------------------------------------------------------------------------------------------|
| `getForecastTime()` | Returns `LocalDateTime` object with weather forecast time. |
| `getSunriseTime()` | Returns `LocalDateTime` object with sunrise time. |
| `getSunsetTime()` | Returns `LocalDateTime` object with sunset time. |
| `getMoonriseTime()` | Returns `LocalDateTime` object with moonrise time. |
| `getMoonsetTime()` | Returns `LocalDateTime` object with moonset time. |
| `getMoonPhase()` | Returns `MoonPhase` object with `MoonType` info and value. |
| `getWeatherState()` | Returns `WeatherState` object with basic weather state information. |
| `getTemperature()` | Returns `DailyTemperature` object. Available fields: `value`, `feelsLike`, `dewPoint` and `unit`. |
| `getAtmosphericPressure()` | Returns `AtmosphericPressure` object. Available fields: `seaLevelValue`. |
| `getHumidity()` | Returns `Humidity` object. Available fields: `value` and `unit`. |
| `getWind()` | Returns `Wind` object. Available fields: `speed`, `degrees`, `gust` and `unit`. |
| `getClouds()` | Returns `Clouds` object. Available fields: `value` and `unit`. |
| `getUvIndex()` | Returns UV index value. |
| `getProbabilityOfPrecipitation()` | Returns probability of precipitation(not percentage). |
| `getProbabilityOfPrecipitationPercentage()` | Returns probability of precipitation percentage. |
| `getRain()` | Returns `DailyRain` object. Available fields: `value`. |
| `getSnow()` | Returns `DailySnow` object. Available fields: `value`. |
`com.github.prominence.openweathermap.api.model.onecall.current.Alert`'s useful public methods(setters are not listed):
| Method | Description |
|------------------------------|--------------------------------------------------------|
| `getSenderName()` | Returns alert sender name. |
| `getEventName()` | Returns alert event name. |
| `getStartTime()` | Returns `LocalDateTime` when event should start. |
| `getEndTime()` | Returns `LocalDateTime` when event should end. |
| `getDescription()` | Returns alert description. |
`com.github.prominence.openweathermap.api.model.onecall.historical.HistoricalWeatherData`'s useful public methods(setters are not listed):
| Method | Description |
|-------------------------------|-------------------------------------------------------------------------------|
| `getCoordinate()` | Returns `Coordinate` object. Available fields: `latitude`, `longitude`. |
| `getTimezone()` | Returns location timezone object. |
| `getTimezoneOffset()` | Returns zone offset. |
| `getHistoricalWeather()` | Returns `HistoricalWeather` object with historical weather state. |
| `getHourlyList()` | Returns list of `HourlyHistorical` objects. |
`com.github.prominence.openweathermap.api.model.onecall.historical.HistoricalWeather`'s useful public methods(setters are not listed):
| Method | Description |
|-------------------------------|-------------------------------------------------------------------------------------------------|
| `getForecastTime()` | Returns `LocalDateTime` object with weather forecast time. |
| `getSunriseTime()` | Returns `LocalDateTime` object with sunrise time. |
| `getSunsetTime()` | Returns `LocalDateTime` object with sunset time. |
| `getWeatherState()` | Returns `WeatherState` object with basic weather state information. |
| `getTemperature()` | Returns `Temperature` object. Available fields: `value`, `feelsLike`, `dewPoint` and `unit`. |
| `getAtmosphericPressure()` | Returns `AtmosphericPressure` object. Available fields: `seaLevelValue`. |
| `getHumidity()` | Returns `Humidity` object. Available fields: `value` and `unit`. |
| `getClouds()` | Returns `Clouds` object. Available fields: `value` and `unit`. |
| `getUvIndex()` | Returns UV index value. |
| `getVisibilityInMetres()` | Returns visibility in metres. |
| `getWind()` | Returns `Wind` object. Available fields: `speed`, `degrees`, `gust` and `unit`. |
| `getRain()` | Returns `Rain` object. Available fields: `oneHourLevel` and `unit`. |
| `getSnow()` | Returns `Snow` object. Available fields: `oneHourLevel` and `unit`. |
`com.github.prominence.openweathermap.api.model.onecall.historical.HourlyHistorical`'s useful public methods(setters are not listed):
| Method | Description |
|-----------------------------------|---------------------------------------------------------------------------------------------------|
| `getForecastTime()` | Returns `LocalDateTime` object with weather forecast time. |
| `getWeatherState()` | Returns `WeatherState` object with basic weather state information. |
| `getTemperature()` | Returns `Temperature` object. Available fields: `value`, `feelsLike`, `dewPoint` and `unit`. |
| `getAtmosphericPressure()` | Returns `AtmosphericPressure` object. Available fields: `seaLevelValue`. |
| `getHumidity()` | Returns `Humidity` object. Available fields: `value` and `unit`. |
| `getClouds()` | Returns `Clouds` object. Available fields: `value` and `unit`. |
| `getVisibilityInMetres()` | Returns visibility in metres. |
| `getWind()` | Returns `Wind` object. Available fields: `speed`, `degrees`, `gust` and `unit`. |
| `getRain()` | Returns `Rain` object. Available fields: `oneHourLevel` and `unit`. |
| `getSnow()` | Returns `Snow` object. Available fields: `oneHourLevel` and `unit`. |
#### Air Pollution API
Examples:
```java
final AirPollutionDetails airPollutionDetails = openWeatherClient
.airPollution()
.current()
.byCoordinate(Coordinate.of(53.54, 27.34))
.retrieve()
.asJava();
```
```java
final AirPollutionDetails airPollutionDetails = openWeatherClient
.airPollution()
.historical()
.byCoordinateAndPeriod(Coordinate.of(53.54, 27.34), 1606223802, 1606482999)
.retrieve()
.asJava();
```
`com.github.prominence.openweathermap.api.model.air.pollution.AirPollutionDetails`'s useful public methods(setters are not listed):
| Method | Description |
|-------------------------------|---------------------------------------------------------------------------|
| `getCoordinate()` | Returns `Coordinate` object. Available fields: `latitude`, `longitude`. |
| `getAirPollutionRecords()` | Returns list of `AirPollutionRecord` objects. |
`com.github.prominence.openweathermap.api.model.air.pollution.AirPollutionRecord`'s useful public methods(setters are not listed):
| Method | Description |
|-------------------------------|---------------------------------------------------------------------------|
| `getForecastTime()` | Returns `LocalDateTime` object with air pollution forecast time. |
| `getAirQualityIndex()` | Returns `AirQualityIndex` object. |
| `getCO()` | Returns carbon monoxide concentration value in μg/m^3.s. |
| `getCarbonMonoxide()` | An alias for `getCO()` method. |
| `getNO()` | Returns nitrogen monoxide concentration value in μg/m^3. |
| `getNitrogenMonoxide()` | An alias for `getNO()` method. |
| `getNO2()` | Returns nitrogen dioxide concentration value in μg/m^3. |
| `getNitrogenDioxide()` | An alias for `getNO2()` method. |
| `getO3()` | Returns ozone concentration value in μg/m^3. |
| `getOzone()` | An alias for `getO3()` method. |
| `getSO2()` | Returns sulphur dioxide concentration value in μg/m^3. |
| `getSulphurDioxide()` | An alias for `getSO2()` method. |
| `getPM2_5()` | Returns fine particles matter concentration value in μg/m^3. |
| `getFineParticlesMatter()` | An alias for `getPM2_5()` method. |
| `getPM10()` | Returns coarse particulate matter concentration value in μg/m^3. |
| `getCoarseParticulateMatter()`| An alias for `getPM10()` method. |
| `getNH3()` | Returns ammonia concentration value in μg/m^3. |
| `getAmmonia()` | An alias for `getNH3()` method. |
### Constants and options
#### Language
| Constant | Description |
|------------------------------|-------------------------------|
| Language.AFRIKAANS | Afrikaans language. |
| Language.ALBANIAN | ALBANIAN language. |
| Language.ARABIC | Arabic language. |
| Language.AZERBAIJANI | Azerbaijani language. |
| Language.BULGARIAN | Bulgarian language. |
| Language.CATALAN | Catalan language. |
| Language.CZECH | Czech language. |
| Language.DANISH | Danish language. |
| Language.GERMAN | German language. |
| Language.GREEK | Greek language. |
| Language.ENGLISH | English language. |
| Language.BASQUE | Basque language. |
| Language.PERSIAN | Persian (Farsi) language. |
| Language.FINNISH | Finnish language. |
| Language.FRENCH | French language. |
| Language.GALICIAN | Galician language. |
| Language.HEBREW | Hebrew language. |
| Language.HINDI | Hindi language. |
| Language.CROATIAN | Croatian language. |
| Language.HUNGARIAN | Hungarian language. |
| Language.INDONESIAN | Indonesian 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.NORWEGIAN | Norwegian language. |
| Language.DUTCH | Dutch language. |
| Language.POLISH | Polish language. |
| Language.PORTUGUESE | Portuguese language. |
| Language.PORTUGUES_BRAZIL | Português Brasil 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.SERBIAN | Serbian language. |
| Language.THAI | Thai language. |
| Language.TURKISH | Turkish language. |
| Language.UKRAINIAN | Ukrainian language. |
| Language.VIETNAMESE | Vietnamese language. |
| Language.CHINESE_SIMPLIFIED | Chinese Simplified language. |
| Language.CHINESE_TRADITIONAL | Chinese Traditional language. |
| Language.ZULU | Zulu 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.13.2.2
* org.slf4j:slf4j-api:1.7.36 (*compile*)
* org.junit.jupiter:junit-jupiter-engine:5.8.2 (*test*)
* org.junit.platform:junit-platform-runner:1.8.2 (*test*)
+181 -78
View File
@@ -1,22 +1,64 @@
### Implemented features: ### Implemented features:
* Current weather data * Current weather data
* 5 day / 3-hour forecast * Hourly forecast
* One Call API * One Call API
* Daily forecast
* Solar Radiation API
* 5 day / 3-hour forecast
* Road Risk API
* Air Pollution
* Geocoding API
Other:
* Request timeout settings
### Maven coordinates: ### Maven coordinates:
```xml ```xml
<dependency> <dependency>
<groupId>com.github.prominence</groupId> <groupId>com.github.prominence</groupId>
<artifactId>openweathermap-api</artifactId> <artifactId>openweathermap-api</artifactId>
<version>2.1.1-SNAPSHOT</version> <version>3.0.0-SNAPSHOT</version>
</dependency> </dependency>
``` ```
```xml
<repositories>
...
<!-- Repository for snapshot versions -->
<repository>
<id>oss.sonatype.org-snapshot</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
...
</repositories>
```
### Gradle coordinates: ### Gradle coordinates:
```groovy ```groovy
compile('com.github.prominence:openweathermap-api:2.1.1-SNAPSHOT') implementation 'com.github.prominence:openweathermap-api:3.0.0-SNAPSHOT'
```
```groovy
repositories {
...
// Repository for snapshot versions
maven {
url "https://oss.sonatype.org/content/repositories/snapshots"
mavenContent {
snapshotsOnly()
}
}
...
}
``` ```
### How to use: ### How to use:
@@ -31,6 +73,14 @@ Currently, available APIs are:
* `currentWeather()` * `currentWeather()`
* `forecast5Day3HourStep()` * `forecast5Day3HourStep()`
* `oneCall()` * `oneCall()`
* `airPollution()`
Also, it is possible to set timeouts for the requests on `openWeatherClient` object:
```java
openWeatherClient.setReadTimeout(1000);
openWeatherClient.setConnectTimeout(1000);
```
Timeout settings are passed to the requesters as a copy.
Default(more or less) customization points: Default(more or less) customization points:
```java ```java
@@ -114,7 +164,7 @@ You are able to set preferable options(via chain methods) and execute appropriat
| `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. | | `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. | | `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. | | `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`. | | `getLocation()` | Returns `Location` object. Available fields: `id`, `name`, `countryCode`, `sunrise` and `sunset` time, `zoneOffset` and `coordinates`. |
| `toString()` | Returns informative string for the whole available weather information. | | `toString()` | Returns informative string for the whole available weather information. |
`toString()` output example: `toString()` output example:
@@ -173,7 +223,7 @@ You are able to set preferable options(via chain methods) and execute appropriat
| Method | Description | | Method | Description |
|-------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------| |-------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|
| `getLocation()` | Returns `Location` object. Available fields: `id`, `name`, `countryCode`, `sunrise` and `sunset` time, `zoneOffset`, `coordinate` and `population`. | | `getLocation()` | Returns `Location` object. Available fields: `id`, `name`, `countryCode`, `sunrise` and `sunset` time, `zoneOffset`, `coordinates` and `population`. |
| `getWeatherForecasts()` | Returns list of `WeatherForecast` objects with forecast information. | | `getWeatherForecasts()` | Returns list of `WeatherForecast` objects with forecast information. |
| `toString()` | Returns informative string for the whole available forecast information. | | `toString()` | Returns informative string for the whole available forecast information. |
@@ -182,7 +232,7 @@ You are able to set preferable options(via chain methods) and execute appropriat
A forecast for Minsk with 15 timestamps. A forecast for Minsk with 15 timestamps.
``` ```
`com.github.prominence.openweathermap.api.model.forecast.WeatherForecast`'s useful public methods(setters are not listed): `com.github.prominence.openweathermap.api.model.forecast.free.WeatherForecast`'s useful public methods(setters are not listed):
| Method | Description | | Method | Description |
|-------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |-------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
@@ -296,7 +346,7 @@ You are able to set preferable options(via chain methods) and execute appropriat
| Method | Description | | Method | Description |
|-------------------------------|--------------------------------------------------------------------------------| |-------------------------------|--------------------------------------------------------------------------------|
| `getCoordinate()` | Returns `Coordinate` object. Available fields: `latitude`, `longitude`. | | `getCoordinates()` | Returns `Coordinate` object. Available fields: `latitude`, `longitude`. |
| `getTimezone()` | Returns location timezone object. | | `getTimezone()` | Returns location timezone object. |
| `getTimezoneOffset()` | Returns zone offset. | | `getTimezoneOffset()` | Returns zone offset. |
| `getCurrent()` | Returns `Current` object with current weather state if available. | | `getCurrent()` | Returns `Current` object with current weather state if available. |
@@ -350,22 +400,25 @@ You are able to set preferable options(via chain methods) and execute appropriat
`com.github.prominence.openweathermap.api.model.onecall.current.Daily`'s useful public methods(setters are not listed): `com.github.prominence.openweathermap.api.model.onecall.current.Daily`'s useful public methods(setters are not listed):
| Method | Description | | Method | Description |
|-----------------------------------------------|---------------------------------------------------------------------------------------------------| |---------------------------------------------|---------------------------------------------------------------------------------------------------|
| `getForecastTime()` | Returns `LocalDateTime` object with weather forecast time. | | `getForecastTime()` | Returns `LocalDateTime` object with weather forecast time. |
| `getSunriseTime()` | Returns `LocalDateTime` object with sunrise time. | | `getSunriseTime()` | Returns `LocalDateTime` object with sunrise time. |
| `getSunsetTime()` | Returns `LocalDateTime` object with sunset time. | | `getSunsetTime()` | Returns `LocalDateTime` object with sunset time. |
| `getWeatherState()` | Returns `WeatherState` object with basic weather state information. | | `getMoonriseTime()` | Returns `LocalDateTime` object with moonrise time. |
| `getTemperature()` | Returns `DailyTemperature` object. Available fields: `value`, `feelsLike`, `dewPoint` and `unit`. | | `getMoonsetTime()` | Returns `LocalDateTime` object with moonset time. |
| `getAtmosphericPressure()` | Returns `AtmosphericPressure` object. Available fields: `seaLevelValue`. | | `getMoonPhase()` | Returns `MoonPhase` object with `MoonType` info and value. |
| `getHumidity()` | Returns `Humidity` object. Available fields: `value` and `unit`. | | `getWeatherState()` | Returns `WeatherState` object with basic weather state information. |
| `getWind()` | Returns `Wind` object. Available fields: `speed`, `degrees`, `gust` and `unit`. | | `getTemperature()` | Returns `DailyTemperature` object. Available fields: `value`, `feelsLike`, `dewPoint` and `unit`. |
| `getClouds()` | Returns `Clouds` object. Available fields: `value` and `unit`. | | `getAtmosphericPressure()` | Returns `AtmosphericPressure` object. Available fields: `seaLevelValue`. |
| `getUvIndex()` | Returns UV index value. | | `getHumidity()` | Returns `Humidity` object. Available fields: `value` and `unit`. |
| `getProbabilityOfPrecipitation()` | Returns probability of precipitation(not percentage). | | `getWind()` | Returns `Wind` object. Available fields: `speed`, `degrees`, `gust` and `unit`. |
| `getProbabilityOfPrecipitationPercentage()` | Returns probability of precipitation percentage. | | `getClouds()` | Returns `Clouds` object. Available fields: `value` and `unit`. |
| `getRain()` | Returns `DailyRain` object. Available fields: `value`. | | `getUvIndex()` | Returns UV index value. |
| `getSnow()` | Returns `DailySnow` object. Available fields: `value`. | | `getProbabilityOfPrecipitation()` | Returns probability of precipitation(not percentage). |
| `getProbabilityOfPrecipitationPercentage()` | Returns probability of precipitation percentage. |
| `getRain()` | Returns `DailyRain` object. Available fields: `value`. |
| `getSnow()` | Returns `DailySnow` object. Available fields: `value`. |
`com.github.prominence.openweathermap.api.model.onecall.current.Alert`'s useful public methods(setters are not listed): `com.github.prominence.openweathermap.api.model.onecall.current.Alert`'s useful public methods(setters are not listed):
@@ -381,7 +434,7 @@ You are able to set preferable options(via chain methods) and execute appropriat
| Method | Description | | Method | Description |
|-------------------------------|-------------------------------------------------------------------------------| |-------------------------------|-------------------------------------------------------------------------------|
| `getCoordinate()` | Returns `Coordinate` object. Available fields: `latitude`, `longitude`. | | `getCoordinates()` | Returns `Coordinate` object. Available fields: `latitude`, `longitude`. |
| `getTimezone()` | Returns location timezone object. | | `getTimezone()` | Returns location timezone object. |
| `getTimezoneOffset()` | Returns zone offset. | | `getTimezoneOffset()` | Returns zone offset. |
| `getHistoricalWeather()` | Returns `HistoricalWeather` object with historical weather state. | | `getHistoricalWeather()` | Returns `HistoricalWeather` object with historical weather state. |
@@ -420,57 +473,107 @@ You are able to set preferable options(via chain methods) and execute appropriat
| `getRain()` | Returns `Rain` object. Available fields: `oneHourLevel` and `unit`. | | `getRain()` | Returns `Rain` object. Available fields: `oneHourLevel` and `unit`. |
| `getSnow()` | Returns `Snow` object. Available fields: `oneHourLevel` and `unit`. | | `getSnow()` | Returns `Snow` object. Available fields: `oneHourLevel` and `unit`. |
#### Air Pollution API
Examples:
```java
final AirPollutionDetails airPollutionDetails = openWeatherClient
.airPollution()
.current()
.byCoordinate(Coordinate.of(53.54, 27.34))
.retrieve()
.asJava();
```
```java
final AirPollutionDetails airPollutionDetails = openWeatherClient
.airPollution()
.historical()
.byCoordinateAndPeriod(Coordinate.of(53.54, 27.34), 1606223802, 1606482999)
.retrieve()
.asJava();
```
`com.github.prominence.openweathermap.api.model.air.pollution.AirPollutionDetails`'s useful public methods(setters are not listed):
| Method | Description |
|-------------------------------|---------------------------------------------------------------------------|
| `getCoordinates()` | Returns `Coordinate` object. Available fields: `latitude`, `longitude`. |
| `getAirPollutionRecords()` | Returns list of `AirPollutionRecord` objects. |
`com.github.prominence.openweathermap.api.model.air.pollution.AirPollutionRecord`'s useful public methods(setters are not listed):
| Method | Description |
|-------------------------------|---------------------------------------------------------------------------|
| `getForecastTime()` | Returns `LocalDateTime` object with air pollution forecast time. |
| `getAirQualityIndex()` | Returns `AirQualityIndex` object. |
| `getCO()` | Returns carbon monoxide concentration value in μg/m^3.s. |
| `getCarbonMonoxide()` | An alias for `getCO()` method. |
| `getNO()` | Returns nitrogen monoxide concentration value in μg/m^3. |
| `getNitrogenMonoxide()` | An alias for `getNO()` method. |
| `getNO2()` | Returns nitrogen dioxide concentration value in μg/m^3. |
| `getNitrogenDioxide()` | An alias for `getNO2()` method. |
| `getO3()` | Returns ozone concentration value in μg/m^3. |
| `getOzone()` | An alias for `getO3()` method. |
| `getSO2()` | Returns sulphur dioxide concentration value in μg/m^3. |
| `getSulphurDioxide()` | An alias for `getSO2()` method. |
| `getPM2_5()` | Returns fine particles matter concentration value in μg/m^3. |
| `getFineParticlesMatter()` | An alias for `getPM2_5()` method. |
| `getPM10()` | Returns coarse particulate matter concentration value in μg/m^3. |
| `getCoarseParticulateMatter()`| An alias for `getPM10()` method. |
| `getNH3()` | Returns ammonia concentration value in μg/m^3. |
| `getAmmonia()` | An alias for `getNH3()` method. |
### Constants and options ### Constants and options
#### Language #### Language
| Constant | Description | | Constant | Description |
|-----------------------------------|-------------------------------| |------------------------------|-------------------------------|
| Language.AFRIKAANS | Afrikaans language. | | Language.AFRIKAANS | Afrikaans language. |
| Language.ALBANIAN | ALBANIAN language. | | Language.ALBANIAN | ALBANIAN language. |
| Language.ARABIC | Arabic language. | | Language.ARABIC | Arabic language. |
| Language.AZERBAIJANI | Azerbaijani language. | | Language.AZERBAIJANI | Azerbaijani language. |
| Language.BULGARIAN | Bulgarian language. | | Language.BULGARIAN | Bulgarian language. |
| Language.CATALAN | Catalan language. | | Language.CATALAN | Catalan language. |
| Language.CZECH | Czech language. | | Language.CZECH | Czech language. |
| Language.DANISH | Danish language. | | Language.DANISH | Danish language. |
| Language.GERMAN | German language. | | Language.GERMAN | German language. |
| Language.GREEK | Greek language. | | Language.GREEK | Greek language. |
| Language.ENGLISH | English language. | | Language.ENGLISH | English language. |
| Language.BASQUE | Basque language. | | Language.BASQUE | Basque language. |
| Language.PERSIAN | Persian (Farsi) language. | | Language.PERSIAN | Persian (Farsi) language. |
| Language.FINNISH | Finnish language. | | Language.FINNISH | Finnish language. |
| Language.FRENCH | French language. | | Language.FRENCH | French language. |
| Language.GALICIAN | Galician language. | | Language.GALICIAN | Galician language. |
| Language.HEBREW | Hebrew language. | | Language.HEBREW | Hebrew language. |
| Language.HINDI | Hindi language. | | Language.HINDI | Hindi language. |
| Language.CROATIAN | Croatian language. | | Language.CROATIAN | Croatian language. |
| Language.HUNGARIAN | Hungarian language. | | Language.HUNGARIAN | Hungarian language. |
| Language.INDONESIAN | Indonesian language. | | Language.INDONESIAN | Indonesian language. |
| Language.ITALIAN | Italian language. | | Language.ITALIAN | Italian language. |
| Language.JAPANESE | Japanese language. | | Language.JAPANESE | Japanese language. |
| Language.KOREAN | Korean language. | | Language.KOREAN | Korean language. |
| Language.LATVIAN | Latvian language. | | Language.LATVIAN | Latvian language. |
| Language.LITHUANIAN | Lithuanian language. | | Language.LITHUANIAN | Lithuanian language. |
| Language.MACEDONIAN | Macedonian language. | | Language.MACEDONIAN | Macedonian language. |
| Language.NORWEGIAN | Norwegian language. | | Language.NORWEGIAN | Norwegian language. |
| Language.DUTCH | Dutch language. | | Language.DUTCH | Dutch language. |
| Language.POLISH | Polish language. | | Language.POLISH | Polish language. |
| Language.PORTUGUESE | Portuguese language. | | Language.PORTUGUESE | Portuguese language. |
| Language.PORTUGUES_BRAZIL | Português Brasil language. | | Language.PORTUGUES_BRAZIL | Português Brasil language. |
| Language.ROMANIAN | Romanian language. | | Language.ROMANIAN | Romanian language. |
| Language.RUSSIAN | Russian language. | | Language.RUSSIAN | Russian language. |
| Language.SWEDISH | Swedish language. | | Language.SWEDISH | Swedish language. |
| Language.SLOVAK | Slovak language. | | Language.SLOVAK | Slovak language. |
| Language.SLOVENIAN | Slovenian language. | | Language.SLOVENIAN | Slovenian language. |
| Language.SPANISH | Spanish language. | | Language.SPANISH | Spanish language. |
| Language.SERBIAN | Serbian language. | | Language.SERBIAN | Serbian language. |
| Language.THAI | Thai language. | | Language.THAI | Thai language. |
| Language.TURKISH | Turkish language. | | Language.TURKISH | Turkish language. |
| Language.UKRANIAN | Ukrainian language. | | Language.UKRAINIAN | Ukrainian language. |
| Language.VIETNAMESE | Vietnamese language. | | Language.VIETNAMESE | Vietnamese language. |
| Language.CHINESE_SIMPLIFIED | Chinese Simplified language. | | Language.CHINESE_SIMPLIFIED | Chinese Simplified language. |
| Language.CHINESE_TRADITIONAL | Chinese Traditional language. | | Language.CHINESE_TRADITIONAL | Chinese Traditional language. |
| Language.ZULU | Zulu language. | | Language.ZULU | Zulu language. |
#### Unit #### Unit
| Constant | Description | | Constant | Description |
@@ -480,7 +583,7 @@ You are able to set preferable options(via chain methods) and execute appropriat
| Unit.STANDARD_SYSTEM | Kelvin, meter/sec, hPa, mm(rain, snow). | | Unit.STANDARD_SYSTEM | Kelvin, meter/sec, hPa, mm(rain, snow). |
### Dependencies ### Dependencies
* com.fasterxml.jackson.core:jackson-databind:2.12.2 * com.fasterxml.jackson.core:jackson-databind:2.13.2.2
* org.slf4j:slf4j-api:1.7.30 (*compile*) * org.slf4j:slf4j-api:1.7.36 (*compile*)
* org.junit.jupiter:junit-jupiter-engine:5.7.1 (*test*) * org.junit.jupiter:junit-jupiter-engine:5.8.2 (*test*)
* org.junit.platform:junit-platform-runner:1.7.1 (*test*) * org.junit.platform:junit-platform-runner:1.8.2 (*test*)
Binary file not shown.
+5
View File
@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored Executable
+234
View File
@@ -0,0 +1,234 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
Vendored
+89
View File
@@ -0,0 +1,89 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
+5
View File
@@ -0,0 +1,5 @@
# This file is generated by the 'io.freefair.lombok' Gradle plugin
config.stopBubbling = true
lombok.addSuppressWarnings = true
lombok.addLombokGeneratedAnnotation = true
lombok.nonNull.exceptionType = IllegalArgumentException
-187
View File
@@ -1,187 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.github.prominence</groupId>
<artifactId>openweathermap-api</artifactId>
<version>2.1.1</version>
<packaging>jar</packaging>
<name>Java OpenWeatherMap API</name>
<description>Java API for OpenWeatherMap services.</description>
<url>https://github.com/Prominence/openweathermap-java-api</url>
<scm>
<url>https://github.com/Prominence/openweathermap-java-api</url>
<connection>scm:git:git://github.com/Prominence/openweathermap-java-api.git</connection>
<developerConnection>scm:git:git@github.com:prominence/openweathermap-java-api.git</developerConnection>
</scm>
<issueManagement>
<url>https://github.com/Prominence/openweathermap-java-api/issues</url>
<system>GitHub Issues</system>
</issueManagement>
<licenses>
<license>
<name>MIT License</name>
<url>https://www.opensource.org/licenses/mit-license.php</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<email>alexey.zinchenko@protonmail.com</email>
<name>Alexey Zinchenko</name>
<url>https://github.com/prominence</url>
<id>Prominence</id>
</developer>
</developers>
<distributionManagement>
<snapshotRepository>
<id>ossrh</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
<repository>
<id>ossrh</id>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
</distributionManagement>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<excludes>
<exclude>**/test/*</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.8</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>true</autoReleaseAfterClose>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<source>8</source>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.6</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.7.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-runner</artifactId>
<version>1.7.1</version>
</dependency>
</dependencies>
</project>
+1
View File
@@ -0,0 +1 @@
rootProject.name = 'openweathermap-api'
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021 Alexey Zinchenko * Copyright (c) 2021-present Alexey Zinchenko
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@@ -23,55 +23,146 @@
package com.github.prominence.openweathermap.api; package com.github.prominence.openweathermap.api;
import com.github.prominence.openweathermap.api.annotation.SubscriptionAvailability; import com.github.prominence.openweathermap.api.annotation.SubscriptionAvailability;
import com.github.prominence.openweathermap.api.context.ApiConfiguration;
import com.github.prominence.openweathermap.api.context.ApiConfigurationHolder;
import com.github.prominence.openweathermap.api.request.RequestSettings;
import com.github.prominence.openweathermap.api.request.air.pollution.AirPollutionRequester;
import com.github.prominence.openweathermap.api.request.forecast.climatic.ClimaticForecastRequester;
import com.github.prominence.openweathermap.api.request.forecast.daily.DailyForecastRequester;
import com.github.prominence.openweathermap.api.request.forecast.free.FiveDayThreeHourStepForecastRequester; 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.forecast.hourly.FourDaysHourlyForecastRequester;
import com.github.prominence.openweathermap.api.request.geocoding.GeocodingRequester;
import com.github.prominence.openweathermap.api.request.onecall.OneCallWeatherRequester; import com.github.prominence.openweathermap.api.request.onecall.OneCallWeatherRequester;
import com.github.prominence.openweathermap.api.request.onecall.OneCallWeatherRequesterImpl; import com.github.prominence.openweathermap.api.request.radiation.SolarRadiationRequester;
import com.github.prominence.openweathermap.api.request.roadrisk.RoadRiskRequester;
import com.github.prominence.openweathermap.api.request.weather.CurrentWeatherRequester; import com.github.prominence.openweathermap.api.request.weather.CurrentWeatherRequester;
import com.github.prominence.openweathermap.api.request.weather.CurrentWeatherRequesterImpl; import lombok.NonNull;
import static com.github.prominence.openweathermap.api.enums.SubscriptionPlan.*; import static com.github.prominence.openweathermap.api.enums.SubscriptionPlan.ALL;
import static com.github.prominence.openweathermap.api.enums.SubscriptionPlan.DEVELOPER;
import static com.github.prominence.openweathermap.api.enums.SubscriptionPlan.ENTERPRISE;
import static com.github.prominence.openweathermap.api.enums.SubscriptionPlan.PAID;
import static com.github.prominence.openweathermap.api.enums.SubscriptionPlan.PROFESSIONAL;
import static com.github.prominence.openweathermap.api.enums.SubscriptionPlan.SPECIAL;
/** /**
* The main public API client to communicate with OpenWeatherMap services. * The main public API client to communicate with OpenWeatherMap services.
* Requires API key for usage. More info on the website <a href="https://openweathermap.org/api">https://openweathermap.org/api</a>. * Requires API key for usage. More info on the website <a href="https://openweathermap.org/api">https://openweathermap.org/api</a>.
*/ */
public class OpenWeatherMapClient { public class OpenWeatherMapClient {
private final String apiKey; private final ApiConfiguration apiConfiguration;
public OpenWeatherMapClient() {
this(ApiConfigurationHolder.getConfiguration());
}
/** /**
* Created OpenWeatherMap client object. * Created OpenWeatherMap client object.
* @param apiKey API key obtained on <a href="https://home.openweathermap.org/api_keys">OpenWeatherMap site</a>. *
* @param apiConfiguration configuration options.
*/ */
public OpenWeatherMapClient(String apiKey) { public OpenWeatherMapClient(@NonNull ApiConfiguration apiConfiguration) {
this.apiKey = apiKey; this.apiConfiguration = apiConfiguration;
} }
/** /**
* Current Weather <a href="https://openweathermap.org/current">API</a>. * Current Weather <a href="https://openweathermap.org/current">API</a>.
*
* @return requester for retrieving current weather information. * @return requester for retrieving current weather information.
*/ */
@SubscriptionAvailability(plans = ALL) @SubscriptionAvailability(plans = ALL)
public CurrentWeatherRequester currentWeather() { public CurrentWeatherRequester currentWeather() {
return new CurrentWeatherRequesterImpl(apiKey); return new CurrentWeatherRequester(getRequestSettings());
} }
/** /**
* 5 Day / 3 Hour Forecast <a href="https://openweathermap.org/forecast5">API</a>. * Hourly forecast <a href="https://openweathermap.org/api/hourly-forecast">API</a>.
* @return requester for retrieving 5 day/3-hour weather forecast information. *
* @return requester for retrieving hourly weather forecast information for 4 days.
*/ */
@SubscriptionAvailability(plans = ALL) @SubscriptionAvailability(plans = {DEVELOPER, PROFESSIONAL, ENTERPRISE})
public FiveDayThreeHourStepForecastRequester forecast5Day3HourStep() { public FourDaysHourlyForecastRequester forecastHourly4Days() {
return new FiveDayThreeHourStepForecastRequesterImpl(apiKey); return new FourDaysHourlyForecastRequester(getRequestSettings());
} }
/** /**
* One Call <a href="https://openweathermap.org/api/one-call-api">API</a>. * One Call <a href="https://openweathermap.org/api/one-call-api">API</a>.
* To get information about current weather, minute forecast for 1 hour, hourly forecast for 48 hours, daily forecast for 7 days and government weather alerts. * To get information about current weather, minute forecast for 1 hour, hourly forecast for 48 hours, daily forecast for 7 days and government weather alerts.
*
* @return requester for retrieving one call weather information. * @return requester for retrieving one call weather information.
*/ */
@SubscriptionAvailability(plans = ALL) @SubscriptionAvailability(plans = ALL)
public OneCallWeatherRequester oneCall() { public OneCallWeatherRequester oneCall() {
return new OneCallWeatherRequesterImpl(apiKey); return new OneCallWeatherRequester(getRequestSettings());
}
/**
* Daily forecast <a href="https://openweathermap.org/api/hourly-forecast">API</a>.
*
* @return requester for retrieving daily weather forecast information for 16 days.
*/
@SubscriptionAvailability(plans = PAID)
public DailyForecastRequester forecastDaily16Days() {
return new DailyForecastRequester(getRequestSettings());
}
/**
* Climatic forecast <a href="https://openweathermap.org/api/forecast30">API</a>.
*
* @return requester for retrieving climatic weather forecast information for 30 days.
*/
@SubscriptionAvailability(plans = {DEVELOPER, PROFESSIONAL, ENTERPRISE})
public ClimaticForecastRequester climaticForecast30Days() {
return new ClimaticForecastRequester(getRequestSettings());
}
/**
* Solar Radiation <a href="https://openweathermap.org/api/solar-radiation">API</a>.
*
* @return requester for retrieving solar radiation information.
*/
@SubscriptionAvailability(plans = SPECIAL)
public SolarRadiationRequester solarRadiation() {
return new SolarRadiationRequester(getRequestSettings());
}
/**
* 5 Day / 3 Hour Forecast <a href="https://openweathermap.org/forecast5">API</a>.
*
* @return requester for retrieving 5 day/3-hour weather forecast information.
*/
@SubscriptionAvailability(plans = ALL)
public FiveDayThreeHourStepForecastRequester forecast5Day3HourStep() {
return new FiveDayThreeHourStepForecastRequester(getRequestSettings());
}
/**
* Road Risk <a href="https://openweathermap.org/api/road-risk">API</a>.
*
* @return requester for retrieving road risk information.
*/
@SubscriptionAvailability(plans = SPECIAL)
public RoadRiskRequester roadRisk() {
return new RoadRiskRequester(getRequestSettings());
}
/**
* Air Pollution <a href="https://openweathermap.org/api/air-pollution">API</a>.
* Air Pollution API provides current, forecast and historical air pollution data for any coordinates on the globe.
*
* @return requester for air pollution information retrieval.
*/
@SubscriptionAvailability(plans = ALL)
public AirPollutionRequester airPollution() {
return new AirPollutionRequester(getRequestSettings());
}
@SubscriptionAvailability(plans = ALL)
public GeocodingRequester geocoding() {
return new GeocodingRequester(getRequestSettings());
}
private RequestSettings getRequestSettings() {
return new RequestSettings(apiConfiguration);
} }
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021 Alexey Zinchenko * Copyright (c) 2021-present Alexey Zinchenko
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@@ -0,0 +1,53 @@
/*
* Copyright (c) 2021-present 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.conf;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode
public final class TimeoutSettings {
private final Integer connectionTimeout;
private final Integer readTimeout;
public TimeoutSettings() {
this(2000, 2000);
}
public TimeoutSettings(Integer connectionTimeout, Integer readTimeout) {
this.connectionTimeout = connectionTimeout;
this.readTimeout = readTimeout;
}
public TimeoutSettings(TimeoutSettings from) {
this.connectionTimeout = from.connectionTimeout;
this.readTimeout = from.readTimeout;
}
public Integer getConnectionTimeout() {
return connectionTimeout;
}
public Integer getReadTimeout() {
return readTimeout;
}
}
@@ -0,0 +1,121 @@
/*
* Copyright (c) 2021-present 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.context;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.github.prominence.openweathermap.api.conf.TimeoutSettings;
import com.github.prominence.openweathermap.api.core.net.HttpClient;
import com.github.prominence.openweathermap.api.core.net.HttpURLConnectionBasedHttpClient;
import com.github.prominence.openweathermap.api.enums.ApiVariant;
import lombok.Getter;
import lombok.NonNull;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
@Getter
public class ApiConfiguration {
@NonNull
private final String apiKey;
@NonNull
private final Map<ApiVariant, String> baseUrls;
@NonNull
private final HttpClient httpClient;
@NonNull
private final TimeoutSettings defaultTimeoutSettings;
private final ObjectReader objectReader;
private final ObjectWriter objectWriter;
private ApiConfiguration(String apiKey, Map<ApiVariant, String> baseUrls, HttpClient httpClient,
ObjectMapper objectMapper, TimeoutSettings defaultTimeoutSettings) {
this.apiKey = apiKey;
this.baseUrls = Collections.unmodifiableMap(baseUrls);
this.httpClient = httpClient;
this.defaultTimeoutSettings = defaultTimeoutSettings;
this.objectReader = objectMapper.reader();
this.objectWriter = objectMapper.writer();
}
public static ApiConfigurationBuilder builder() {
return new ApiConfigurationBuilder();
}
public static class ApiConfigurationBuilder {
private String apiKey;
private Map<ApiVariant, String> baseUrls;
private HttpClient httpClient = new HttpURLConnectionBasedHttpClient();
private TimeoutSettings defaultTimeoutSettings = new TimeoutSettings();
private ObjectMapper objectMapper = new ObjectMapper();
public ApiConfigurationBuilder() {
baseUrls = Arrays.stream(ApiVariant.values())
.collect(Collectors.toMap(Function.identity(), ApiVariant::getBaseUrl));
}
public ApiConfigurationBuilder apiKey(@NonNull String apiKey) {
this.apiKey = apiKey;
return this;
}
public ApiConfigurationBuilder baseUrls(@NonNull Map<ApiVariant, String> baseUrls) {
final List<ApiVariant> variants = Arrays.stream(ApiVariant.values()).collect(Collectors.toList());
if (!baseUrls.keySet().containsAll(variants)) {
throw new IllegalArgumentException("Not all API variants were found: " + baseUrls.keySet() + " , expected: " + variants);
}
this.baseUrls = new HashMap<>(baseUrls);
return this;
}
public ApiConfigurationBuilder httpClient(@NonNull HttpClient httpClient) {
this.httpClient = httpClient;
return this;
}
public ApiConfigurationBuilder objectMapper(@NonNull ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
return this;
}
public ApiConfigurationBuilder defaultTimeoutSettings(@NonNull TimeoutSettings defaultTimeoutSettings) {
this.defaultTimeoutSettings = new TimeoutSettings(defaultTimeoutSettings);
return this;
}
public ApiConfiguration build() {
return new ApiConfiguration(apiKey, baseUrls, httpClient, objectMapper, defaultTimeoutSettings);
}
public String toString() {
return "ApiConfiguration.ApiConfigurationBuilder(apiKey=" + this.apiKey + ")";
}
}
}
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2021-present 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.context;
import lombok.NonNull;
public class ApiConfigurationHolder {
private static ApiConfiguration configuration = ApiConfiguration.builder()
.apiKey(System.getenv("OPENWEATHER_API_KEY"))
.build();
public static ApiConfiguration getConfiguration() {
return configuration;
}
public static void setConfiguration(@NonNull ApiConfiguration configuration) {
ApiConfigurationHolder.configuration = configuration;
}
}
@@ -0,0 +1,32 @@
/*
* Copyright (c) 2021-present 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.core.net;
import com.github.prominence.openweathermap.api.conf.TimeoutSettings;
public interface HttpClient {
void setTimeoutSettings(TimeoutSettings timeoutSettings);
String executeGetRequest(String url);
String executePostRequest(String url, String body);
}
@@ -0,0 +1,151 @@
/*
* Copyright (c) 2021-present 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.core.net;
import com.github.prominence.openweathermap.api.conf.TimeoutSettings;
import com.github.prominence.openweathermap.api.exception.InvalidAuthTokenException;
import com.github.prominence.openweathermap.api.exception.NoDataFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Optional;
import java.util.stream.Collectors;
public class HttpURLConnectionBasedHttpClient implements HttpClient {
private static final Logger logger = LoggerFactory.getLogger(HttpURLConnectionBasedHttpClient.class);
private TimeoutSettings timeoutSettings;
@Override
public void setTimeoutSettings(TimeoutSettings timeoutSettings) {
this.timeoutSettings = timeoutSettings;
}
@Override
public String executeGetRequest(String url) {
return doExecute(url, RequestExecutor.Method.GET, null);
}
private String doExecute(String url, RequestExecutor.Method method, String body) {
InputStream resultStream = null;
try {
HttpURLConnection connection = getConnection(url);
configureTimeouts(connection);
configureConnection(connection, method, body);
resultStream = evaluateResponse(connection);
logger.debug("Executing OpenWeatherMap API request: " + url);
return convertInputStreamToString(resultStream);
} catch (IllegalStateException | IOException ex) {
logger.error("An error occurred during OpenWeatherMap API response parsing: ", ex);
throw new NoDataFoundException(ex);
} finally {
closeQuietly(resultStream);
}
}
HttpURLConnection getConnection(String url) throws IOException {
return (HttpURLConnection) new URL(url).openConnection();
}
private void closeQuietly(InputStream resultStream) {
if (resultStream != null) {
try {
resultStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
private InputStream evaluateResponse(HttpURLConnection connection) throws IOException {
final int responseCode = connection.getResponseCode();
switch (responseCode) {
case HttpURLConnection.HTTP_OK:
return connection.getInputStream();
case HttpURLConnection.HTTP_UNAUTHORIZED:
throw new InvalidAuthTokenException();
case HttpURLConnection.HTTP_NOT_FOUND:
case HttpURLConnection.HTTP_BAD_REQUEST:
throw new NoDataFoundException();
default:
throw new IllegalStateException("Unexpected value: " + responseCode);
}
}
private void configureTimeouts(HttpURLConnection connection) {
Optional.ofNullable(timeoutSettings)
.ifPresent(ts -> {
Optional.ofNullable(ts.getConnectionTimeout())
.ifPresent(connection::setConnectTimeout);
Optional.ofNullable(ts.getReadTimeout())
.ifPresent(connection::setReadTimeout);
});
}
private void configureConnection(HttpURLConnection connection, RequestExecutor.Method method, String body) throws IOException {
connection.setRequestMethod(method.name());
connection.setRequestProperty("Content-Type", "application/json; utf-8");
connection.setRequestProperty("Accept", "application/json");
addOptionalBodyContent(connection, body);
}
@Override
public String executePostRequest(String url, String body) {
return doExecute(url, RequestExecutor.Method.POST, body);
}
private void addOptionalBodyContent(HttpURLConnection connection, String body) throws IOException {
if (body != null) {
connection.setDoOutput(true);
try (OutputStream os = connection.getOutputStream()) {
byte[] input = body.getBytes(StandardCharsets.UTF_8);
os.write(input, 0, input.length);
}
}
}
/**
* Reads the input stream line-by-line and returns its content in <code>String</code> representation.
*
* @param inputStream input stream to convert.
* @return converted <code>InputStream</code> content.
* @throws IllegalArgumentException in case if input stream is unable to be read.
*/
private String convertInputStreamToString(InputStream inputStream) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
return reader.lines().collect(Collectors.joining(System.lineSeparator()));
} catch (IOException ex) {
logger.error("Error during response reading: ", ex);
throw new IllegalArgumentException(ex);
}
}
}
@@ -0,0 +1,92 @@
/*
* Copyright (c) 2021-present 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.core.net;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.github.prominence.openweathermap.api.enums.ApiVariant;
import com.github.prominence.openweathermap.api.request.RequestSettings;
import java.net.URL;
import java.util.stream.Collectors;
public final class RequestExecutor {
private final RequestSettings requestSettings;
public RequestExecutor(RequestSettings requestSettings) {
this.requestSettings = requestSettings;
}
public String getResponse(ApiVariant variant) {
return getResponse(variant, Method.GET);
}
public String getResponse(ApiVariant variant, Method httpMethod) {
return getResponse(selectRequestUrl(variant), httpMethod);
}
/**
* Executes call to provided API url and retrieves response in <code>String</code> representation.
*
* @param url the url to make API request.
* @param httpMethod HTTP method to execute.
* @return response from the request in <code>String</code> representation.
* @throws IllegalArgumentException in case if provided parameter isn't a valid url for {@link URL} instance.
*/
private String getResponse(String url, Method httpMethod) {
final HttpClient httpClient = requestSettings.getApiConfiguration().getHttpClient();
httpClient.setTimeoutSettings(requestSettings.getTimeoutSettings());
if (httpMethod == Method.GET) {
return httpClient.executeGetRequest(url);
} else {
return httpClient.executePostRequest(url, getSerializedPayload());
}
}
private String selectRequestUrl(ApiVariant variant) {
StringBuilder requestUrlBuilder = new StringBuilder(requestSettings.getApiConfiguration().getBaseUrls().get(variant));
requestUrlBuilder.append(requestSettings.getUrlAppender());
requestUrlBuilder.append('?');
String parameters = requestSettings.getRequestParameters().entrySet().stream()
.map(entry -> entry.getKey() + "=" + entry.getValue())
.collect(Collectors.joining("&"));
requestUrlBuilder.append(parameters);
return requestUrlBuilder.toString();
}
private String getSerializedPayload() {
final ObjectWriter objectWriter = requestSettings.getApiConfiguration().getObjectWriter();
try {
return objectWriter.writeValueAsString(requestSettings.getPayloadObject());
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
public enum Method {
GET,
POST
}
}
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2021-present 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.deserializer;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.github.prominence.openweathermap.api.model.air.pollution.Concentration;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Optional;
public class ConcentrationDeserializer extends JsonDeserializer<Concentration> {
@Override
public Concentration deserialize(JsonParser parser, DeserializationContext context) throws IOException {
return Optional.ofNullable(parser.readValueAs(BigDecimal.class))
.map(Concentration::new)
.orElse(null);
}
}
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2021-present 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.deserializer;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.Optional;
public class EpochSecondsDeserializer extends JsonDeserializer<OffsetDateTime> {
@Override
public OffsetDateTime deserialize(final JsonParser parser, final DeserializationContext context) throws IOException {
return Optional.ofNullable(parser.readValueAs(Long.class))
.map(Instant::ofEpochSecond)
.map((Instant instant) -> OffsetDateTime.ofInstant(instant, ZoneOffset.UTC))
.orElse(null);
}
}
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2021-present 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.deserializer;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Optional;
public class PercentageZeroToOneDeserializer extends JsonDeserializer<Integer> {
@Override
public Integer deserialize(JsonParser parser, DeserializationContext context) throws IOException {
return Optional.ofNullable(parser.readValueAs(BigDecimal.class))
.map(v -> v.multiply(BigDecimal.valueOf(100)))
.map(v -> v.setScale(0, RoundingMode.HALF_EVEN))
.map(BigDecimal::intValue)
.orElse(null);
}
}
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2021-present 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.deserializer;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.github.prominence.openweathermap.api.model.generic.precipitation.PrecipitationIntensity;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Optional;
public class PrecipitationIntensityDeserializer extends JsonDeserializer<PrecipitationIntensity> {
@Override
public PrecipitationIntensity deserialize(JsonParser parser, DeserializationContext context) throws IOException {
return Optional.ofNullable(parser.readValueAs(BigDecimal.class))
.map(PrecipitationIntensity::new)
.orElse(null);
}
}
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2021-present 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.deserializer;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
import java.util.Optional;
public class RequiredPercentageDeserializer extends JsonDeserializer<Integer> {
@Override
public Integer deserialize(JsonParser parser, DeserializationContext context) throws IOException {
return Optional.ofNullable(parser.readValueAs(Integer.class))
.filter(v -> v <= 100)
.filter(v -> v >= 0)
.orElseThrow(() -> new IllegalArgumentException("Invalid data found for percentage"));
}
}
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2021-present 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.deserializer;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.github.prominence.openweathermap.api.model.generic.temperature.TemperatureValue;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Optional;
public class TemperatureValueDeserializer extends JsonDeserializer<TemperatureValue> {
@Override
public TemperatureValue deserialize(JsonParser parser, DeserializationContext context) throws IOException {
return Optional.ofNullable(parser.readValueAs(BigDecimal.class))
.map(TemperatureValue::new)
.orElse(null);
}
}
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2021-present 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.deserializer;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.github.prominence.openweathermap.api.model.generic.visibility.Visibility;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Optional;
public class VisibilityDeserializer extends JsonDeserializer<Visibility> {
@Override
public Visibility deserialize(JsonParser parser, DeserializationContext context) throws IOException {
return Optional.ofNullable(parser.readValueAs(BigDecimal.class))
.map(Visibility::new)
.orElse(null);
}
}
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2021-present 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.deserializer;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.github.prominence.openweathermap.api.model.generic.wind.WindSpeed;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Optional;
public class WindSpeedDeserializer extends JsonDeserializer<WindSpeed> {
@Override
public WindSpeed deserialize(JsonParser parser, DeserializationContext context) throws IOException {
return Optional.ofNullable(parser.readValueAs(BigDecimal.class))
.map(WindSpeed::new)
.orElse(null);
}
}
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021 Alexey Zinchenko * Copyright (c) 2021-present Alexey Zinchenko
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@@ -20,21 +20,22 @@
* SOFTWARE. * SOFTWARE.
*/ */
package com.github.prominence.openweathermap.api.utils; package com.github.prominence.openweathermap.api.deserializer;
import com.github.prominence.openweathermap.api.exception.NoDataFoundException; import com.fasterxml.jackson.core.JsonParser;
import org.junit.jupiter.api.Test; import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import static org.junit.jupiter.api.Assertions.assertThrows; import java.io.IOException;
import java.time.ZoneId;
import java.util.Optional;
public class RequestUtilsUnitTest { public class ZoneIdDeserializer extends JsonDeserializer<ZoneId> {
@Test
public void whenPassInvalidUrl_thenThrowAnException() {
assertThrows(IllegalArgumentException.class, () -> RequestUtils.getResponse("wrongUrl"));
}
@Test @Override
public void whenPassUrlToNonExistingPage_thenThrowAnException() { public ZoneId deserialize(final JsonParser parser, final DeserializationContext context) throws IOException {
assertThrows(NoDataFoundException.class, () -> RequestUtils.getResponse("https://openweathermap.org/somePage")); return Optional.ofNullable(parser.readValueAs(String.class))
.map(ZoneId::of)
.orElse(null);
} }
} }
@@ -0,0 +1,41 @@
/*
* Copyright (c) 2021-present 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.deserializer;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
import java.time.ZoneOffset;
import java.util.Optional;
public class ZoneOffsetDeserializer extends JsonDeserializer<ZoneOffset> {
@Override
public ZoneOffset deserialize(final JsonParser parser, final DeserializationContext context) throws IOException {
return Optional.ofNullable(parser.readValueAs(Integer.class))
.map(ZoneOffset::ofTotalSeconds)
.orElse(null);
}
}
@@ -0,0 +1,83 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Arrays;
/**
* The enum Air quality index.
*/
public enum AirQualityIndex {
/**
* Good air quality index.
*/
GOOD(1),
/**
* Fair air quality index.
*/
FAIR(2),
/**
* Moderate air quality index.
*/
MODERATE(3),
/**
* Poor air quality index.
*/
POOR(4),
/**
* Very poor air quality index.
*/
VERY_POOR(5);
private final int value;
AirQualityIndex(int index) {
this.value = index;
}
/**
* Gets value.
*
* @return the value
*/
public int getValue() {
return value;
}
/**
* Gets by index.
*
* @param index the index
* @return the by index
*/
@JsonCreator
public static AirQualityIndex getByIndex(@JsonProperty("aqi") int index) {
return Arrays.stream(values())
.filter(airQualityIndex -> airQualityIndex.getValue() == index)
.findFirst()
.orElse(null);
}
}
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.enums;
public enum ApiVariant {
BASE("https://api.openweathermap.org/"),
PRO("https://pro.openweathermap.org/");
private final String baseUrl;
ApiVariant(String baseUrl) {
this.baseUrl = baseUrl;
}
public String getBaseUrl() {
return baseUrl;
}
}
@@ -0,0 +1,71 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import java.util.Arrays;
/**
* Enumeration for time of a day representation.
*/
public enum DayTime {
/**
* Day value.
*/
DAY("d"),
/**
* Night value.
*/
NIGHT("n");
private final String value;
DayTime(String value) {
this.value = value;
}
/**
* Returns time of a day value.
*
* @return string value
*/
public String getValue() {
return value;
}
/**
* Finds the appropriate day time based on the short form value.
*
* @param value the short form value (d/n).
* @return day time
*/
@JsonCreator
public static DayTime findByValue(String value) {
return Arrays.stream(values())
.filter(dayTime -> dayTime.getValue().equals(value))
.findFirst()
.orElse(null);
}
}
@@ -0,0 +1,74 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import java.util.Arrays;
public enum EventLevel {
/**
* Unknown event severity.
*/
UNKNOWN(0),
/**
* Green alert.
*/
GREEN(1),
/**
* Yellow alert.
*/
YELLOW(2),
/**
* Orange alert.
*/
ORANGE(3),
/**
* Red alert.
*/
RED(4);
private final int value;
EventLevel(int value) {
this.value = value;
}
public int getValue() {
return value;
}
/**
* Finds the appropriate event level based on the numerical level.
*
* @param value the numerical level.
* @return event level
*/
@JsonCreator
public static EventLevel findByValue(int value) {
return Arrays.stream(values())
.filter(eventLevel -> eventLevel.getValue() == value)
.findFirst()
.orElse(null);
}
}
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021 Alexey Zinchenko * Copyright (c) 2021-present Alexey Zinchenko
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@@ -233,9 +233,9 @@ public enum Language {
TURKISH("tr"), TURKISH("tr"),
/** /**
* Ukranian language. * Ukrainian language.
*/ */
UKRANIAN("uk"), UKRAINIAN("uk"),
/** /**
* Vietnamese language. * Vietnamese language.
@@ -0,0 +1,63 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.enums;
public enum MoonType {
NEW_MOON,
WAXING_CRESCENT,
FIRST_QUARTER_MOON,
WAXING_GIBBOUS,
FULL_MOON,
WANING_GIBBOUS,
LAST_QUARTER_MOON,
WANING_CRESCENT,
INVALID;
private static final double precision = 0.000001d;
public static MoonType valueOf(double numericValue) {
if (equals(numericValue, 0) || equals(numericValue, 1)) {
return NEW_MOON;
} else if (equals(numericValue, 0.25)) {
return FIRST_QUARTER_MOON;
} else if (equals(numericValue, 0.5)) {
return FULL_MOON;
} else if (equals(numericValue, 0.75)) {
return LAST_QUARTER_MOON;
} else if (numericValue > 0 && numericValue < 0.25) {
return WAXING_CRESCENT;
} else if (numericValue > 0.25 && numericValue < 0.5) {
return WAXING_GIBBOUS;
} else if (numericValue > 0.5 && numericValue < 0.75) {
return WANING_GIBBOUS;
} else if (numericValue > 0.75 && numericValue < 1) {
return WANING_CRESCENT;
} else {
return INVALID;
}
}
private static boolean equals(double d1, double d2) {
return Math.abs(d1 - d2) < precision;
}
}
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021 Alexey Zinchenko * Copyright (c) 2021-present Alexey Zinchenko
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021 Alexey Zinchenko * Copyright (c) 2021-present Alexey Zinchenko
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@@ -20,31 +20,22 @@
* SOFTWARE. * SOFTWARE.
*/ */
package com.github.prominence.openweathermap.api.model; package com.github.prominence.openweathermap.api.enums;
/** public enum ResponseType {
* Enumeration for time of a day representation. JSON("json"),
*/ HTML("html"),
public enum DayTime { XML("xml");
/**
* Day value.
*/
DAY("d"),
/**
* Night value.
*/
NIGHT("n");
private final String value; private final String value;
DayTime(String value) { ResponseType(String value) {
this.value = value; this.value = value;
} }
/** /**
* Returns time of a day value. * Returns language's value.
* @return string value * @return value.
*/ */
public String getValue() { public String getValue() {
return value; return value;
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021 Alexey Zinchenko * Copyright (c) 2021-present Alexey Zinchenko
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@@ -20,31 +20,51 @@
* SOFTWARE. * SOFTWARE.
*/ */
package com.github.prominence.openweathermap.api.request.onecall.current; package com.github.prominence.openweathermap.api.enums;
import com.github.prominence.openweathermap.api.model.Coordinate; import com.fasterxml.jackson.annotation.JsonCreator;
import com.github.prominence.openweathermap.api.request.RequestUrlBuilder;
/** import java.util.Arrays;
* The type One call current weather requester.
*/ public enum RoadState {
public class OneCallCurrentWeatherRequesterImpl implements OneCallCurrentWeatherRequester { NO_REPORT(0),
private final RequestUrlBuilder urlBuilder; DRY(1),
MOIST(2),
MOIST_AND_CHEMICALLY_TREATED(3),
WET(4),
WET_AND_CHEMICALLY_TREATED(5),
ICE(6),
FROST(7),
SNOW(8),
SNOW_OR_ICE_WATCH(9),
SNOW_OR_ICE_WARNING(10),
WET_ABOVE_FREEZING(11),
WET_BELOW_FREEZING(12),
ABSORPTION(13),
ABSORPTION_AT_DEWPOINT(14),
DEW(15),
BLACK_ICE_WARNING(16),
OTHER(17),
SLUSH(18);
private final int value;
RoadState(int value) {
this.value = value;
}
public int getValue() {
return value;
}
/** /**
* Instantiates a new One call current weather requester. * Finds the appropriate road state based on the numerical code.
* *
* @param urlBuilder the url builder * @param value the numerical code.
* @return road state
*/ */
public OneCallCurrentWeatherRequesterImpl(RequestUrlBuilder urlBuilder) { @JsonCreator
this.urlBuilder = urlBuilder; public static RoadState findByValue(int value) {
urlBuilder.append("onecall"); return Arrays.stream(values()).filter(roadState -> roadState.getValue() == value).findFirst().orElse(null);
}
@Override
public OneCallCurrentWeatherRequestCustomizer byCoordinate(Coordinate coordinate) {
urlBuilder.addRequestParameter("lat", String.valueOf(coordinate.getLatitude()));
urlBuilder.addRequestParameter("lon", String.valueOf(coordinate.getLongitude()));
return new OneCallCurrentWeatherRequestCustomizerImpl(urlBuilder);
} }
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021 Alexey Zinchenko * Copyright (c) 2021-present Alexey Zinchenko
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@@ -28,9 +28,9 @@ package com.github.prominence.openweathermap.api.enums;
*/ */
public enum SubscriptionPlan { public enum SubscriptionPlan {
/** /**
* Free subscription plan. * An alias that represents any of paid plans: startup, developer, professional or enterprise.
*/ */
FREE, PAID,
/** /**
* Startup subscription plan. * Startup subscription plan.
@@ -52,6 +52,12 @@ public enum SubscriptionPlan {
*/ */
ENTERPRISE, ENTERPRISE,
/**
* Special subscription plan. You should contact a manager to get an access.
*/
SPECIAL,
/** /**
* All existing subscription plans. * All existing subscription plans.
*/ */
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021 Alexey Zinchenko * Copyright (c) 2021-present Alexey Zinchenko
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@@ -47,37 +47,6 @@ public enum UnitSystem {
this.value = value; this.value = value;
} }
/**
* Returns wind unit for current unit system.
* @return wind unit.
*/
public String getWindUnit() {
switch (this) {
case IMPERIAL:
return "miles/hour";
case STANDARD:
case METRIC:
default:
return "meter/sec";
}
}
/**
* Returns temperature unit for current unit system.
* @return temperature unit.
*/
public String getTemperatureUnit() {
switch (this) {
case METRIC:
return "°C";
case IMPERIAL:
return "°F";
case STANDARD:
default:
return "";
}
}
/** /**
* Returns unit system value. * Returns unit system value.
* @return value unit system. * @return value unit system.
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021 Alexey Zinchenko * Copyright (c) 2021-present Alexey Zinchenko
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@@ -22,6 +22,9 @@
package com.github.prominence.openweathermap.api.enums; package com.github.prominence.openweathermap.api.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Arrays; import java.util.Arrays;
import java.util.Optional; import java.util.Optional;
@@ -277,7 +280,7 @@ public enum WeatherCondition {
private final String description; private final String description;
private final String iconId; private final String iconId;
private WeatherCondition(int id, String name, String description, String iconId) { WeatherCondition(int id, String name, String description, String iconId) {
this.id = id; this.id = id;
this.name = name; this.name = name;
this.description = description; this.description = description;
@@ -311,13 +314,24 @@ public enum WeatherCondition {
return description; return description;
} }
/**
* Gets icon id based on part of day.
*
* @param partOfDay The part of day we need the icon for.
* @return the icon id
*/
public String getIconId(DayTime partOfDay) {
return iconId + partOfDay.getValue();
}
/** /**
* Gets day icon id. * Gets day icon id.
* *
* @return the day icon id * @return the day icon id
*/ */
public String getDayIconId() { public String getDayIconId() {
return iconId + 'd'; return getIconId(DayTime.DAY);
} }
/** /**
@@ -326,35 +340,42 @@ public enum WeatherCondition {
* @return the night icon id * @return the night icon id
*/ */
public String getNightIconId() { public String getNightIconId() {
return iconId + 'n'; return getIconId(DayTime.NIGHT);
} }
/** /**
* Gets day icon url. * Gets day icon url.
* *
* @param secure Determines whether we need to use secure channel (HTTPS) for loading the image.
* @return the day icon url * @return the day icon url
*/ */
public String getDayIconUrl() { public String getDayIconUrl(boolean secure) {
return getIconUrl(getDayIconId()); return getIconUrl(getDayIconId(), secure);
} }
/** /**
* Gets night icon url. * Gets night icon url.
* *
* @param secure Determines whether we need to use secure channel (HTTPS) for loading the image.
* @return the night icon url * @return the night icon url
*/ */
public String getNightIconUrl() { public String getNightIconUrl(boolean secure) {
return getIconUrl(getNightIconId()); return getIconUrl(getNightIconId(), secure);
} }
/** /**
* Gets icon url. * Gets icon url.
* *
* @param iconId the icon id * @param iconId the icon id
* @param secure Determines whether we need to use secure channel (HTTPS) for loading the image.
* @return the icon url * @return the icon url
*/ */
public static String getIconUrl(String iconId) { public static String getIconUrl(String iconId, boolean secure) {
return "http://openweathermap.org/img/w/" + iconId + ".png"; String scheme = "http";
if (secure) {
scheme = "https";
}
return scheme + "://openweathermap.org/img/w/" + iconId + ".png";
} }
/** /**
@@ -363,8 +384,10 @@ public enum WeatherCondition {
* @param id the id * @param id the id
* @return the by id * @return the by id
*/ */
public static WeatherCondition getById(int id) { @JsonCreator
final Optional<WeatherCondition> optionalWeatherCondition = Arrays.stream(values()).filter(weatherCondition -> weatherCondition.getId() == id).findFirst(); public static WeatherCondition getById(@JsonProperty("id") int id) {
final Optional<WeatherCondition> optionalWeatherCondition =
Arrays.stream(values()).filter(weatherCondition -> weatherCondition.getId() == id).findFirst();
return optionalWeatherCondition.orElse(null); return optionalWeatherCondition.orElse(null);
} }
@@ -0,0 +1,29 @@
/*
* Copyright (c) 2021-present 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.exception;
public class ApiPayloadParseException extends RuntimeException {
public ApiPayloadParseException(String message, Throwable cause) {
super(message, cause);
}
}
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021 Alexey Zinchenko * Copyright (c) 2021-present Alexey Zinchenko
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021 Alexey Zinchenko * Copyright (c) 2021-present Alexey Zinchenko
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@@ -1,155 +0,0 @@
/*
* 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 java.util.Objects;
/**
* The AtmosphericPressure type represents atmospheric pressure value.
* Its value can only be a double in [0, +) range.
*/
public class AtmosphericPressure {
private static final String DEFAULT_UNIT = "hPa";
private double value;
private Double seaLevelValue;
private Double groundLevelValue;
/**
* Instantiates a new Pressure.
*
* @param value the value representing pressure value.
* @throws IllegalArgumentException in case if provided value isn't in allowed 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.
*
* @return pressure value.
*/
public double getValue() {
return value;
}
/**
* Sets pressure value.
*
* @param value new pressure value.
* @throws IllegalArgumentException in case if provided value isn't in allowed range.
*/
public void setValue(double value) {
if (value < 0) {
throw new IllegalArgumentException("Atmospheric pressure value must be in [0, +∞) range.");
}
this.value = value;
}
/**
* Gets sea level value.
*
* @return the sea level value.
*/
public Double getSeaLevelValue() {
return seaLevelValue;
}
/**
* Sets sea level value.
*
* @param seaLevelValue the sea level value.
* @throws IllegalArgumentException in case if provided value isn't in allowed range.
*/
public void setSeaLevelValue(double seaLevelValue) {
if (seaLevelValue < 0) {
throw new IllegalArgumentException("Atmospheric pressure value must be in [0, +∞) range.");
}
this.seaLevelValue = seaLevelValue;
}
/**
* Gets ground level value.
*
* @return the ground level value.
*/
public Double getGroundLevelValue() {
return groundLevelValue;
}
/**
* Sets ground level value.
*
* @param groundLevelValue the ground level value.
* @throws IllegalArgumentException in case if provided value isn't in allowed range.
*/
public void setGroundLevelValue(double groundLevelValue) {
if (groundLevelValue < 0) {
throw new IllegalArgumentException("Atmospheric pressure value must be in [0, +∞) range.");
}
this.groundLevelValue = groundLevelValue;
}
/**
* Returns pressure unitSystem. Constantly equals to 'hPa'.
*
* @return the pressure unitSystem.
*/
public String getUnit() {
return DEFAULT_UNIT;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
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
public int hashCode() {
return Objects.hash(value, seaLevelValue, groundLevelValue);
}
@Override
public String toString() {
return "Pressure: " + value + ' ' + getUnit();
}
}
@@ -1,106 +0,0 @@
/*
* 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 java.util.Objects;
/**
* The Clouds type represents cloudiness value percentage.
* Its value can only be an integer in [0, 100] range.
*/
public class Clouds {
private static final String DEFAULT_UNIT = "%";
private byte value;
/**
* Instantiates a new Clouds.
*
* @param value the value representing cloudiness percentage.
* @throws IllegalArgumentException in case if provided value isn't in allowed range.
*/
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.");
}
return new Clouds(value);
}
/**
* Returns cloudiness percentage value.
*
* @return cloudiness percentage.
*/
public byte getValue() {
return value;
}
/**
* Sets cloudiness percentage value.
*
* @param value new cloudiness value.
* @throws IllegalArgumentException in case if provided value isn't in allowed range.
*/
public void setValue(byte value) {
if (value < 0 || value > 100) {
throw new IllegalArgumentException("Cloudiness value must be in [0, 100] range.");
}
this.value = value;
}
/**
* Returns cloudiness unitSystem. Constantly equals to '%'.
*
* @return the cloudiness unitSystem.
*/
public String getUnit() {
return DEFAULT_UNIT;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Clouds)) return false;
Clouds clouds = (Clouds) o;
return value == clouds.value;
}
@Override
public int hashCode() {
return Objects.hash(value);
}
@Override
public String toString() {
return "Clouds: " + value + getUnit();
}
}
@@ -1,117 +0,0 @@
/*
* 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 java.util.Objects;
/**
* Represents some location by its latitude and longitude.
*/
public class Coordinate {
private double latitude;
private double longitude;
private Coordinate() {
}
/**
* Method for {@link Coordinate} creation with correctness check.
* @param latitude latitude
* @param longitude longitude
* @return coordinate object.
*/
public static Coordinate of(double latitude, double longitude) {
final Coordinate coordinate = new Coordinate();
coordinate.setLatitude(latitude);
coordinate.setLongitude(longitude);
return coordinate;
}
/**
* 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].");
}
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].");
}
this.longitude = longitude;
}
/**
* Returns latitude.
* @return latitude
*/
public double getLatitude() {
return latitude;
}
/**
* Returns longitude.
* @return longitude
*/
public double getLongitude() {
return longitude;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Coordinate)) return false;
Coordinate that = (Coordinate) o;
return Double.compare(that.latitude, latitude) == 0 &&
Double.compare(that.longitude, longitude) == 0;
}
@Override
public int hashCode() {
return Objects.hash(latitude, longitude);
}
@Override
public String toString() {
return formatAsDegree(latitude) +
", " + formatAsDegree(longitude);
}
private String formatAsDegree(double value) {
int degrees = (int) value;
double secondsDouble = value % 1 * 60;
int minutes = (int) secondsDouble;
int seconds = (int) (secondsDouble % 1 * 60);
return String.format("%s° %s %s″", degrees, minutes, seconds);
}
}
@@ -1,106 +0,0 @@
/*
* 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 java.util.Objects;
/**
* The Humidity type represents humidity value percentage.
* Its value can only be an integer in [0, 100] range.
*/
public class Humidity {
private static final String DEFAULT_UNIT = "%";
private int value;
/**
* Instantiates a new Humidity.
*
* @param value the value representing humidity percentage.
* @throws IllegalArgumentException in case if provided value isn't in allowed range.
*/
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.");
}
return new Humidity(value);
}
/**
* Returns humidity percentage value.
*
* @return humidity percentage.
*/
public int getValue() {
return value;
}
/**
* Sets humidity percentage value.
*
* @param value new humidity value.
* @throws IllegalArgumentException in case if provided value isn't in allowed range.
*/
public void setValue(int value) {
if (value < 0 || value > 100) {
throw new IllegalArgumentException("Humidity value must be in [0, 100] range.");
}
this.value = value;
}
/**
* Returns humidity unitSystem. Constantly equals to '%'.
*
* @return the humidity unitSystem.
*/
public String getUnit() {
return DEFAULT_UNIT;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Humidity)) return false;
Humidity humidity = (Humidity) o;
return value == humidity.value;
}
@Override
public int hashCode() {
return Objects.hash(value);
}
@Override
public String toString() {
return "Humidity: " + value + getUnit();
}
}
@@ -1,183 +0,0 @@
/*
* 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 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;
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.");
}
this.unit = unit;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Temperature)) return false;
Temperature that = (Temperature) o;
return Double.compare(that.value, value) == 0 &&
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, feelsLike, unit);
}
@Override
public String toString() {
final StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("Temperature: ");
stringBuilder.append(value);
stringBuilder.append(' ');
stringBuilder.append(unit);
if (maxTemperature != null) {
stringBuilder.append(", Maximum value: ");
stringBuilder.append(maxTemperature);
stringBuilder.append(' ');
stringBuilder.append(unit);
}
if (minTemperature != null) {
stringBuilder.append(", Minimum value: ");
stringBuilder.append(minTemperature);
stringBuilder.append(' ');
stringBuilder.append(unit);
}
if (feelsLike != null) {
stringBuilder.append(", Feels like: ");
stringBuilder.append(feelsLike);
stringBuilder.append(' ');
stringBuilder.append(unit);
}
return stringBuilder.toString();
}
}
@@ -1,136 +0,0 @@
/*
* 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 com.github.prominence.openweathermap.api.enums.WeatherCondition;
import java.util.Objects;
/**
* The type Weather state.
*/
public class WeatherState {
private final int id;
private final String name;
private final String description;
private String iconId;
private final WeatherCondition weatherConditionEnum;
public WeatherState(Integer id, String name, String description) {
this.id = id;
this.name = name;
this.description = description;
this.weatherConditionEnum = WeatherCondition.getById(id);
}
/**
* Gets id.
*
* @return the id
*/
public int getId() {
return id;
}
/**
* Gets name.
*
* @return the name
*/
public String getName() {
return name;
}
/**
* Gets description.
*
* @return the description
*/
public String getDescription() {
return description;
}
/**
* Gets icon id.
*
* @return the icon id
*/
public String getIconId() {
return iconId;
}
/**
* Sets icon id.
*
* @param iconId the icon id
*/
public void setIconId(String iconId) {
this.iconId = iconId;
}
/**
* Gets weather condition enum.
*
* @return the weather condition enum
*/
public WeatherCondition getWeatherConditionEnum() {
return weatherConditionEnum;
}
/**
* Gets weather icon url.
*
* @return the weather icon url
*/
public String getWeatherIconUrl() {
if (iconId != null) {
return WeatherCondition.getIconUrl(iconId);
}
if (weatherConditionEnum != null) {
// return the default one for the current weather condition
return weatherConditionEnum.getDayIconUrl();
}
return null;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
WeatherState that = (WeatherState) o;
return Objects.equals(id, that.id) &&
Objects.equals(name, that.name) &&
Objects.equals(description, that.description) &&
Objects.equals(iconId, that.iconId);
}
@Override
public int hashCode() {
return Objects.hash(id, name, description, iconId, weatherConditionEnum);
}
@Override
public String toString() {
return "Weather state: " + name + "(" + description + ").";
}
}
@@ -0,0 +1,102 @@
/*
* Copyright (c) 2021-present 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.air.pollution;
import com.github.prominence.openweathermap.api.enums.AirQualityIndex;
import java.time.OffsetDateTime;
/**
* Interface of air pollution concentration measurements.
*/
public interface AirPollutionConcentration {
/**
* The date time when the measurement happened.
*
* @return datetime
*/
OffsetDateTime getMeasurementTime();
/**
* The air quality index as an (overview).
*
* @return index
*/
AirQualityIndex getAirQualityIndex();
/**
* The concentration of CO in the air.
*
* @return CO
*/
Concentration getCarbonMonoxide();
/**
* The concentration of NO in the air.
*
* @return NO
*/
Concentration getNitrogenMonoxide();
/**
* The concentration of NO2 in the air.
*
* @return NO2
*/
Concentration getNitrogenDioxide();
/**
* The concentration of O3 in the air.
*
* @return O3
*/
Concentration getOzone();
/**
* The concentration of SO2 in the air.
*
* @return SO2
*/
Concentration getSulphurDioxide();
/**
* The concentration of pine particles matter in the air.
*
* @return fine particles
*/
Concentration getFineParticlesMatter();
/**
* The concentration of coarse particulate matter in the air.
*
* @return coarse particles
*/
Concentration getCoarseParticulateMatter();
/**
* The concentration of NH3 in the air.
*
* @return NH3
*/
Concentration getAmmonia();
}
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021 Alexey Zinchenko * Copyright (c) 2021-present Alexey Zinchenko
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@@ -20,15 +20,20 @@
* SOFTWARE. * SOFTWARE.
*/ */
package com.github.prominence.openweathermap.api.request.weather.multiple; package com.github.prominence.openweathermap.api.model.air.pollution;
import com.github.prominence.openweathermap.api.model.weather.Weather; import com.github.prominence.openweathermap.api.model.generic.location.CoordinateAware;
import com.github.prominence.openweathermap.api.request.AsyncRequestTerminator;
import java.util.List; import java.util.List;
/** /**
* The interface Multiple result current weather async request terminator. * Interface of air pollution overview.
*/ */
public interface MultipleResultCurrentWeatherAsyncRequestTerminator extends AsyncRequestTerminator<List<Weather>, String> { public interface AirPollutionDetails extends CoordinateAware {
/**
* The pollution details.
* @return pollution
*/
List<AirPollutionConcentration> getAirPollutionConcentration();
} }
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2021-present 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.air.pollution;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.github.prominence.openweathermap.api.model.generic.location.Coordinates;
import lombok.Data;
import java.util.List;
import java.util.stream.Collectors;
/**
* The type representing Air pollution data.
*/
@Data
public class AirPollutionDetailsModel implements AirPollutionDetails {
@JsonProperty("coord")
private Coordinates coordinates;
@JsonProperty("list")
private List<AirPollutionRecord> airPollutionRecords;
@JsonIgnore
@Override
public List<AirPollutionConcentration> getAirPollutionConcentration() {
return airPollutionRecords.stream()
.map(AirPollutionConcentration.class::cast)
.collect(Collectors.toList());
}
}
@@ -0,0 +1,61 @@
/*
* Copyright (c) 2021-present 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.air.pollution;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.github.prominence.openweathermap.api.deserializer.ConcentrationDeserializer;
import lombok.Data;
/**
* The type Air pollution record.
*/
@Data
public class AirPollutionMeasurements {
@JsonDeserialize(using = ConcentrationDeserializer.class)
@JsonProperty("co")
private Concentration carbonMonoxide;
@JsonDeserialize(using = ConcentrationDeserializer.class)
@JsonProperty("no")
private Concentration nitrogenMonoxide;
@JsonDeserialize(using = ConcentrationDeserializer.class)
@JsonProperty("no2")
private Concentration nitrogenDioxide;
@JsonDeserialize(using = ConcentrationDeserializer.class)
@JsonProperty("o3")
private Concentration ozone;
@JsonDeserialize(using = ConcentrationDeserializer.class)
@JsonProperty("so2")
private Concentration sulphurDioxide;
@JsonDeserialize(using = ConcentrationDeserializer.class)
@JsonProperty("pm2_5")
private Concentration fineParticlesMatter;
@JsonDeserialize(using = ConcentrationDeserializer.class)
@JsonProperty("pm10")
private Concentration coarseParticulateMatter;
@JsonDeserialize(using = ConcentrationDeserializer.class)
@JsonProperty("nh3")
private Concentration ammonia;
}
@@ -0,0 +1,105 @@
/*
* Copyright (c) 2021-present 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.air.pollution;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.github.prominence.openweathermap.api.deserializer.EpochSecondsDeserializer;
import com.github.prominence.openweathermap.api.enums.AirQualityIndex;
import lombok.Data;
import java.time.OffsetDateTime;
import java.util.Optional;
/**
* The type representing an Air pollution record.
*/
@Data
public class AirPollutionRecord implements AirPollutionConcentration {
@JsonDeserialize(using = EpochSecondsDeserializer.class)
@JsonProperty("dt")
private OffsetDateTime measurementTime;
@JsonProperty("main")
private AirQualityIndex airQualityIndex;
@JsonProperty("components")
private AirPollutionMeasurements components;
@Override
public OffsetDateTime getMeasurementTime() {
return measurementTime;
}
@Override
public AirQualityIndex getAirQualityIndex() {
return airQualityIndex;
}
@JsonIgnore
@Override
public Concentration getCarbonMonoxide() {
return Optional.ofNullable(components).map(AirPollutionMeasurements::getCarbonMonoxide).orElse(null);
}
@JsonIgnore
@Override
public Concentration getNitrogenMonoxide() {
return Optional.ofNullable(components).map(AirPollutionMeasurements::getNitrogenMonoxide).orElse(null);
}
@JsonIgnore
@Override
public Concentration getNitrogenDioxide() {
return Optional.ofNullable(components).map(AirPollutionMeasurements::getNitrogenDioxide).orElse(null);
}
@JsonIgnore
@Override
public Concentration getOzone() {
return Optional.ofNullable(components).map(AirPollutionMeasurements::getOzone).orElse(null);
}
@JsonIgnore
@Override
public Concentration getSulphurDioxide() {
return Optional.ofNullable(components).map(AirPollutionMeasurements::getSulphurDioxide).orElse(null);
}
@JsonIgnore
@Override
public Concentration getFineParticlesMatter() {
return Optional.ofNullable(components).map(AirPollutionMeasurements::getFineParticlesMatter).orElse(null);
}
@JsonIgnore
@Override
public Concentration getCoarseParticulateMatter() {
return Optional.ofNullable(components).map(AirPollutionMeasurements::getCoarseParticulateMatter).orElse(null);
}
@JsonIgnore
@Override
public Concentration getAmmonia() {
return Optional.ofNullable(components).map(AirPollutionMeasurements::getAmmonia).orElse(null);
}
}
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2021-present 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.air.pollution;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.NonNull;
import lombok.ToString;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
* Entity for air pollution concentration measurement.
*/
@EqualsAndHashCode
@ToString
@AllArgsConstructor
public class Concentration {
private static final int DECIMAL_PLACES = 10;
@NonNull
private final BigDecimal value;
/**
* Returns the measured value in micrograms/m^3.
*
* @return value
*/
@JsonIgnore
public BigDecimal asMicrogramsPerCubicMeters() {
return value.setScale(DECIMAL_PLACES, RoundingMode.HALF_EVEN);
}
}
@@ -1,84 +0,0 @@
/*
* 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<WeatherForecast> 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<WeatherForecast> getWeatherForecasts() {
return weatherForecasts;
}
/**
* Sets list of weather forecasts for different timestamps.
* @param weatherForecasts list of forecast information
*/
public void setWeatherForecasts(List<WeatherForecast> 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.";
}
}
@@ -1,235 +0,0 @@
/*
* 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 sunriseTime;
private LocalDateTime sunsetTime;
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 getSunriseTime() {
return sunriseTime;
}
/**
* Sets location sunrise time.
* @param sunriseTime sunrise time
*/
public void setSunriseTime(LocalDateTime sunriseTime) {
this.sunriseTime = sunriseTime;
}
/**
* Returns location sunset time.
* @return sunset time
*/
public LocalDateTime getSunsetTime() {
return sunsetTime;
}
/**
* Sets location sunset time.
* @param sunsetTime sunset time
*/
public void setSunsetTime(LocalDateTime sunsetTime) {
this.sunsetTime = sunsetTime;
}
/**
* 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(sunriseTime, location.sunriseTime) &&
Objects.equals(sunsetTime, location.sunsetTime) &&
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, sunriseTime, sunsetTime, 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();
}
}
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2021-present 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.fasterxml.jackson.annotation.JsonProperty;
import com.github.prominence.openweathermap.api.enums.DayTime;
import lombok.Data;
@Data
public class MetaData {
@JsonProperty("pod")
private DayTime partOfDay;
}
@@ -1,97 +0,0 @@
/*
* 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 threeHourLevel;
private Rain(double threeHourLevel) {
this.threeHourLevel = threeHourLevel;
}
/**
* Creates {@link Rain} object with correctness check.
* @param threeHourLevel 3-hour rain level value
* @return rain object.
*/
public static Rain withThreeHourLevelValue(double threeHourLevel) {
if (threeHourLevel < 0) {
throw new IllegalArgumentException("Rain level value cannot be negative.");
}
return new Rain(threeHourLevel);
}
/**
* Returns 3-hour rain level value.
* @return 3-hour rain level value
*/
public double getThreeHourLevel() {
return threeHourLevel;
}
/**
* Sets 3-hour rain level value with correctness check.
* @param threeHourLevel 3-hour rain level value
*/
public void setThreeHourLevel(double threeHourLevel) {
if (threeHourLevel < 0) {
throw new IllegalArgumentException("Rain level value cannot be negative.");
}
this.threeHourLevel = threeHourLevel;
}
/**
* 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.threeHourLevel, threeHourLevel) == 0;
}
@Override
public int hashCode() {
return Objects.hash(threeHourLevel);
}
@Override
public String toString() {
return "3-hour rain level: " +
threeHourLevel + ' ' +
getUnit();
}
}
@@ -1,97 +0,0 @@
/*
* 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 threeHourLevel;
private Snow(double threeHourLevel) {
this.threeHourLevel = threeHourLevel;
}
/**
* Creates {@link Snow} object with correctness check.
* @param threeHourLevel 3-hour snow level value
* @return snow object.
*/
public static Snow withThreeHourLevelValue(double threeHourLevel) {
if (threeHourLevel < 0) {
throw new IllegalArgumentException("Snow level value cannot be negative.");
}
return new Snow(threeHourLevel);
}
/**
* Returns 3-hour snow level value.
* @return 3-hour snow level value
*/
public double getThreeHourLevel() {
return threeHourLevel;
}
/**
* Sets 3-hour snow level value with correctness check.
* @param threeHourLevel 3-hour snow level value
*/
public void setThreeHourLevel(double threeHourLevel) {
if (threeHourLevel < 0) {
throw new IllegalArgumentException("Snow level value cannot be negative.");
}
this.threeHourLevel = threeHourLevel;
}
/**
* 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.threeHourLevel, threeHourLevel) == 0;
}
@Override
public int hashCode() {
return Objects.hash(threeHourLevel);
}
@Override
public String toString() {
return "3-hour snow level: " +
threeHourLevel + ' ' +
getUnit();
}
}
@@ -1,309 +0,0 @@
/*
* 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 LocalDateTime forecastTime;
private WeatherState weatherState;
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;
/**
* 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 weather state.
*
* @return the weather state
*/
public WeatherState getWeatherState() {
return weatherState;
}
/**
* Sets weather state.
*
* @param weatherState the weather state
*/
public void setWeatherState(WeatherState weatherState) {
this.weatherState = weatherState;
}
/**
* 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(forecastTime, that.forecastTime) &&
Objects.equals(weatherState, that.weatherState) &&
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(forecastTime, weatherState, temperature, atmosphericPressure, humidity, wind, rain, snow, clouds, forecastTimeISO, dayTime);
}
@Override
public String toString() {
final StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("Timestamp: ");
stringBuilder.append(forecastTimeISO);
if (weatherState != null) {
stringBuilder.append(", Weather: ");
stringBuilder.append(weatherState.getDescription());
}
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.getThreeHourLevel());
stringBuilder.append(' ');
stringBuilder.append(rain.getUnit());
}
if (snow != null) {
stringBuilder.append(", Snow: ");
stringBuilder.append(snow.getThreeHourLevel());
stringBuilder.append(' ');
stringBuilder.append(snow.getUnit());
}
return stringBuilder.toString();
}
}
@@ -1,145 +0,0 @@
/*
* 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 wind information.
*/
public class Wind {
private double speed;
private Double degrees;
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 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.");
}
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 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(unit, wind.unit);
}
@Override
public int hashCode() {
return Objects.hash(speed, degrees, unit);
}
@Override
public String toString() {
return "Wind speed: " + speed + " " + unit +
", degrees: " + degrees;
}
}
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021 Alexey Zinchenko * Copyright (c) 2021-present Alexey Zinchenko
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@@ -20,26 +20,29 @@
* SOFTWARE. * SOFTWARE.
*/ */
package com.github.prominence.openweathermap.api.request.weather.single; package com.github.prominence.openweathermap.api.model.forecast.climatic;
import com.github.prominence.openweathermap.api.model.weather.Weather; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.github.prominence.openweathermap.api.request.RequestTerminator; import com.github.prominence.openweathermap.api.model.generic.location.BaseLocation;
import java.util.List;
/** /**
* The current weather request terminator interface. * Root object for 30 days long daily forecasts.
*/ */
public interface SingleResultCurrentWeatherRequestTerminator extends RequestTerminator<Weather, String> { public interface ThirtyDaysDailyForecast {
/**
* XML response format.
*
* @return the XML string
*/
String asXML();
/** /**
* HTML response format. * The location where the forecast belongs to.
* * @return location
* @return the HTML string
*/ */
String asHTML(); @JsonIgnore
BaseLocation getLocation();
/**
* The forecasts.
* @return days
*/
@JsonIgnore
List<WeatherForecastDay> getWeatherForecasts();
} }
@@ -0,0 +1,62 @@
/*
* Copyright (c) 2021-present 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.climatic;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.github.prominence.openweathermap.api.model.generic.location.BaseLocation;
import com.github.prominence.openweathermap.api.model.generic.location.BaseLocationModel;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;
/**
* Represents information about forecast for different timestamps.
*/
@Data
public class ThirtyDaysDailyForecastModel implements ThirtyDaysDailyForecast {
@JsonProperty("cod")
private long cod;
@JsonProperty("message")
private BigDecimal message;
@JsonProperty("city")
private BaseLocationModel locationModel;
@JsonProperty("list")
private List<WeatherForecast> forecasts;
@Override
@JsonIgnore
public BaseLocation getLocation() {
return locationModel;
}
@Override
@JsonIgnore
public List<WeatherForecastDay> getWeatherForecasts() {
return forecasts.stream().map(WeatherForecastDay.class::cast).collect(Collectors.toList());
}
}
@@ -0,0 +1,193 @@
/*
* Copyright (c) 2021-present 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.climatic;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.github.prominence.openweathermap.api.deserializer.EpochSecondsDeserializer;
import com.github.prominence.openweathermap.api.deserializer.RequiredPercentageDeserializer;
import com.github.prominence.openweathermap.api.deserializer.WindSpeedDeserializer;
import com.github.prominence.openweathermap.api.enums.WeatherCondition;
import com.github.prominence.openweathermap.api.model.generic.clouds.CloudCoverage;
import com.github.prominence.openweathermap.api.model.generic.clouds.Clouds;
import com.github.prominence.openweathermap.api.model.generic.location.SunlightStages;
import com.github.prominence.openweathermap.api.model.generic.precipitation.Humidity;
import com.github.prominence.openweathermap.api.model.generic.precipitation.PrecipitationValues;
import com.github.prominence.openweathermap.api.model.generic.pressure.BaseAtmosphericPressure;
import com.github.prominence.openweathermap.api.model.generic.temperature.DailyTemperature;
import com.github.prominence.openweathermap.api.model.generic.temperature.TemperatureDailyBasic;
import com.github.prominence.openweathermap.api.model.generic.temperature.TemperatureDailyDetailed;
import com.github.prominence.openweathermap.api.model.generic.temperature.TemperatureValue;
import com.github.prominence.openweathermap.api.model.generic.wind.BasicWind;
import com.github.prominence.openweathermap.api.model.generic.wind.WindSpeed;
import lombok.Data;
import java.math.BigDecimal;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
/**
* Represents weather forecast information for a particular timestamp.
*/
@Data
public class WeatherForecast implements WeatherForecastDay, DailyTemperature, BaseAtmosphericPressure, BasicWind, Humidity,
PrecipitationValues, SunlightStages {
@JsonDeserialize(using = EpochSecondsDeserializer.class)
@JsonProperty("dt")
private OffsetDateTime forecastTime;
@JsonProperty("temp")
private TemperatureDailyDetailed temperature;
@JsonProperty("feels_like")
private TemperatureDailyBasic feelsLike;
@JsonProperty("weather")
private List<WeatherCondition> weatherStates = new ArrayList<>();
@JsonDeserialize(using = RequiredPercentageDeserializer.class)
@JsonProperty("humidity")
private int humidityPercentage;
@JsonProperty("pressure")
private BigDecimal pressure;
@JsonDeserialize(using = RequiredPercentageDeserializer.class)
@JsonProperty("clouds")
private int clouds;
@JsonDeserialize(using = WindSpeedDeserializer.class)
@JsonProperty("speed")
private WindSpeed speed;
@JsonProperty("deg")
private Integer directionDegrees;
@JsonProperty("rain")
private BigDecimal rain;
@JsonProperty("snow")
private BigDecimal snow;
@JsonDeserialize(using = EpochSecondsDeserializer.class)
@JsonProperty("sunrise")
private OffsetDateTime sunriseTime;
@JsonDeserialize(using = EpochSecondsDeserializer.class)
@JsonProperty("sunset")
private OffsetDateTime sunsetTime;
@Override
@JsonIgnore
public DailyTemperature getTemperature() {
return this;
}
@Override
@JsonIgnore
public BasicWind getWind() {
return this;
}
@Override
@JsonIgnore
public TemperatureValue getMorning() {
return Optional.ofNullable(temperature).map(TemperatureDailyBasic::getMorning).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getDay() {
return Optional.ofNullable(temperature).map(TemperatureDailyBasic::getDay).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getEve() {
return Optional.ofNullable(temperature).map(TemperatureDailyBasic::getEve).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getNight() {
return Optional.ofNullable(temperature).map(TemperatureDailyBasic::getNight).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getMin() {
return Optional.ofNullable(temperature).map(TemperatureDailyDetailed::getMin).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getMax() {
return Optional.ofNullable(temperature).map(TemperatureDailyDetailed::getMax).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getMorningFeelsLike() {
return Optional.ofNullable(feelsLike).map(TemperatureDailyBasic::getMorning).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getDayFeelsLike() {
return Optional.ofNullable(feelsLike).map(TemperatureDailyBasic::getDay).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getEveFeelsLike() {
return Optional.ofNullable(feelsLike).map(TemperatureDailyBasic::getEve).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getNightFeelsLike() {
return Optional.ofNullable(feelsLike).map(TemperatureDailyBasic::getNight).orElse(null);
}
@Override
@JsonIgnore
public Humidity getHumidity() {
return this;
}
@Override
@JsonIgnore
public BaseAtmosphericPressure getAtmosphericPressure() {
return this;
}
@Override
@JsonIgnore
public CloudCoverage getCloudCoverage() {
return new Clouds(this.clouds);
}
@Override
@JsonIgnore
public PrecipitationValues getPrecipitation() {
return this;
}
@Override
@JsonIgnore
public SunlightStages getSunlightStages() {
return this;
}
}
@@ -0,0 +1,104 @@
/*
* Copyright (c) 2021-present 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.climatic;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.github.prominence.openweathermap.api.enums.WeatherCondition;
import com.github.prominence.openweathermap.api.model.generic.TimeAware;
import com.github.prominence.openweathermap.api.model.generic.clouds.CloudCoverage;
import com.github.prominence.openweathermap.api.model.generic.location.SunlightStages;
import com.github.prominence.openweathermap.api.model.generic.precipitation.Humidity;
import com.github.prominence.openweathermap.api.model.generic.precipitation.PrecipitationValues;
import com.github.prominence.openweathermap.api.model.generic.pressure.BaseAtmosphericPressure;
import com.github.prominence.openweathermap.api.model.generic.temperature.DailyTemperature;
import com.github.prominence.openweathermap.api.model.generic.wind.BasicWind;
import java.util.List;
/**
* Contains forecast information for one day of the 30 day long climatic forecasts.
*/
public interface WeatherForecastDay extends TimeAware {
/**
* The temperature forecast.
*
* @return temps
*/
@JsonIgnore
DailyTemperature getTemperature();
/**
* The humidity forecast.
*
* @return humidity
*/
@JsonIgnore
Humidity getHumidity();
/**
* The atmospheric pressure forecast.
*
* @return pressure
*/
@JsonIgnore
BaseAtmosphericPressure getAtmosphericPressure();
/**
* The forecasted wind conditions.
*
* @return wind
*/
@JsonIgnore
BasicWind getWind();
/**
* The expected weather states.
*
* @return weather states
*/
List<WeatherCondition> getWeatherStates();
/**
* The forecasted cloud coverage.
*
* @return clouds
*/
@JsonIgnore
CloudCoverage getCloudCoverage();
/**
* The forecasted precipitation.
*
* @return precipitation
*/
@JsonIgnore
PrecipitationValues getPrecipitation();
/**
* Information about sunlight stages.
*
* @return sunlight
*/
@JsonIgnore
SunlightStages getSunlightStages();
}
@@ -0,0 +1,105 @@
/*
* Copyright (c) 2021-present 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.daily;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.github.prominence.openweathermap.api.enums.WeatherCondition;
import com.github.prominence.openweathermap.api.model.generic.TimeAware;
import com.github.prominence.openweathermap.api.model.generic.clouds.CloudCoverage;
import com.github.prominence.openweathermap.api.model.generic.location.SunlightStages;
import com.github.prominence.openweathermap.api.model.generic.precipitation.Humidity;
import com.github.prominence.openweathermap.api.model.generic.precipitation.PrecipitationForecast;
import com.github.prominence.openweathermap.api.model.generic.pressure.BaseAtmosphericPressure;
import com.github.prominence.openweathermap.api.model.generic.temperature.DailyTemperature;
import com.github.prominence.openweathermap.api.model.generic.wind.DetailedWindInfo;
import java.util.List;
/**
* Interface for weather forecast data used by the SixteenDaysDailyForecast.
*/
public interface DailyWeather extends TimeAware {
/**
* The temperature data,
*
* @return temp
*/
@JsonIgnore
DailyTemperature getTemperature();
/**
* The humidity.
*
* @return humidity
*/
@JsonIgnore
Humidity getHumidity();
/**
* The atmospheric pressure.
*
* @return pressure
*/
@JsonIgnore
BaseAtmosphericPressure getAtmosphericPressure();
/**
* The wind conditions.
*
* @return wind
*/
@JsonIgnore
DetailedWindInfo getWind();
/**
* The weather states.
*
* @return weather
*/
List<WeatherCondition> getWeatherStates();
/**
* The cloud coverage.
*
* @return louds
*/
@JsonIgnore
CloudCoverage getCloudCoverage();
/**
* The precipitation.
*
* @return precipitation
*/
@JsonIgnore
PrecipitationForecast getPrecipitation();
/**
* The sunlight stages.
*
* @return sunlight
*/
@JsonIgnore
SunlightStages getSunlightStages();
}
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021 Alexey Zinchenko * Copyright (c) 2021-present Alexey Zinchenko
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@@ -20,22 +20,30 @@
* SOFTWARE. * SOFTWARE.
*/ */
package com.github.prominence.openweathermap.api.request.weather.multiple; package com.github.prominence.openweathermap.api.model.forecast.daily;
import com.github.prominence.openweathermap.api.model.weather.Weather; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.github.prominence.openweathermap.api.request.AsyncRequestTerminator; import com.github.prominence.openweathermap.api.model.generic.location.DetailedLocationInfo;
import java.util.List; import java.util.List;
import java.util.concurrent.CompletableFuture;
/** /**
* The interface Multiple result current weather async request terminator. * Represents the daily forecast for the next sixteen days
*/ */
public interface MultipleResultCitiesInCircleCurrentWeatherAsyncRequestTerminator extends AsyncRequestTerminator<List<Weather>, String> { public interface SixteenDaysDailyForecast {
/** /**
* XML response format. * Information about the location.
* *
* @return the completable future * @return location
*/ */
CompletableFuture<String> asXML(); @JsonIgnore
DetailedLocationInfo getLocation();
/**
* The daily forecasts.
*
* @return forecasts
*/
@JsonIgnore
List<DailyWeather> getWeatherForecasts();
} }
@@ -0,0 +1,64 @@
/*
* Copyright (c) 2021-present 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.daily;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.github.prominence.openweathermap.api.model.generic.location.DetailedLocationInfo;
import com.github.prominence.openweathermap.api.model.generic.location.DetailedLocationModel;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;
/**
* Represents information about forecast for different timestamps.
*/
@Data
@JsonIgnoreProperties(value = {"cnt"})
public class SixteenDaysDailyForecastModel implements SixteenDaysDailyForecast {
@JsonProperty("cod")
private long cod;
@JsonProperty("message")
private BigDecimal message;
@JsonProperty("city")
private DetailedLocationModel locationModel;
@JsonProperty("list")
private List<WeatherForecast> forecasts;
@Override
@JsonIgnore
public DetailedLocationInfo getLocation() {
return locationModel;
}
@Override
@JsonIgnore
public List<DailyWeather> getWeatherForecasts() {
return forecasts.stream().map(DailyWeather.class::cast).collect(Collectors.toList());
}
}
@@ -0,0 +1,200 @@
/*
* Copyright (c) 2021-present 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.daily;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.github.prominence.openweathermap.api.deserializer.EpochSecondsDeserializer;
import com.github.prominence.openweathermap.api.deserializer.PercentageZeroToOneDeserializer;
import com.github.prominence.openweathermap.api.deserializer.RequiredPercentageDeserializer;
import com.github.prominence.openweathermap.api.deserializer.WindSpeedDeserializer;
import com.github.prominence.openweathermap.api.enums.WeatherCondition;
import com.github.prominence.openweathermap.api.model.generic.clouds.CloudCoverage;
import com.github.prominence.openweathermap.api.model.generic.clouds.Clouds;
import com.github.prominence.openweathermap.api.model.generic.location.SunlightStages;
import com.github.prominence.openweathermap.api.model.generic.precipitation.Humidity;
import com.github.prominence.openweathermap.api.model.generic.precipitation.PrecipitationForecast;
import com.github.prominence.openweathermap.api.model.generic.pressure.BaseAtmosphericPressure;
import com.github.prominence.openweathermap.api.model.generic.temperature.DailyTemperature;
import com.github.prominence.openweathermap.api.model.generic.temperature.TemperatureDailyBasic;
import com.github.prominence.openweathermap.api.model.generic.temperature.TemperatureDailyDetailed;
import com.github.prominence.openweathermap.api.model.generic.temperature.TemperatureValue;
import com.github.prominence.openweathermap.api.model.generic.wind.DetailedWindInfo;
import com.github.prominence.openweathermap.api.model.generic.wind.WindSpeed;
import lombok.Data;
import java.math.BigDecimal;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
/**
* Represents weather forecast information for a particular timestamp.
*/
@Data
public class WeatherForecast
implements DailyWeather, DailyTemperature, BaseAtmosphericPressure, DetailedWindInfo, Humidity, PrecipitationForecast, SunlightStages {
@JsonDeserialize(using = EpochSecondsDeserializer.class)
@JsonProperty("dt")
private OffsetDateTime forecastTime;
@JsonProperty("temp")
private TemperatureDailyDetailed temperature;
@JsonProperty("feels_like")
private TemperatureDailyBasic feelsLike;
@JsonProperty("weather")
private List<WeatherCondition> weatherStates = new ArrayList<>();
@JsonDeserialize(using = RequiredPercentageDeserializer.class)
@JsonProperty("humidity")
private int humidityPercentage;
@JsonProperty("pressure")
private BigDecimal pressure;
@JsonDeserialize(using = RequiredPercentageDeserializer.class)
@JsonProperty("clouds")
private int clouds;
@JsonDeserialize(using = WindSpeedDeserializer.class)
@JsonProperty("speed")
private WindSpeed speed;
@JsonProperty("deg")
private Integer directionDegrees;
@JsonDeserialize(using = WindSpeedDeserializer.class)
@JsonProperty("gust")
private WindSpeed gust;
@JsonProperty("rain")
private BigDecimal rain;
@JsonProperty("snow")
private BigDecimal snow;
@JsonDeserialize(using = PercentageZeroToOneDeserializer.class)
@JsonProperty("pop")
private Integer probabilityOfPrecipitation;
@JsonDeserialize(using = EpochSecondsDeserializer.class)
@JsonProperty("sunrise")
private OffsetDateTime sunriseTime;
@JsonDeserialize(using = EpochSecondsDeserializer.class)
@JsonProperty("sunset")
private OffsetDateTime sunsetTime;
@Override
@JsonIgnore
public DailyTemperature getTemperature() {
return this;
}
@Override
@JsonIgnore
public DetailedWindInfo getWind() {
return this;
}
@Override
@JsonIgnore
public TemperatureValue getMorning() {
return Optional.ofNullable(temperature).map(TemperatureDailyBasic::getMorning).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getDay() {
return Optional.ofNullable(temperature).map(TemperatureDailyBasic::getDay).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getEve() {
return Optional.ofNullable(temperature).map(TemperatureDailyBasic::getEve).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getNight() {
return Optional.ofNullable(temperature).map(TemperatureDailyBasic::getNight).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getMin() {
return Optional.ofNullable(temperature).map(TemperatureDailyDetailed::getMin).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getMax() {
return Optional.ofNullable(temperature).map(TemperatureDailyDetailed::getMax).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getMorningFeelsLike() {
return Optional.ofNullable(feelsLike).map(TemperatureDailyBasic::getMorning).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getDayFeelsLike() {
return Optional.ofNullable(feelsLike).map(TemperatureDailyBasic::getDay).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getEveFeelsLike() {
return Optional.ofNullable(feelsLike).map(TemperatureDailyBasic::getEve).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getNightFeelsLike() {
return Optional.ofNullable(feelsLike).map(TemperatureDailyBasic::getNight).orElse(null);
}
@Override
@JsonIgnore
public Humidity getHumidity() {
return this;
}
@Override
@JsonIgnore
public BaseAtmosphericPressure getAtmosphericPressure() {
return this;
}
@Override
@JsonIgnore
public CloudCoverage getCloudCoverage() {
return new Clouds(this.clouds);
}
@Override
@JsonIgnore
public PrecipitationForecast getPrecipitation() {
return this;
}
@Override
@JsonIgnore
public SunlightStages getSunlightStages() {
return this;
}
}
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2021-present 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.free;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.github.prominence.openweathermap.api.model.generic.location.DetailedLocationInfo;
import com.github.prominence.openweathermap.api.model.generic.location.SunlightStages;
import java.util.List;
/**
* Represents the 3 hours forecast for the next five days
*/
public interface FiveDaysThreeHoursForecast {
/**
* Information about the location.
*
* @return location
*/
@JsonIgnore
DetailedLocationInfo getLocation();
/**
* The expected sunlight stages.
*
* @return sunlight
*/
@JsonIgnore
SunlightStages getSunlightStages();
/**
* The 3-hourly forecasts.
*
* @return forecasts
*/
@JsonIgnore
List<ThreeHourWeather> getWeatherForecasts();
}
@@ -0,0 +1,69 @@
/*
* Copyright (c) 2021-present 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.free;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.github.prominence.openweathermap.api.model.generic.location.DetailedLocationInfo;
import com.github.prominence.openweathermap.api.model.generic.location.SunlightStages;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;
/**
* Represents information about forecast for different timestamps.
*/
@Data
@JsonIgnoreProperties(value = {"cnt"})
public class FiveDaysThreeHoursForecastModel implements FiveDaysThreeHoursForecast {
@JsonProperty("cod")
private long cod;
@JsonProperty("message")
private BigDecimal message;
@JsonProperty("city")
private LocationModel locationModel;
@JsonProperty("list")
private List<WeatherForecast> forecasts;
@Override
@JsonIgnore
public DetailedLocationInfo getLocation() {
return locationModel;
}
@Override
@JsonIgnore
public SunlightStages getSunlightStages() {
return locationModel;
}
@Override
@JsonIgnore
public List<ThreeHourWeather> getWeatherForecasts() {
return forecasts.stream().map(ThreeHourWeather.class::cast).collect(Collectors.toList());
}
}
@@ -0,0 +1,51 @@
/*
* Copyright (c) 2021-present 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.free;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.github.prominence.openweathermap.api.deserializer.EpochSecondsDeserializer;
import com.github.prominence.openweathermap.api.model.generic.location.DetailedLocationInfo;
import com.github.prominence.openweathermap.api.model.generic.location.DetailedLocationModel;
import com.github.prominence.openweathermap.api.model.generic.location.SunlightStages;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.time.OffsetDateTime;
/**
* Represents location information.
*/
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class LocationModel extends DetailedLocationModel implements DetailedLocationInfo, SunlightStages {
@JsonDeserialize(using = EpochSecondsDeserializer.class)
@JsonProperty("sunrise")
private OffsetDateTime sunriseTime;
@JsonDeserialize(using = EpochSecondsDeserializer.class)
@JsonProperty("sunset")
private OffsetDateTime sunsetTime;
}
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021 Alexey Zinchenko * Copyright (c) 2021-present Alexey Zinchenko
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@@ -20,15 +20,18 @@
* SOFTWARE. * SOFTWARE.
*/ */
package com.github.prominence.openweathermap.api.request; package com.github.prominence.openweathermap.api.model.forecast.free;
import java.util.concurrent.CompletableFuture; import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.math.BigDecimal;
/** /**
* The interface Async request terminator. * Represents snow/rain information.
*
* @param <T> the type parameter
* @param <S> the type parameter
*/ */
public interface AsyncRequestTerminator<T, S> extends RequestTerminator<CompletableFuture<T>, CompletableFuture<S>> { @Data
public class Precipitation {
@JsonProperty("3h")
private BigDecimal threeHourLevel;
} }
@@ -0,0 +1,111 @@
/*
* Copyright (c) 2021-present 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.free;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.github.prominence.openweathermap.api.enums.DayTime;
import com.github.prominence.openweathermap.api.enums.WeatherCondition;
import com.github.prominence.openweathermap.api.model.generic.TimeAware;
import com.github.prominence.openweathermap.api.model.generic.clouds.CloudCoverage;
import com.github.prominence.openweathermap.api.model.generic.precipitation.Humidity;
import com.github.prominence.openweathermap.api.model.generic.precipitation.PrecipitationForecast;
import com.github.prominence.openweathermap.api.model.generic.pressure.DetailedAtmosphericPressure;
import com.github.prominence.openweathermap.api.model.generic.temperature.TemperatureWithRange;
import com.github.prominence.openweathermap.api.model.generic.visibility.Visibility;
import com.github.prominence.openweathermap.api.model.generic.wind.DetailedWindInfo;
import java.util.List;
/**
* Weather forecasts for 3 hours.
*/
public interface ThreeHourWeather extends TimeAware {
/**
* The temperature forecast.
*
* @return temperature
*/
@JsonIgnore
TemperatureWithRange getTemperature();
/**
* The humidity forecast.
*
* @return humidity
*/
@JsonIgnore
Humidity getHumidity();
/**
* The atmospheric pressure forecast.
*
* @return pressure
*/
@JsonIgnore
DetailedAtmosphericPressure getAtmosphericPressure();
/**
* The wind forecast.
*
* @return wind
*/
@JsonIgnore
DetailedWindInfo getWind();
/**
* The weather states.
*
* @return states
*/
List<WeatherCondition> getWeatherStates();
/**
* The forecasted cloud cover.
*
* @return clouds
*/
CloudCoverage getClouds();
/**
* The precipitation forecast.
*
* @return precipitation
*/
@JsonIgnore
PrecipitationForecast getThreeHoursPrecipitation();
/**
* The visibility forecast.
*
* @return visibility
*/
Visibility getVisibility();
/**
* The part of day.
*
* @return part of day
*/
@JsonIgnore
DayTime getPartOfDay();
}
@@ -0,0 +1,141 @@
/*
* Copyright (c) 2021-present 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.free;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.github.prominence.openweathermap.api.deserializer.EpochSecondsDeserializer;
import com.github.prominence.openweathermap.api.deserializer.PercentageZeroToOneDeserializer;
import com.github.prominence.openweathermap.api.deserializer.VisibilityDeserializer;
import com.github.prominence.openweathermap.api.enums.DayTime;
import com.github.prominence.openweathermap.api.enums.WeatherCondition;
import com.github.prominence.openweathermap.api.model.forecast.MetaData;
import com.github.prominence.openweathermap.api.model.generic.MainMetrics;
import com.github.prominence.openweathermap.api.model.generic.TimeAware;
import com.github.prominence.openweathermap.api.model.generic.clouds.CloudCoverage;
import com.github.prominence.openweathermap.api.model.generic.clouds.Clouds;
import com.github.prominence.openweathermap.api.model.generic.precipitation.Humidity;
import com.github.prominence.openweathermap.api.model.generic.precipitation.PrecipitationForecast;
import com.github.prominence.openweathermap.api.model.generic.pressure.DetailedAtmosphericPressure;
import com.github.prominence.openweathermap.api.model.generic.temperature.TemperatureWithRange;
import com.github.prominence.openweathermap.api.model.generic.visibility.Visibility;
import com.github.prominence.openweathermap.api.model.generic.wind.DetailedWindInfo;
import com.github.prominence.openweathermap.api.model.generic.wind.WindModel;
import lombok.Data;
import java.math.BigDecimal;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
/**
* Represents weather forecast information for a particular timestamp.
*/
@Data
@JsonIgnoreProperties(value = {"dt_txt"})
public class WeatherForecast implements TimeAware, ThreeHourWeather, PrecipitationForecast {
@JsonDeserialize(using = EpochSecondsDeserializer.class)
@JsonProperty("dt")
private OffsetDateTime forecastTime;
@JsonProperty("main")
private MainMetrics mainMetrics;
@JsonProperty("weather")
private List<WeatherCondition> weatherStates = new ArrayList<>();
@JsonProperty("clouds")
private Clouds clouds;
@JsonProperty("wind")
private WindModel windModel;
@JsonProperty("rain")
private Precipitation rainModel;
@JsonProperty("snow")
private Precipitation snowModel;
@JsonDeserialize(using = VisibilityDeserializer.class)
@JsonProperty("visibility")
private Visibility visibility;
@JsonDeserialize(using = PercentageZeroToOneDeserializer.class)
@JsonProperty("pop")
private Integer probabilityOfPrecipitation;
@JsonProperty("sys")
private MetaData sysMeta;
@Override
@JsonIgnore
public TemperatureWithRange getTemperature() {
return mainMetrics;
}
@Override
@JsonIgnore
public Humidity getHumidity() {
return mainMetrics;
}
@Override
@JsonIgnore
public DetailedAtmosphericPressure getAtmosphericPressure() {
return mainMetrics;
}
@Override
@JsonIgnore
public DetailedWindInfo getWind() {
return windModel;
}
@Override
@JsonIgnore
public DayTime getPartOfDay() {
return Optional.ofNullable(sysMeta).map(MetaData::getPartOfDay).orElse(null);
}
@Override
@JsonIgnore
public PrecipitationForecast getThreeHoursPrecipitation() {
return this;
}
@Override
@JsonIgnore
public BigDecimal getRain() {
return Optional.ofNullable(rainModel)
.map(Precipitation::getThreeHourLevel)
.orElse(null);
}
@Override
@JsonIgnore
public BigDecimal getSnow() {
return Optional.ofNullable(snowModel)
.map(Precipitation::getThreeHourLevel)
.orElse(null);
}
@Override
public CloudCoverage getClouds() {
return clouds;
}
}
@@ -0,0 +1,59 @@
/*
* Copyright (c) 2021-present 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.hourly;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.github.prominence.openweathermap.api.model.generic.location.BaseLocation;
import com.github.prominence.openweathermap.api.model.generic.location.SunlightStages;
import java.util.List;
/**
* Represents the hourly forecast for the next four days
*/
public interface FourDaysHourlyForecast {
/**
* Information about the location.
*
* @return location
*/
@JsonIgnore
BaseLocation getLocation();
/**
* The expected sunlight stages.
*
* @return sunlight
*/
@JsonIgnore
SunlightStages getSunlightStages();
/**
* The hourly forecasts.
*
* @return hours
*/
@JsonIgnore
List<HourlyWeather> getWeatherForecasts();
}
@@ -0,0 +1,70 @@
/*
* Copyright (c) 2021-present 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.hourly;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.github.prominence.openweathermap.api.model.generic.location.BaseLocation;
import com.github.prominence.openweathermap.api.model.generic.location.SunlightStages;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;
/**
* Represents information about forecast for different timestamps.
*/
@Data
@JsonIgnoreProperties(value = {"cnt"})
public class FourDaysHourlyForecastModel implements FourDaysHourlyForecast {
@JsonProperty("cod")
private long cod;
@JsonProperty("message")
private BigDecimal message;
@JsonProperty("list")
private List<HourlyWeatherForecast> forecasts;
@JsonProperty("city")
private LocationModel locationModel;
@Override
@JsonIgnore
public BaseLocation getLocation() {
return locationModel;
}
@Override
@JsonIgnore
public SunlightStages getSunlightStages() {
return locationModel;
}
@Override
@JsonIgnore
public List<HourlyWeather> getWeatherForecasts() {
return forecasts.stream().map(HourlyWeather.class::cast).collect(Collectors.toList());
}
}
@@ -0,0 +1,110 @@
/*
* Copyright (c) 2021-present 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.hourly;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.github.prominence.openweathermap.api.enums.DayTime;
import com.github.prominence.openweathermap.api.enums.WeatherCondition;
import com.github.prominence.openweathermap.api.model.generic.TimeAware;
import com.github.prominence.openweathermap.api.model.generic.clouds.CloudCoverage;
import com.github.prominence.openweathermap.api.model.generic.precipitation.Humidity;
import com.github.prominence.openweathermap.api.model.generic.precipitation.PrecipitationForecast;
import com.github.prominence.openweathermap.api.model.generic.pressure.DetailedAtmosphericPressure;
import com.github.prominence.openweathermap.api.model.generic.temperature.TemperatureWithRange;
import com.github.prominence.openweathermap.api.model.generic.visibility.Visibility;
import com.github.prominence.openweathermap.api.model.generic.wind.DetailedWindInfo;
import java.util.List;
/**
* Forecast details for a single hour.
*/
public interface HourlyWeather extends TimeAware {
/**
* The temperature forecast.
*
* @return temperature
*/
@JsonIgnore
TemperatureWithRange getTemperature();
/**
* The humidity forecast.
*
* @return humidity
*/
@JsonIgnore
Humidity getHumidity();
/**
* The atmospheric pressure forecast.
*
* @return pressure
*/
@JsonIgnore
DetailedAtmosphericPressure getAtmosphericPressure();
/**
* The wind forecast.
*
* @return wind
*/
DetailedWindInfo getWind();
/**
* The weather states.
*
* @return states
*/
List<WeatherCondition> getWeatherStates();
/**
* The forecasted cloud cover.
*
* @return clouds
*/
CloudCoverage getClouds();
/**
* The precipitation forecast.
*
* @return precipitation
*/
@JsonIgnore
PrecipitationForecast getHourlyPrecipitation();
/**
* The visibility forecast.
*
* @return visibility
*/
Visibility getVisibility();
/**
* The part of day.
*
* @return part of day
*/
@JsonIgnore
DayTime getPartOfDay();
}
@@ -0,0 +1,138 @@
/*
* Copyright (c) 2021-present 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.hourly;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.github.prominence.openweathermap.api.deserializer.EpochSecondsDeserializer;
import com.github.prominence.openweathermap.api.deserializer.PercentageZeroToOneDeserializer;
import com.github.prominence.openweathermap.api.deserializer.VisibilityDeserializer;
import com.github.prominence.openweathermap.api.enums.DayTime;
import com.github.prominence.openweathermap.api.enums.WeatherCondition;
import com.github.prominence.openweathermap.api.model.forecast.MetaData;
import com.github.prominence.openweathermap.api.model.generic.MainMetrics;
import com.github.prominence.openweathermap.api.model.generic.TimeAware;
import com.github.prominence.openweathermap.api.model.generic.clouds.CloudCoverage;
import com.github.prominence.openweathermap.api.model.generic.clouds.Clouds;
import com.github.prominence.openweathermap.api.model.generic.precipitation.BasePrecipitation;
import com.github.prominence.openweathermap.api.model.generic.precipitation.Humidity;
import com.github.prominence.openweathermap.api.model.generic.precipitation.PrecipitationForecast;
import com.github.prominence.openweathermap.api.model.generic.pressure.DetailedAtmosphericPressure;
import com.github.prominence.openweathermap.api.model.generic.temperature.TemperatureWithRange;
import com.github.prominence.openweathermap.api.model.generic.visibility.Visibility;
import com.github.prominence.openweathermap.api.model.generic.wind.DetailedWindInfo;
import com.github.prominence.openweathermap.api.model.generic.wind.WindModel;
import lombok.Data;
import java.math.BigDecimal;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
/**
* Represents weather forecast information for a particular timestamp.
*/
@Data
@JsonIgnoreProperties(value = {"dt_txt"})
public class HourlyWeatherForecast implements TimeAware, HourlyWeather, PrecipitationForecast {
@JsonDeserialize(using = EpochSecondsDeserializer.class)
@JsonProperty("dt")
private OffsetDateTime forecastTime;
@JsonProperty("main")
private MainMetrics mainMetrics;
@JsonProperty("weather")
private List<WeatherCondition> weatherStates = new ArrayList<>();
@JsonProperty("clouds")
private Clouds clouds;
@JsonProperty("wind")
private WindModel windModel;
@JsonProperty("rain")
private BasePrecipitation rainModel;
@JsonProperty("snow")
private BasePrecipitation snowModel;
@JsonDeserialize(using = VisibilityDeserializer.class)
@JsonProperty("visibility")
private Visibility visibility;
@JsonDeserialize(using = PercentageZeroToOneDeserializer.class)
@JsonProperty("pop")
private Integer probabilityOfPrecipitation;
@JsonProperty("sys")
private MetaData sysMeta;
@Override
@JsonIgnore
public TemperatureWithRange getTemperature() {
return mainMetrics;
}
@Override
@JsonIgnore
public Humidity getHumidity() {
return mainMetrics;
}
@Override
@JsonIgnore
public DetailedAtmosphericPressure getAtmosphericPressure() {
return mainMetrics;
}
@Override
@JsonIgnore
public DetailedWindInfo getWind() {
return windModel;
}
@Override
@JsonIgnore
public PrecipitationForecast getHourlyPrecipitation() {
return this;
}
@Override
@JsonIgnore
public BigDecimal getRain() {
return Optional.ofNullable(getRainModel()).map(BasePrecipitation::getOneHourLevel).orElse(null);
}
@Override
@JsonIgnore
public BigDecimal getSnow() {
return Optional.ofNullable(getSnowModel()).map(BasePrecipitation::getOneHourLevel).orElse(null);
}
@Override
public CloudCoverage getClouds() {
return clouds;
}
@Override
@JsonIgnore
public DayTime getPartOfDay() {
return Optional.ofNullable(sysMeta).map(MetaData::getPartOfDay).orElse(null);
}
}
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2021-present 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.hourly;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.github.prominence.openweathermap.api.deserializer.EpochSecondsDeserializer;
import com.github.prominence.openweathermap.api.model.generic.location.BaseLocation;
import com.github.prominence.openweathermap.api.model.generic.location.BaseLocationModel;
import com.github.prominence.openweathermap.api.model.generic.location.SunlightStages;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.time.OffsetDateTime;
/**
* Represents location information.
*/
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class LocationModel extends BaseLocationModel implements BaseLocation, SunlightStages {
@JsonDeserialize(using = EpochSecondsDeserializer.class)
@JsonProperty("sunrise")
private OffsetDateTime sunriseTime;
@JsonDeserialize(using = EpochSecondsDeserializer.class)
@JsonProperty("sunset")
private OffsetDateTime sunsetTime;
}
@@ -0,0 +1,65 @@
/*
* Copyright (c) 2021-present 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.generic;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.github.prominence.openweathermap.api.deserializer.RequiredPercentageDeserializer;
import com.github.prominence.openweathermap.api.deserializer.TemperatureValueDeserializer;
import com.github.prominence.openweathermap.api.model.generic.precipitation.Humidity;
import com.github.prominence.openweathermap.api.model.generic.pressure.DetailedAtmosphericPressure;
import com.github.prominence.openweathermap.api.model.generic.temperature.TemperatureValue;
import com.github.prominence.openweathermap.api.model.generic.temperature.TemperatureWithRange;
import lombok.Data;
import java.math.BigDecimal;
/**
* Contains Temperature and AtmosphericPressure.
*/
@Data
@JsonIgnoreProperties(value = {"temp_kf"})
public class MainMetrics implements TemperatureWithRange, Humidity, DetailedAtmosphericPressure {
@JsonDeserialize(using = TemperatureValueDeserializer.class)
@JsonProperty("temp")
private TemperatureValue temperature;
@JsonDeserialize(using = TemperatureValueDeserializer.class)
@JsonProperty("temp_max")
private TemperatureValue max;
@JsonDeserialize(using = TemperatureValueDeserializer.class)
@JsonProperty("temp_min")
private TemperatureValue min;
@JsonDeserialize(using = TemperatureValueDeserializer.class)
@JsonProperty("feels_like")
private TemperatureValue feelsLike;
@JsonDeserialize(using = RequiredPercentageDeserializer.class)
@JsonProperty("humidity")
private int humidityPercentage;
@JsonProperty("pressure")
private BigDecimal pressure;
@JsonProperty("sea_level")
private BigDecimal seaLevel;
@JsonProperty("grnd_level")
private BigDecimal groundLevel;
}
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2021-present 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.generic;
import java.time.OffsetDateTime;
/**
* Indicates that the implementation keeps track of the forecast time.
*/
public interface TimeAware {
/**
* Returns the time when the data was calculated.
*
* @return timestamp
*/
OffsetDateTime getForecastTime();
}
@@ -0,0 +1,28 @@
/*
* Copyright (c) 2021-present 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.generic.clouds;
public interface CloudCoverage {
Integer getCoveragePercentage();
}
@@ -0,0 +1,41 @@
/*
* Copyright (c) 2021-present 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.generic.clouds;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* The Clouds type represents cloudiness value percentage.
* Its value can only be an integer in [0, 100] range.
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Clouds implements CloudCoverage {
@JsonProperty("all")
private Integer coveragePercentage;
}
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021 Alexey Zinchenko * Copyright (c) 2021-present Alexey Zinchenko
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@@ -20,31 +20,41 @@
* SOFTWARE. * SOFTWARE.
*/ */
package com.github.prominence.openweathermap.api.request; package com.github.prominence.openweathermap.api.model.generic.location;
import com.github.prominence.openweathermap.api.enums.Language; import java.time.ZoneOffset;
import com.github.prominence.openweathermap.api.enums.UnitSystem;
/** /**
* The interface Request customizer. * Contains basic location information.
*
* @param <T> the type parameter
*/ */
public interface RequestCustomizer<T extends RequestCustomizer<?>> { public interface BaseLocation extends CoordinateAware {
/** /**
* Customize language. * The time zone of the location.
* *
* @param language the language * @return time zone
* @return the request customizer
*/ */
T language(Language language); ZoneOffset getTimeZone();
/** /**
* Customize unit system. * The Id of the city.
* *
* @param unitSystem the unit system * @return city Id
* @return the request customizer
*/ */
T unitSystem(UnitSystem unitSystem); long getCityId();
/**
* The name of the city.
*
* @return city name
*/
String getCityName();
/**
* The country code of the location.
*
* @return country code
*/
String getCountryCode();
} }

Some files were not shown because too many files have changed in this diff Show More