Compare commits

..

60 Commits

Author SHA1 Message Date
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
Prominence f2c672b864 Added doc link. 2021-04-15 00:04:06 +03:00
Alexey Zinchenko e594ffb7ad 2.1.1 version implementation. 2021-04-15 00:00:48 +03:00
Alexey Zinchenko 4cfa8ab843 2.1.0 version implementation. 2021-04-12 02:00:51 +03:00
Alexey Zinchenko 196f9ec289 Update README.md 2021-03-28 16:13:58 +03:00
Prominence 4998663298 Releasing 2.0.1 version. 2021-03-26 23:36:06 +03:00
Alexey Zinchenko f5d202aee3 Version 2.0.1 (#13)
* Added method for weather icon id retrieval. Small internal changes in models.

* Changed temperature unit signs.
2021-03-26 23:32:57 +03:00
302 changed files with 27220 additions and 5040 deletions
+13
View File
@@ -0,0 +1,13 @@
container:
image: gradle:jdk17
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:
push:
branches: [ master ]
branches: [ dev ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ master ]
branches: [ dev ]
schedule:
- 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
.idea/
target/
.idea
.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)
+60 -11
View File
@@ -1,24 +1,33 @@
# 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.
### Implemented features:
Free:
* Current weather data
* 5 day / 3-hour forecast
* 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:
Free:
* One Call API
* Air pollution
* Geocoding API
* Weather Stations
* Weather Triggers
Paid:
* Daily Forecast 16 days
* Hourly Forecast 4 days
* probably others...
* Bulk Downloading
* Global Weather Alerts / Push notifications
### Maven coordinates:
@@ -26,14 +35,46 @@ Paid:
<dependency>
<groupId>com.github.prominence</groupId>
<artifactId>openweathermap-api</artifactId>
<version>2.0.0</version>
<version>3.0.0-SNAPSHOT</version>
</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:
```groovy
compile('com.github.prominence:openweathermap-api:2.0.0')
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
@@ -41,14 +82,22 @@ compile('com.github.prominence:openweathermap-api:2.0.0')
* [OpenWeatherMap Java API - 1.1](docs/Release_1.1.md)
* [OpenWeatherMap Java API - 1.2](docs/Release_1.2.md)
* [OpenWeatherMap Java API - 2.0.0](docs/Release_2.0.0.md)
* [OpenWeatherMap Java API - 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.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)
### License
MIT
[ci-shield]: https://travis-ci.org/Prominence/openweathermap-java-api.svg?branch=dev
[ci-link]: https://travis-ci.org/Prominence/openweathermap-java-api
[ci-shield]: https://api.cirrus-ci.com/github/Prominence/openweathermap-java-api.svg?branch=dev
[ci-link]: https://api.cirrus-ci.com/github/Prominence/openweathermap-java-api
[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
[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
+122
View File
@@ -0,0 +1,122 @@
plugins {
id 'java-library'
id 'maven-publish'
id 'signing'
id 'jacoco'
}
repositories {
mavenLocal()
maven {
url = uri('https://repo.maven.apache.org/maven2/')
}
}
dependencies {
implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.2.2'
implementation 'org.slf4j:slf4j-api:1.7.36'
testImplementation 'org.junit.platform:junit-platform-runner:1.8.2'
testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
annotationProcessor 'com.github.bsideup.jabel:jabel-javac-plugin:0.4.2'
}
group = 'com.github.prominence'
version = '3.0.0-SNAPSHOT'
description = 'Java OpenWeatherMap API'
configure([tasks.compileJava]) {
sourceCompatibility = 17 // for the IDE support
options.release = 8
javaCompiler = javaToolchains.compilerFor {
languageVersion = JavaLanguageVersion.of(17)
}
}
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:
```groovy
compile('com.github.prominence:openweathermap-api:1.0')
implementation 'com.github.prominence:openweathermap-api:1.0'
```
### How to use:
+1 -1
View File
@@ -18,7 +18,7 @@
### Gradle coordinates:
```groovy
compile('com.github.prominence:openweathermap-api:1.1')
implementation 'com.github.prominence:openweathermap-api:1.1'
```
### How to use:
+1 -1
View File
@@ -18,7 +18,7 @@
### Gradle coordinates:
```groovy
compile('com.github.prominence:openweathermap-api:1.2')
implementation 'com.github.prominence:openweathermap-api:1.2'
```
### How to use:
+2 -2
View File
@@ -15,7 +15,7 @@
### Gradle coordinates:
```groovy
compile('com.github.prominence:openweathermap-api:2.0.0')
implementation 'com.github.prominence:openweathermap-api:2.0.0'
```
### How to use:
@@ -79,7 +79,7 @@ final Weather weather = openWeatherClient
final List<Weather> weatherList = openWeatherClient
.currentWeather()
.multiple()
.byCitiesInCycle(Coordinate.withValues(55.5, 37.5))
.byCitiesInCycle(Coordinate.of(55.5, 37.5))
.language(Language.GERMAN)
.unitSystem(UnitSystem.IMPERIAL)
.retrieve()
+253
View File
@@ -0,0 +1,253 @@
### Implemented features:
* Current weather data
* 5 day / 3-hour forecast
### Maven coordinates:
```xml
<dependency>
<groupId>com.github.prominence</groupId>
<artifactId>openweathermap-api</artifactId>
<version>2.0.1</version>
</dependency>
```
### Gradle coordinates:
```groovy
implementation 'com.github.prominence:openweathermap-api:2.0.1'
```
### How to use:
Firstly, you need to create the instance of `OpenWeatherMapClient` class:
```java
OpenWeatherMapClient openWeatherClient = new OpenWeatherMapClient(API_TOKEN);
```
where `API_TOKEN` is your token([you can get it here](https://home.openweathermap.org/api_keys)) as `String`.
Currently, available APIs are:
* `currentWeather()`
* `forecast5Day3HourStep()`
Default(more or less) customization points:
```java
...
// response language
.language(Language.RUSSIAN)
...
// response units of measure
.unitSystem(UnitSystem.IMPERIAL)
...
```
Available output forms:
* `asJava()`
* `asJSON()`
Additional output forms, available for several APIs:
* `asXML()`
* `asHTML()`
_All response forms can be in **sync** and **async** variants._
#### Current weather data
Examples:
```java
final String weatherJson = openWeatherClient
.currentWeather()
.single()
.byCityName("Minsk")
.language(Language.RUSSIAN)
.unitSystem(UnitSystem.IMPERIAL)
.retrieve()
.asJSON();
```
```java
final Weather weather = openWeatherClient
.currentWeather()
.single()
.byCityName("Minsk")
.language(Language.RUSSIAN)
.unitSystem(UnitSystem.METRIC)
.retrieve()
.asJava();
```
```java
final List<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 |
|---------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `getState()` | Returns short weather description. Example: `Clear`. |
| `getDescription()` | Returns weather description. Example: `clear sky`. |
| `getWeatherIconUrl()` | Returns a link to weather icon hosted on https://openweathermap.org website. |
| `getCalculatedOn()` | Returns `LocalDateTime` object with data calculation time. |
| `getTemperature()` | Returns `Temperature` instance that contains information about temperature. Available fields: `value`, `maxTemperature`, `minTemperature`, `feelsLike` and `unit`. |
| `getAtmosphericPressure()`| Returns `AtmosphericPressure` instance that contains information about atmospheric pressure. Available fields: `value`, `seaLevelValue`, `groundLevelValue` and `unit`. |
| `getHumidity()` | Returns `Humidity` instance that contains humidity percentage information. |
| `getWind()` | Returns `Wind` instance that contains wind information: `speed`, `degrees`, `gust` and `unit`. |
| `getRain()` | Returns `Rain` instance that contains information about rain volume for the last one hour and/or the last 3 hours. Can be absent in case of no data. |
| `getSnow()` | Returns `Snow` instance that contains information about snow volume for the last one hour and/or the last 3 hours. Can be absent in case of no data. |
| `getClouds()` | Returns `Clouds` instance that contains information about cloudiness percentage. |
| `getLocation()` | Returns `Location` object. Available fields: `id`, `name`, `countryCode`, `sunrise` and `sunset` time, `zoneOffset` and `coordinate`. |
| `toString()` | Returns informative string for the whole available weather information. |
`toString()` output example:
```
Location: Minsk(BY), Weather: clear sky, -4.22 ℃, 1020.0 hPa, Clouds: 0%
```
#### 5 day / 3-hour forecast
Examples:
```java
final Forecast forecast = openWeatherClient
.forecast5Day3HourStep()
.byCityName("Minsk")
.language(Language.ENGLISH)
.unitSystem(UnitSystem.METRIC)
.count(15)
.retrieve()
.asJava();
```
```java
final String forecastJson = getClient()
.forecast5Day3HourStep()
.byCityName("New York", "NY", "US")
.language(Language.SPANISH)
.unitSystem(UnitSystem.IMPERIAL)
.count(15)
.retrieve()
.asJSON();
```
```java
CompletableFuture<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.request.forecast.free.Forecast`'s useful public methods(setters are not listed):
| Method | Description |
|-------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|
| `getLocation()` | Returns `Location` object. Available fields: `id`, `name`, `countryCode`, `sunrise` and `sunset` time, `zoneOffset`, `coordinate` and `population`. |
| `getWeatherForecasts()` | Returns list of `WeatherForecast` objects with forecast information. |
| `toString()` | Returns informative string for the whole available forecast information. |
`toString()` output example:
```
A forecast for Minsk with 15 timestamps.
```
`com.github.prominence.openweathermap.api.model.forecast.WeatherForecast`'s useful public methods(setters are not listed):
| Method | Description |
|-------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `getState()` | Returns short weather description. Example: `Clear`. |
| `getDescription()` | Returns weather description. Example: `clear sky`. |
| `getWeatherIconUrl()` | Returns a link to weather icon hosted on https://openweathermap.org website. |
| `getForecastTime()` | Returns `LocalDateTime` object with weather forecast time. |
| `getTemperature()` | Returns `Temperature` instance that contains information about temperature. Available fields: `value`, `maxTemperature`, `minTemperature`, `feelsLike` and `unit`. |
| `getAtmosphericPressure()` | Returns `AtmosphericPressure` instance that contains information about atmospheric pressure. Available fields: `value`, `seaLevelValue`, `groundLevelValue` and `unit`. |
| `getHumidity()` | Returns `Humidity` instance that contains humidity percentage information. |
| `getWind()` | Returns `Wind` instance that contains wind information: `speed`, `degrees` and `unit`. |
| `getRain()` | Returns `Rain` instance that contains information about rain volume for the last 3 hours. Can be absent in case of no data. |
| `getSnow()` | Returns `Snow` instance that contains information about snow volume for the last 3 hours. Can be absent in case of no data. |
| `getClouds()` | Returns `Clouds` instance that contains information about cloudiness percentage. |
| `getForecastTimeISO()` | Returns String with time of data forecasted, ISO, UTC. |
| `getDayTime()` | Returns enumerations representing the part of day(day, night). |
| `toString()` | Returns informative string for the forecast of particular timestamp. |
### Constants and options
#### Language
| Constant | Description |
|-----------------------------------|-------------------------------|
| Language.ARABIC | Arabic language. |
| Language.BULGARIAN | Bulgarian language. |
| Language.CATALAN | Catalan language. |
| Language.CZECH | Czech language. |
| Language.GERMAN | German language. |
| Language.GREEK | Greek language. |
| Language.ENGLISH | English language. |
| Language.PERSIAN | Persian (Farsi) language. |
| Language.FINNISH | Finnish language. |
| Language.FRENCH | French language. |
| Language.GALICIAN | Galician language. |
| Language.CROATIAN | Croatian language. |
| Language.HUNGARIAN | Hungarian language. |
| Language.ITALIAN | Italian language. |
| Language.JAPANESE | Japanese language. |
| Language.KOREAN | Korean language. |
| Language.LATVIAN | Latvian language. |
| Language.LITHUANIAN | Lithuanian language. |
| Language.MACEDONIAN | Macedonian language. |
| Language.DUTCH | Dutch language. |
| Language.POLISH | Polish language. |
| Language.PORTUGUESE | Portuguese language. |
| Language.ROMANIAN | Romanian language. |
| Language.RUSSIAN | Russian language. |
| Language.SWEDISH | Swedish language. |
| Language.SLOVAK | Slovak language. |
| Language.SLOVENIAN | Slovenian language. |
| Language.SPANISH | Spanish language. |
| Language.TURKISH | Turkish language. |
| Language.UKRANIAN | Ukrainian language. |
| Language.VIETNAMESE | Vietnamese language. |
| Language.CHINESE_SIMPLIFIED | Chinese Simplified language. |
| Language.CHINESE_TRADITIONAL | Chinese Traditional language. |
#### Unit
| Constant | Description |
|----------------------|------------------------------------------------|
| Unit.METRIC_SYSTEM | Celsius, meter/sec, hPa, mm(rain, snow). |
| Unit.IMPERIAL_SYSTEM | Fahrenheit, miles/hour, hPa, mm(rain, snow). |
| Unit.STANDARD_SYSTEM | Kelvin, meter/sec, hPa, mm(rain, snow). |
### Dependencies
* com.fasterxml.jackson.core:jackson-databind:2.12.2
* org.slf4j:slf4j-api:1.7.30 (*compile*)
* junit:junit:4.13.1 (*test*)
+484
View File
@@ -0,0 +1,484 @@
### Implemented features:
* Current weather data
* 5 day / 3-hour forecast
* One Call API
### Maven coordinates:
```xml
<dependency>
<groupId>com.github.prominence</groupId>
<artifactId>openweathermap-api</artifactId>
<version>2.1.0</version>
</dependency>
```
### Gradle coordinates:
```groovy
implementation 'com.github.prominence:openweathermap-api:2.1.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()`
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). |
| `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). |
| `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`. |
### 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*)
+486
View File
@@ -0,0 +1,486 @@
### Implemented features:
* Current weather data
* 5 day / 3-hour forecast
* One Call API
### Maven coordinates:
```xml
<dependency>
<groupId>com.github.prominence</groupId>
<artifactId>openweathermap-api</artifactId>
<version>2.1.1</version>
</dependency>
```
### Gradle coordinates:
```groovy
implementation 'com.github.prominence:openweathermap-api:2.1.1'
```
### 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()`
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`. |
### 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*)
+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*)
+355 -19
View File
@@ -1,6 +1,17 @@
### Implemented features:
* Current weather data
* Hourly forecast
* 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:
@@ -8,14 +19,46 @@
<dependency>
<groupId>com.github.prominence</groupId>
<artifactId>openweathermap-api</artifactId>
<version>2.0.0-SNAPSHOT</version>
<version>3.0.0-SNAPSHOT</version>
</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:
```groovy
compile('com.github.prominence:openweathermap-api:2.0.0-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:
@@ -29,6 +72,15 @@ where `API_TOKEN` is your token([you can get it here](https://home.openweatherma
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
@@ -79,7 +131,7 @@ final Weather weather = openWeatherClient
final List<Weather> weatherList = openWeatherClient
.currentWeather()
.multiple()
.byCitiesInCycle(Coordinate.withValues(55.5, 37.5))
.byCitiesInCycle(Coordinate.of(55.5, 37.5))
.language(Language.GERMAN)
.unitSystem(UnitSystem.IMPERIAL)
.retrieve()
@@ -103,10 +155,8 @@ You are able to set preferable options(via chain methods) and execute appropriat
| Method | Description |
|---------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `getState()` | Returns short weather description. Example: `Clear`. |
| `getDescription()` | Returns weather description. Example: `clear sky`. |
| `getWeatherIconUrl()` | Returns a link to weather icon hosted on https://openweathermap.org website. |
| `getCalculatedOn()` | Returns `LocalDateTime` object with data calculation time. |
| `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. |
@@ -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. |
| `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`. |
| `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()` output example:
@@ -169,11 +219,11 @@ final String forecastXml = getClient()
You are able to set preferable options(via chain methods) and execute appropriate request.
`com.github.prominence.openweathermap.api.request.forecast.free.Forecast`'s useful public methods(setters are not listed):
`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`. |
| `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. |
| `toString()` | Returns informative string for the whole available forecast information. |
@@ -182,14 +232,12 @@ You are able to set preferable options(via chain methods) and execute appropriat
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 |
|-------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `getState()` | Returns short weather description. Example: `Clear`. |
| `getDescription()` | Returns weather description. Example: `clear sky`. |
| `getWeatherIconUrl()` | Returns a link to weather icon hosted on https://openweathermap.org website. |
| `getForecastTime()` | Returns `LocalDateTime` object with weather forecast time. |
| `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. |
@@ -201,44 +249,331 @@ A forecast for Minsk with 15 timestamps.
| `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 |
|-------------------------------|--------------------------------------------------------------------------------|
| `getCoordinates()` | 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 |
|-------------------------------|-------------------------------------------------------------------------------|
| `getCoordinates()` | 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 |
|-------------------------------|---------------------------------------------------------------------------|
| `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
#### 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.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 |
@@ -248,6 +583,7 @@ A forecast for Minsk with 15 timestamps.
| Unit.STANDARD_SYSTEM | Kelvin, meter/sec, hPa, mm(rain, snow). |
### Dependencies
* com.fasterxml.jackson.core:jackson-databind:2.12.2
* org.slf4j:slf4j-api:1.7.30 (*compile*)
* junit:junit:4.13.1 (*test*)
* 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*)
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
-176
View File
@@ -1,176 +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.0.0</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>http://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>
</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>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
+1
View File
@@ -0,0 +1 @@
rootProject.name = 'openweathermap-api'
@@ -23,10 +23,20 @@
package com.github.prominence.openweathermap.api;
import com.github.prominence.openweathermap.api.annotation.SubscriptionAvailability;
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.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.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.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.CurrentWeatherRequesterImpl;
import static com.github.prominence.openweathermap.api.enums.SubscriptionPlan.*;
@@ -36,22 +46,83 @@ import static com.github.prominence.openweathermap.api.enums.SubscriptionPlan.*;
*/
public class OpenWeatherMapClient {
private final String apiKey;
private final TimeoutSettings timeoutSettings = new TimeoutSettings();
private HttpClient httpClient = new HttpURLConnectionBasedHttpClient();
/**
* Created OpenWeatherMap client object.
* @param apiKey API key obtained on <a href="https://home.openweathermap.org/api_keys">OpwnWeatherMap site</a>.
* @param apiKey API key obtained on <a href="https://home.openweathermap.org/api_keys">OpenWeatherMap site</a>.
*/
public OpenWeatherMapClient(String apiKey) {
this.apiKey = apiKey;
}
public void setConnectionTimeout(int connectionTimeout) {
timeoutSettings.setConnectionTimeout(connectionTimeout);
}
public void setReadTimeout(int readTimeout) {
timeoutSettings.setReadTimeout(readTimeout);
}
public void setHttpClient(HttpClient httpClient) {
this.httpClient = httpClient;
}
/**
* Current Weather <a href="https://openweathermap.org/current">API</a>.
* @return requester for retrieving current weather information.
*/
@SubscriptionAvailability(plans = ALL)
public CurrentWeatherRequester currentWeather() {
return new CurrentWeatherRequesterImpl(apiKey);
return new CurrentWeatherRequester(getRequestSettings());
}
/**
* Hourly forecast <a href="https://openweathermap.org/api/hourly-forecast">API</a>.
* @return requester for retrieving hourly weather forecast information for 4 days.
*/
@SubscriptionAvailability(plans = { DEVELOPER, PROFESSIONAL, ENTERPRISE })
public FourDaysHourlyForecastRequester forecastHourly4Days() {
return new FourDaysHourlyForecastRequester(getRequestSettings());
}
/**
* 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.
* @return requester for retrieving one call weather information.
*/
@SubscriptionAvailability(plans = ALL)
public OneCallWeatherRequester oneCall() {
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());
}
/**
@@ -60,6 +131,36 @@ public class OpenWeatherMapClient {
*/
@SubscriptionAvailability(plans = ALL)
public FiveDayThreeHourStepForecastRequester forecast5Day3HourStep() {
return new FiveDayThreeHourStepForecastRequesterImpl(apiKey);
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() {
final RequestSettings requestSettings = new RequestSettings(apiKey, timeoutSettings);
requestSettings.setHttpClient(httpClient);
return requestSettings;
}
}
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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;
public class TimeoutSettings {
private Integer connectionTimeout;
private 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 void setConnectionTimeout(Integer connectionTimeout) {
this.connectionTimeout = connectionTimeout;
}
public Integer getReadTimeout() {
return readTimeout;
}
public void setReadTimeout(Integer readTimeout) {
this.readTimeout = readTimeout;
}
}
@@ -0,0 +1,10 @@
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,126 @@
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.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
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) {
InputStream resultStream;
try {
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
if (timeoutSettings != null) {
if (timeoutSettings.getConnectionTimeout() != null) {
connection.setConnectTimeout(timeoutSettings.getConnectionTimeout());
}
if (timeoutSettings.getReadTimeout() != null) {
connection.setReadTimeout(timeoutSettings.getReadTimeout());
}
}
connection.setRequestMethod("GET");
connection.setRequestProperty("Content-Type", "application/json; utf-8");
connection.setRequestProperty("Accept", "application/json");
resultStream = switch (connection.getResponseCode()) {
case HttpURLConnection.HTTP_OK -> connection.getInputStream();
case HttpURLConnection.HTTP_UNAUTHORIZED -> throw new InvalidAuthTokenException();
case HttpURLConnection.HTTP_NOT_FOUND, HttpURLConnection.HTTP_BAD_REQUEST ->
throw new NoDataFoundException();
default -> throw new IllegalStateException("Unexpected value: " + connection.getResponseCode());
};
} catch (IllegalStateException | IOException ex) {
logger.error("An error occurred during OpenWeatherMap API response parsing: ", ex);
throw new NoDataFoundException(ex);
}
logger.debug("Executing OpenWeatherMap API request: " + url);
return convertInputStreamToString(resultStream);
}
@Override
public String executePostRequest(String url, String body) {
InputStream resultStream;
try {
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
if (timeoutSettings != null) {
if (timeoutSettings.getConnectionTimeout() != null) {
connection.setConnectTimeout(timeoutSettings.getConnectionTimeout());
}
if (timeoutSettings.getReadTimeout() != null) {
connection.setReadTimeout(timeoutSettings.getReadTimeout());
}
}
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json; utf-8");
connection.setRequestProperty("Accept", "application/json");
connection.setDoOutput(true);
try(OutputStream os = connection.getOutputStream()) {
byte[] input = body.getBytes(StandardCharsets.UTF_8);
os.write(input, 0, input.length);
}
resultStream = switch (connection.getResponseCode()) {
case HttpURLConnection.HTTP_OK -> connection.getInputStream();
case HttpURLConnection.HTTP_UNAUTHORIZED -> throw new InvalidAuthTokenException();
case HttpURLConnection.HTTP_NOT_FOUND, HttpURLConnection.HTTP_BAD_REQUEST ->
throw new NoDataFoundException();
default -> throw new IllegalStateException("Unexpected value: " + connection.getResponseCode());
};
} catch (IllegalStateException | IOException ex) {
logger.error("An error occurred during OpenWeatherMap API response parsing: ", ex);
throw new NoDataFoundException(ex);
}
logger.debug("Executing OpenWeatherMap API request: " + url);
return convertInputStreamToString(resultStream);
}
/**
* 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 static String convertInputStreamToString(InputStream inputStream) {
StringBuilder result = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
} catch (IOException ex) {
logger.error("Error during response reading: ", ex);
throw new IllegalArgumentException(ex);
}
return result.toString();
}
}
@@ -0,0 +1,97 @@
/*
* Copyright (c) 2021 Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.core.net;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.github.prominence.openweathermap.api.request.RequestSettings;
import java.net.URL;
import java.util.stream.Collectors;
public final class RequestExecutor {
private static final String OWM_URL_BASE = "https://SUBDOMAIN.openweathermap.org/";
private final RequestSettings requestSettings;
public RequestExecutor(RequestSettings requestSettings) {
this.requestSettings = requestSettings;
}
public String getResponse() {
return getResponse(Method.GET);
}
public String getResponse(Method httpMethod) {
return getResponse(buildRequestUrl(), 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.getHttpClient();
httpClient.setTimeoutSettings(requestSettings.getTimeoutSettings());
if (httpMethod == Method.GET) {
return httpClient.executeGetRequest(url);
} else {
return httpClient.executePostRequest(url, getSerializedPayload());
}
}
private String buildRequestUrl() {
StringBuilder requestUrlBuilder = new StringBuilder(OWM_URL_BASE.replace("SUBDOMAIN", requestSettings.getSubdomain()));
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 ObjectMapper objectMapper = new ObjectMapper();
final SimpleModule module = new SimpleModule();
module.addSerializer(requestSettings.getPayloadClass(), requestSettings.getPayloadSerializer());
objectMapper.registerModule(module);
try {
return objectMapper.writeValueAsString(requestSettings.getPayloadObject());
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
public enum Method {
GET,
POST
}
}
@@ -0,0 +1,52 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.model.AtmosphericPressure;
import java.io.IOException;
public class AtmosphericPressureDeserializer extends JsonDeserializer<AtmosphericPressure> {
@Override
public AtmosphericPressure deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
final JsonNode mainNode = p.getCodec().readTree(p);
final AtmosphericPressure atmosphericPressure = AtmosphericPressure.withValue(mainNode.get("pressure").asDouble());
final JsonNode seaLevelNode = mainNode.get("sea_level");
final JsonNode groundLevelNode = mainNode.get("grnd_level");
if (seaLevelNode != null) {
atmosphericPressure.setSeaLevelValue(seaLevelNode.asDouble());
}
if (groundLevelNode != null) {
atmosphericPressure.setGroundLevelValue(groundLevelNode.asDouble());
}
return atmosphericPressure;
}
}
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.model.Clouds;
import java.io.IOException;
public class CloudsDeserializer extends JsonDeserializer<Clouds> {
@Override
public Clouds deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
final JsonNode cloudsNode = p.getCodec().readTree(p);
final JsonNode allValueNode = cloudsNode.get("all");
if (allValueNode != null) {
return Clouds.withValue((byte) allValueNode.asInt());
}
return null;
}
}
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.model.Coordinates;
import java.io.IOException;
public class CoordinatesDeserializer extends JsonDeserializer<Coordinates> {
@Override
public Coordinates deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JacksonException {
JsonNode rootNode = jp.getCodec().readTree(jp);
if (rootNode.has("lat") && rootNode.has("lon")) {
return Coordinates.of(rootNode.get("lat").asDouble(), rootNode.get("lon").asDouble());
}
return null;
}
}
@@ -0,0 +1,57 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.github.prominence.openweathermap.api.model.Coordinates;
import com.github.prominence.openweathermap.api.model.geocoding.GeocodingRecord;
import java.io.IOException;
import java.util.Map;
public class GeocodingRecordDeserializer extends JsonDeserializer<GeocodingRecord> {
private static final ObjectMapper objectMapper = new ObjectMapper();
public GeocodingRecordDeserializer() {
final SimpleModule module = new SimpleModule();
module.addDeserializer(Coordinates.class, new CoordinatesDeserializer());
objectMapper.registerModule(module);
}
@Override
public GeocodingRecord deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JacksonException {
JsonNode rootNode = jp.getCodec().readTree(jp);
String name = rootNode.get("name").asText();
String country = rootNode.get("country").asText();
Map<String, String> localNames = objectMapper.readValue(objectMapper.treeAsTokens(rootNode.get("local_names")), new TypeReference<Map<String, String>>() {});
Coordinates coordinates = objectMapper.readValue(objectMapper.treeAsTokens(rootNode), Coordinates.class);
return new GeocodingRecord(name, localNames, coordinates, country);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Alexey Zinchenko
* Copyright (c) 2022 Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -20,31 +20,22 @@
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.request;
package com.github.prominence.openweathermap.api.deserializer;
import com.github.prominence.openweathermap.api.enums.Language;
import com.github.prominence.openweathermap.api.enums.UnitSystem;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.model.Humidity;
/**
* The interface Request customizer.
*
* @param <T> the type parameter
*/
public interface RequestCustomizer<T extends RequestCustomizer<?>> {
import java.io.IOException;
/**
* Customize language.
*
* @param language the language
* @return the request customizer
*/
T language(Language language);
public class HumidityDeserializer extends JsonDeserializer<Humidity> {
@Override
public Humidity deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
final JsonNode rootNode = p.getCodec().readTree(p);
/**
* Customize unit system.
*
* @param unitSystem the unit system
* @return the request customizer
*/
T unitSystem(UnitSystem unitSystem);
return Humidity.withValue((byte) (rootNode.get("humidity").asInt()));
}
}
@@ -0,0 +1,59 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.enums.UnitSystem;
import com.github.prominence.openweathermap.api.model.Temperature;
import java.io.IOException;
public class TemperatureDeserializer extends JsonDeserializer<Temperature> {
@Override
public Temperature deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
final JsonNode mainNode = p.getCodec().readTree(p);
final UnitSystem unitSystem = (UnitSystem) ctxt.findInjectableValue("unitSystem", null, null);
final double tempValue = mainNode.get("temp").asDouble();
final Temperature temperature = Temperature.withValue(tempValue, unitSystem.getTemperatureUnit());
final JsonNode feelsLikeNode = mainNode.get("feels_like");
if (feelsLikeNode != null) {
temperature.setFeelsLike(feelsLikeNode.asDouble());
}
final JsonNode tempMaxNode = mainNode.get("temp_max");
if (tempMaxNode != null) {
temperature.setMaxTemperature(tempMaxNode.asDouble());
}
final JsonNode tempMinNode = mainNode.get("temp_min");
if (tempMinNode != null) {
temperature.setMinTemperature(tempMinNode.asDouble());
}
return temperature;
}
}
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.model.WeatherState;
import java.io.IOException;
public class WeatherStateDeserializer extends JsonDeserializer<WeatherState> {
@Override
public WeatherState deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
JsonNode weatherNode = p.getCodec().readTree(p);
final WeatherState weatherState = new WeatherState(
weatherNode.get("id").asInt(),
weatherNode.get("main").asText(),
weatherNode.get("description").asText()
);
weatherState.setIconId(weatherNode.get("icon").asText());
return weatherState;
}
}
@@ -0,0 +1,66 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.enums.UnitSystem;
import com.github.prominence.openweathermap.api.model.Wind;
import java.io.IOException;
public class WindDeserializer extends JsonDeserializer<Wind> {
@Override
public Wind deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
final JsonNode windNode = p.getCodec().readTree(p);
final UnitSystem unitSystem = (UnitSystem) ctxt.findInjectableValue("unitSystem", null, null);
JsonNode speedNode = windNode.get("speed");
if (speedNode == null) {
speedNode = windNode.get("wind_speed");
}
double speed = speedNode.asDouble();
final Wind wind = Wind.withValue(speed, unitSystem.getWindUnit());
JsonNode degNode = windNode.get("deg");
if (degNode == null) {
degNode = windNode.get("wind_deg");
}
if (degNode != null) {
wind.setDegrees(degNode.asDouble());
}
JsonNode gustNode = windNode.get("gust");
if (gustNode == null) {
gustNode = windNode.get("wind_gust");
}
if (gustNode != null) {
wind.setGust(gustNode.asDouble());
}
return wind;
}
}
@@ -0,0 +1,57 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.github.prominence.openweathermap.api.model.Coordinates;
import com.github.prominence.openweathermap.api.model.geocoding.ZipCodeGeocodingRecord;
import java.io.IOException;
public class ZipCodeGeocodingDeserializer extends JsonDeserializer<ZipCodeGeocodingRecord> {
private static final ObjectMapper objectMapper = new ObjectMapper();
public ZipCodeGeocodingDeserializer() {
final SimpleModule module = new SimpleModule();
module.addDeserializer(Coordinates.class, new CoordinatesDeserializer());
objectMapper.registerModule(module);
}
@Override
public ZipCodeGeocodingRecord deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
JsonNode rootNode = p.getCodec().readTree(p);
String zip = rootNode.get("zip").asText();
String name = rootNode.get("name").asText();
String country = rootNode.get("country").asText();
Coordinates coordinates = objectMapper.readValue(objectMapper.treeAsTokens(rootNode), Coordinates.class);
return new ZipCodeGeocodingRecord(zip, name, coordinates, country);
}
}
@@ -0,0 +1,18 @@
package com.github.prominence.openweathermap.api.deserializer.forecast.climatic;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.model.forecast.climatic.AtmosphericPressure;
import java.io.IOException;
public class ClimaticForecastAtmosphericPressureDeserializer extends JsonDeserializer<AtmosphericPressure> {
@Override
public AtmosphericPressure deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
final JsonNode jsonNode = jsonParser.getCodec().readTree(jsonParser);
return (AtmosphericPressure) AtmosphericPressure.withValue(jsonNode.get("pressure").asDouble());
}
}
@@ -0,0 +1,23 @@
package com.github.prominence.openweathermap.api.deserializer.forecast.climatic;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.model.Clouds;
import java.io.IOException;
public class ClimaticForecastCloudsDeserializer extends JsonDeserializer<Clouds> {
@Override
public Clouds deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
final JsonNode rootNode = jsonParser.getCodec().readTree(jsonParser);
final JsonNode cloudsNode = rootNode.get("clouds");
if (cloudsNode != null) {
return Clouds.withValue((byte) cloudsNode.asInt());
}
return null;
}
}
@@ -0,0 +1,54 @@
package com.github.prominence.openweathermap.api.deserializer.forecast.climatic;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.github.prominence.openweathermap.api.deserializer.CoordinatesDeserializer;
import com.github.prominence.openweathermap.api.model.Coordinates;
import com.github.prominence.openweathermap.api.model.forecast.climatic.Location;
import java.io.IOException;
import static com.github.prominence.openweathermap.api.utils.JsonDeserializationUtils.parseZoneOffset;
public class ClimaticForecastLocationDeserializer extends JsonDeserializer<Location> {
private final ObjectMapper objectMapper = new ObjectMapper();
public ClimaticForecastLocationDeserializer() {
final SimpleModule module = new SimpleModule();
module.addDeserializer(Coordinates.class, new CoordinatesDeserializer());
objectMapper.registerModule(module);
}
@Override
public Location deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
final JsonNode rootNode = jsonParser.getCodec().readTree(jsonParser);
final Location location = (Location) Location.withValues(rootNode.get("id").asInt(), rootNode.get("name").asText());
final JsonNode timezoneNode = rootNode.get("timezone");
if (timezoneNode != null) {
location.setZoneOffset(parseZoneOffset(timezoneNode));
}
final JsonNode countryNode = rootNode.get("country");
if (countryNode != null) {
location.setCountryCode(countryNode.asText());
}
final JsonNode coordNode = rootNode.get("coord");
if (coordNode != null) {
location.setCoordinates(objectMapper.readValue(objectMapper.treeAsTokens(coordNode), Coordinates.class));
}
final JsonNode populationNode = rootNode.get("population");
if (populationNode != null) {
location.setPopulation(populationNode.asLong());
}
return location;
}
}
@@ -0,0 +1,22 @@
package com.github.prominence.openweathermap.api.deserializer.forecast.climatic;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.model.forecast.climatic.Rain;
import java.io.IOException;
public class ClimaticForecastRainDeserializer extends JsonDeserializer<Rain> {
@Override
public Rain deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
final JsonNode rootNode = jsonParser.getCodec().readTree(jsonParser);
final JsonNode rainNode = rootNode.get("rain");
if (rainNode != null) {
return (Rain) Rain.withValue(rainNode.asDouble());
}
return null;
}
}
@@ -0,0 +1,22 @@
package com.github.prominence.openweathermap.api.deserializer.forecast.climatic;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.model.forecast.climatic.Snow;
import java.io.IOException;
public class ClimaticForecastSnowDeserializer extends JsonDeserializer<Snow> {
@Override
public Snow deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
final JsonNode rootNode = jsonParser.getCodec().readTree(jsonParser);
final JsonNode snowNode = rootNode.get("snow");
if (snowNode != null) {
return (Snow) Snow.withValue(snowNode.asDouble());
}
return null;
}
}
@@ -0,0 +1,34 @@
package com.github.prominence.openweathermap.api.deserializer.forecast.climatic;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.model.forecast.climatic.Temperature;
import java.io.IOException;
public class ClimaticForecastTemperatureDeserializer extends JsonDeserializer<Temperature> {
@Override
public Temperature deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
final JsonNode rootNode = jsonParser.getCodec().readTree(jsonParser);
final Temperature temperature = new Temperature();
final JsonNode tempNode = rootNode.get("temp");
temperature.setMorning(tempNode.get("morn").asDouble());
temperature.setDay(tempNode.get("day").asDouble());
temperature.setEve(tempNode.get("eve").asDouble());
temperature.setNight(tempNode.get("night").asDouble());
temperature.setMin(tempNode.get("min").asDouble());
temperature.setMax(tempNode.get("max").asDouble());
final JsonNode feelsLikeNode = rootNode.get("feels_like");
temperature.setMorningFeelsLike(feelsLikeNode.get("morn").asDouble());
temperature.setDayFeelsLike(feelsLikeNode.get("day").asDouble());
temperature.setEveFeelsLike(feelsLikeNode.get("eve").asDouble());
temperature.setNightFeelsLike(feelsLikeNode.get("night").asDouble());
return temperature;
}
}
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.forecast.climatic;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.enums.UnitSystem;
import com.github.prominence.openweathermap.api.model.Wind;
import java.io.IOException;
public class ClimaticForecastWindDeserializer extends JsonDeserializer<Wind> {
@Override
public Wind deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
final JsonNode windNode = p.getCodec().readTree(p);
final UnitSystem unitSystem = (UnitSystem) ctxt.findInjectableValue("unitSystem", null, null);
JsonNode speedNode = windNode.get("speed");
if (speedNode == null) {
speedNode = windNode.get("wind_speed");
}
double speed = speedNode.asDouble();
final Wind wind = Wind.withValue(speed, unitSystem.getWindUnit());
JsonNode degNode = windNode.get("deg");
if (degNode == null) {
degNode = windNode.get("wind_deg");
}
if (degNode != null) {
wind.setDegrees(degNode.asDouble());
}
return wind;
}
}
@@ -0,0 +1,18 @@
package com.github.prominence.openweathermap.api.deserializer.forecast.daily;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.model.forecast.daily.AtmosphericPressure;
import java.io.IOException;
public class DailyForecastAtmosphericPressureDeserializer extends JsonDeserializer<AtmosphericPressure> {
@Override
public AtmosphericPressure deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
final JsonNode jsonNode = jsonParser.getCodec().readTree(jsonParser);
return (AtmosphericPressure) AtmosphericPressure.withValue(jsonNode.get("pressure").asDouble());
}
}
@@ -0,0 +1,23 @@
package com.github.prominence.openweathermap.api.deserializer.forecast.daily;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.model.Clouds;
import java.io.IOException;
public class DailyForecastCloudsDeserializer extends JsonDeserializer<Clouds> {
@Override
public Clouds deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
final JsonNode rootNode = jsonParser.getCodec().readTree(jsonParser);
final JsonNode cloudsNode = rootNode.get("clouds");
if (cloudsNode != null) {
return Clouds.withValue((byte) cloudsNode.asInt());
}
return null;
}
}
@@ -0,0 +1,54 @@
package com.github.prominence.openweathermap.api.deserializer.forecast.daily;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.github.prominence.openweathermap.api.deserializer.CoordinatesDeserializer;
import com.github.prominence.openweathermap.api.model.Coordinates;
import com.github.prominence.openweathermap.api.model.forecast.daily.Location;
import java.io.IOException;
import static com.github.prominence.openweathermap.api.utils.JsonDeserializationUtils.parseZoneOffset;
public class DailyForecastLocationDeserializer extends JsonDeserializer<Location> {
private final ObjectMapper objectMapper = new ObjectMapper();
public DailyForecastLocationDeserializer() {
final SimpleModule module = new SimpleModule();
module.addDeserializer(Coordinates.class, new CoordinatesDeserializer());
objectMapper.registerModule(module);
}
@Override
public Location deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
final JsonNode rootNode = jsonParser.getCodec().readTree(jsonParser);
final Location location = (Location) Location.withValues(rootNode.get("id").asInt(), rootNode.get("name").asText());
final JsonNode timezoneNode = rootNode.get("timezone");
if (timezoneNode != null) {
location.setZoneOffset(parseZoneOffset(timezoneNode));
}
final JsonNode countryNode = rootNode.get("country");
if (countryNode != null) {
location.setCountryCode(countryNode.asText());
}
final JsonNode coordNode = rootNode.get("coord");
if (coordNode != null) {
location.setCoordinates(objectMapper.readValue(objectMapper.treeAsTokens(coordNode), Coordinates.class));
}
final JsonNode populationNode = rootNode.get("population");
if (populationNode != null) {
location.setPopulation(populationNode.asLong());
}
return location;
}
}
@@ -0,0 +1,22 @@
package com.github.prominence.openweathermap.api.deserializer.forecast.daily;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.model.forecast.daily.Rain;
import java.io.IOException;
public class DailyForecastRainDeserializer extends JsonDeserializer<Rain> {
@Override
public Rain deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
final JsonNode rootNode = jsonParser.getCodec().readTree(jsonParser);
final JsonNode rainNode = rootNode.get("rain");
if (rainNode != null) {
return (Rain) Rain.withValue(rainNode.asDouble());
}
return null;
}
}
@@ -0,0 +1,22 @@
package com.github.prominence.openweathermap.api.deserializer.forecast.daily;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.model.forecast.daily.Snow;
import java.io.IOException;
public class DailyForecastSnowDeserializer extends JsonDeserializer<Snow> {
@Override
public Snow deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
final JsonNode rootNode = jsonParser.getCodec().readTree(jsonParser);
final JsonNode snowNode = rootNode.get("snow");
if (snowNode != null) {
return (Snow) Snow.withValue(snowNode.asDouble());
}
return null;
}
}
@@ -0,0 +1,34 @@
package com.github.prominence.openweathermap.api.deserializer.forecast.daily;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.model.forecast.daily.Temperature;
import java.io.IOException;
public class DailyForecastTemperatureDeserializer extends JsonDeserializer<Temperature> {
@Override
public Temperature deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
final JsonNode rootNode = jsonParser.getCodec().readTree(jsonParser);
final Temperature temperature = new Temperature();
final JsonNode tempNode = rootNode.get("temp");
temperature.setMorning(tempNode.get("morn").asDouble());
temperature.setDay(tempNode.get("day").asDouble());
temperature.setEve(tempNode.get("eve").asDouble());
temperature.setNight(tempNode.get("night").asDouble());
temperature.setMin(tempNode.get("min").asDouble());
temperature.setMax(tempNode.get("max").asDouble());
final JsonNode feelsLikeNode = rootNode.get("feels_like");
temperature.setMorningFeelsLike(feelsLikeNode.get("morn").asDouble());
temperature.setDayFeelsLike(feelsLikeNode.get("day").asDouble());
temperature.setEveFeelsLike(feelsLikeNode.get("eve").asDouble());
temperature.setNightFeelsLike(feelsLikeNode.get("night").asDouble());
return temperature;
}
}
@@ -0,0 +1,87 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.forecast.free;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.github.prominence.openweathermap.api.deserializer.CoordinatesDeserializer;
import com.github.prominence.openweathermap.api.model.Coordinates;
import com.github.prominence.openweathermap.api.model.forecast.free.Location;
import java.io.IOException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.TimeZone;
public class FreeForecastLocationDeserializer extends JsonDeserializer<Location> {
private final ObjectMapper objectMapper = new ObjectMapper();
public FreeForecastLocationDeserializer() {
final SimpleModule module = new SimpleModule();
module.addDeserializer(Coordinates.class, new CoordinatesDeserializer());
objectMapper.registerModule(module);
}
@Override
public Location deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
final JsonNode rootNode = p.getCodec().readTree(p);
final Location location = Location.withValues(rootNode.get("id").asInt(), rootNode.get("name").asText());
final JsonNode timezoneNode = rootNode.get("timezone");
if (timezoneNode != null) {
location.setZoneOffset(ZoneOffset.ofTotalSeconds(timezoneNode.asInt()));
}
final JsonNode countryNode = rootNode.get("country");
if (countryNode != null) {
location.setCountryCode(countryNode.asText());
}
final JsonNode sunriseNode = rootNode.get("sunrise");
final JsonNode sunsetNode = rootNode.get("sunset");
if (sunriseNode != null) {
location.setSunriseTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(sunriseNode.asLong()), TimeZone.getDefault().toZoneId()));
}
if (sunsetNode != null) {
location.setSunsetTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(sunsetNode.asLong()), TimeZone.getDefault().toZoneId()));
}
final JsonNode coordNode = rootNode.get("coord");
if (coordNode != null) {
location.setCoordinates(objectMapper.readValue(objectMapper.treeAsTokens(coordNode), Coordinates.class));
}
final JsonNode populationNode = rootNode.get("population");
if (populationNode != null) {
location.setPopulation(populationNode.asLong());
}
return location;
}
}
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.forecast.free;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.model.forecast.free.Rain;
import java.io.IOException;
public class FreeForecastRainDeserializer extends JsonDeserializer<Rain> {
@Override
public Rain deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
final JsonNode rainNode = p.getCodec().readTree(p);
final JsonNode oneHourNode = rainNode.get("3h");
if (oneHourNode != null) {
return Rain.withThreeHourLevelValue(oneHourNode.asDouble());
}
return null;
}
}
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.forecast.free;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.model.forecast.free.Snow;
import java.io.IOException;
public class FreeForecastSnowDeserializer extends JsonDeserializer<Snow> {
@Override
public Snow deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
final JsonNode snowNode = p.getCodec().readTree(p);
final JsonNode oneHourNode = snowNode.get("3h");
if (oneHourNode != null) {
return Snow.withThreeHourLevelValue(oneHourNode.asDouble());
}
return null;
}
}
@@ -0,0 +1,82 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.forecast.hourly;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.github.prominence.openweathermap.api.deserializer.CoordinatesDeserializer;
import com.github.prominence.openweathermap.api.model.Coordinates;
import com.github.prominence.openweathermap.api.model.forecast.hourly.Location;
import java.io.IOException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.TimeZone;
public class HourlyForecastLocationDeserializer extends JsonDeserializer<Location> {
private final ObjectMapper objectMapper = new ObjectMapper();
public HourlyForecastLocationDeserializer() {
final SimpleModule module = new SimpleModule();
module.addDeserializer(Coordinates.class, new CoordinatesDeserializer());
objectMapper.registerModule(module);
}
@Override
public Location deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
final JsonNode rootNode = p.getCodec().readTree(p);
final Location location = Location.withValues(rootNode.get("id").asInt(), rootNode.get("name").asText());
final JsonNode timezoneNode = rootNode.get("timezone");
if (timezoneNode != null) {
location.setZoneOffset(ZoneOffset.ofTotalSeconds(timezoneNode.asInt()));
}
final JsonNode countryNode = rootNode.get("country");
if (countryNode != null) {
location.setCountryCode(countryNode.asText());
}
final JsonNode sunriseNode = rootNode.get("sunrise");
final JsonNode sunsetNode = rootNode.get("sunset");
if (sunriseNode != null) {
location.setSunriseTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(sunriseNode.asLong()), TimeZone.getDefault().toZoneId()));
}
if (sunsetNode != null) {
location.setSunsetTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(sunsetNode.asLong()), TimeZone.getDefault().toZoneId()));
}
final JsonNode coordNode = rootNode.get("coord");
if (coordNode != null) {
location.setCoordinates(objectMapper.readValue(objectMapper.treeAsTokens(coordNode), Coordinates.class));
}
return location;
}
}
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.forecast.hourly;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.model.forecast.hourly.Rain;
import java.io.IOException;
public class HourlyForecastRainDeserializer extends JsonDeserializer<Rain> {
@Override
public Rain deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
final JsonNode rainNode = p.getCodec().readTree(p);
final JsonNode oneHourNode = rainNode.get("1h");
if (oneHourNode != null) {
return Rain.withOneHourLevelValue(oneHourNode.asDouble());
}
return null;
}
}
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.forecast.hourly;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.model.forecast.hourly.Snow;
import java.io.IOException;
public class HourlyForecastSnowDeserializer extends JsonDeserializer<Snow> {
@Override
public Snow deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
final JsonNode snowNode = p.getCodec().readTree(p);
final JsonNode oneHourNode = snowNode.get("1h");
if (oneHourNode != null) {
return Snow.withOneHourLevelValue(oneHourNode.asDouble());
}
return null;
}
}
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.onecall;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.model.onecall.current.Alert;
import com.github.prominence.openweathermap.api.utils.JsonDeserializationUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class AlertDeserializer extends JsonDeserializer<Alert> {
@Override
public Alert deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
final JsonNode alertNode = p.getCodec().readTree(p);
Alert alert = new Alert();
alert.setSenderName(alertNode.get("sender_name").asText());
alert.setEventName(alertNode.get("event").asText());
alert.setStartTime(JsonDeserializationUtils.parseDateTime(alertNode.get("start")));
alert.setEndTime(JsonDeserializationUtils.parseDateTime(alertNode.get("end")));
alert.setDescription(alertNode.get("description").asText());
final JsonNode tagsNode = alertNode.get("tags");
if (tagsNode != null) {
List<String> tags = new ArrayList<>();
for (JsonNode tagNode : tagsNode) {
tags.add(tagNode.asText());
}
alert.setTags(tags);
}
return alert;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Alexey Zinchenko
* Copyright (c) 2022 Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -20,21 +20,21 @@
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.request.weather.multiple;
package com.github.prominence.openweathermap.api.deserializer.onecall;
import com.github.prominence.openweathermap.api.model.weather.Weather;
import com.github.prominence.openweathermap.api.request.RequestTerminator;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.model.onecall.AtmosphericPressure;
import java.util.List;
import java.io.IOException;
/**
* The interface Multiple result current weather request terminator.
*/
public interface MultipleResultCitiesInCircleCurrentWeatherRequestTerminator extends RequestTerminator<List<Weather>, String> {
/**
* XML response format.
*
* @return the XML string
*/
String asXML();
public class OneCallAtmosphericPressureDeserializer extends JsonDeserializer<AtmosphericPressure> {
@Override
public AtmosphericPressure deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
final JsonNode rootNode = p.getCodec().readTree(p);
return AtmosphericPressure.withValue(rootNode.get("pressure").asDouble());
}
}
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.onecall;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.model.onecall.current.DailyRain;
import java.io.IOException;
public class OneCallDailyRainDeserializer extends JsonDeserializer<DailyRain> {
@Override
public DailyRain deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
final JsonNode rootNode = p.getCodec().readTree(p);
final JsonNode valueNode = rootNode.get("rain");
if (valueNode != null) {
return DailyRain.withValue(valueNode.asDouble());
}
return null;
}
}
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.onecall;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.model.onecall.current.DailySnow;
import java.io.IOException;
public class OneCallDailySnowDeserializer extends JsonDeserializer<DailySnow> {
@Override
public DailySnow deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
final JsonNode rootNode = p.getCodec().readTree(p);
final JsonNode valueNode = rootNode.get("snow");
if (valueNode != null) {
return DailySnow.withValue(valueNode.asDouble());
}
return null;
}
}
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.onecall;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.model.onecall.current.DailyTemperature;
import java.io.IOException;
public class OneCallDailyTemperatureDeserializer extends JsonDeserializer<DailyTemperature> {
@Override
public DailyTemperature deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
final JsonNode rootNode = p.getCodec().readTree(p);
final DailyTemperature temperature = new DailyTemperature();
final JsonNode tempNode = rootNode.get("temp");
temperature.setMorning(tempNode.get("morn").asDouble());
temperature.setDay(tempNode.get("day").asDouble());
temperature.setEve(tempNode.get("eve").asDouble());
temperature.setNight(tempNode.get("night").asDouble());
temperature.setMin(tempNode.get("min").asDouble());
temperature.setMax(tempNode.get("max").asDouble());
final JsonNode feelsLikeNode = rootNode.get("feels_like");
temperature.setMorningFeelsLike(feelsLikeNode.get("morn").asDouble());
temperature.setDayFeelsLike(feelsLikeNode.get("day").asDouble());
temperature.setEveFeelsLike(feelsLikeNode.get("eve").asDouble());
temperature.setNightFeelsLike(feelsLikeNode.get("night").asDouble());
return temperature;
}
}
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.onecall;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.model.onecall.Rain;
import java.io.IOException;
public class OneCallRainDeserializer extends JsonDeserializer<Rain> {
@Override
public Rain deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
final JsonNode rootNode = p.getCodec().readTree(p);
final JsonNode rainNode = rootNode.get("rain");
if (rainNode != null) {
final JsonNode oneHourNode = rainNode.get("1h");
if (oneHourNode != null) {
return Rain.withOneHourLevelValue(oneHourNode.asDouble());
}
}
return null;
}
}
@@ -0,0 +1,48 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.onecall;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.model.onecall.Rain;
import com.github.prominence.openweathermap.api.model.onecall.Snow;
import java.io.IOException;
public class OneCallSnowDeserializer extends JsonDeserializer<Snow> {
@Override
public Snow deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
final JsonNode rootNode = p.getCodec().readTree(p);
final JsonNode snowNode = rootNode.get("snow");
if (snowNode != null) {
final JsonNode OneHourNode = snowNode.get("1h");
if (OneHourNode != null) {
Rain.withOneHourLevelValue(OneHourNode.asDouble());
}
}
return null;
}
}
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.onecall;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.enums.UnitSystem;
import com.github.prominence.openweathermap.api.model.onecall.Temperature;
import java.io.IOException;
public class OneCallTemperatureDeserializer extends JsonDeserializer<Temperature> {
@Override
public Temperature deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
final JsonNode rootNode = p.getCodec().readTree(p);
final UnitSystem unitSystem = (UnitSystem) ctxt.findInjectableValue("unitSystem", null, null);
final double tempValue = rootNode.get("temp").asDouble();
final Temperature temperature = Temperature.withValue(tempValue, unitSystem.getTemperatureUnit());
final JsonNode tempFeelsLike = rootNode.get("feels_like");
if (tempFeelsLike != null) {
temperature.setFeelsLike(tempFeelsLike.asDouble());
}
final JsonNode dewPoint = rootNode.get("dew_point");
if (dewPoint != null) {
temperature.setDewPoint(dewPoint.asDouble());
}
return temperature;
}
}
@@ -0,0 +1,29 @@
package com.github.prominence.openweathermap.api.deserializer.radiation;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.model.radiation.SolarRadiationRecord;
import com.github.prominence.openweathermap.api.utils.JsonDeserializationUtils;
import java.io.IOException;
public class SolarRadiationRecordDeserializer extends JsonDeserializer<SolarRadiationRecord> {
@Override
public SolarRadiationRecord deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
final JsonNode rootNode = jsonParser.getCodec().readTree(jsonParser);
SolarRadiationRecord record = new SolarRadiationRecord();
final JsonNode radiationNode = rootNode.get("radiation");
record.setMeasurementTime(JsonDeserializationUtils.parseDateTime(rootNode.get("dt")));
record.setCloudSkyGlobalHorizontalIrradiance(radiationNode.get("ghi").asDouble());
record.setCloudSkyDirectNormalIrradiance(radiationNode.get("dni").asDouble());
record.setCloudSkyDiffuseHorizontalIrradiance(radiationNode.get("dhi").asDouble());
record.setClearSkyGlobalHorizontalIrradiance(radiationNode.get("ghi_cs").asDouble());
record.setClearSkyDirectNormalIrradiance(radiationNode.get("dni_cs").asDouble());
record.setClearSkyDiffuseHorizontalIrradiance(radiationNode.get("dhi_cs").asDouble());
return record;
}
}
@@ -0,0 +1,23 @@
package com.github.prominence.openweathermap.api.deserializer.roadrisk;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.enums.EventLevel;
import com.github.prominence.openweathermap.api.model.roadrisk.Alert;
import java.io.IOException;
public class RoadRiskAlertDeserializer extends JsonDeserializer<Alert> {
@Override
public Alert deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
final JsonNode rootNode = jsonParser.getCodec().readTree(jsonParser);
final Alert alert = new Alert();
alert.setEvent(rootNode.get("event").asText());
alert.setSenderName(rootNode.get("sender_name").asText());
alert.setEventLevel(EventLevel.findByValue(rootNode.get("event_level").asInt()));
return alert;
}
}
@@ -0,0 +1,23 @@
package com.github.prominence.openweathermap.api.deserializer.roadrisk;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.enums.RoadState;
import com.github.prominence.openweathermap.api.model.roadrisk.RoadDetails;
import java.io.IOException;
public class RoadRiskRoadDetailsDeserializer extends JsonDeserializer<RoadDetails> {
@Override
public RoadDetails deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
final JsonNode rootNode = jsonParser.getCodec().readTree(jsonParser);
final RoadDetails roadDetails = new RoadDetails();
roadDetails.setSurfaceTemperature(rootNode.get("temp").asDouble());
roadDetails.setRoadState(RoadState.findByValue(rootNode.get("state").asInt()));
return roadDetails;
}
}
@@ -0,0 +1,31 @@
package com.github.prominence.openweathermap.api.deserializer.roadrisk;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.model.roadrisk.Weather;
import java.io.IOException;
public class RoadRiskWeatherDeserializer extends JsonDeserializer<Weather> {
@Override
public Weather deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
final JsonNode rootNode = jsonParser.getCodec().readTree(jsonParser);
final Weather weather = new Weather();
weather.setTemperature(rootNode.get("temp").asDouble());
weather.setDewPoint(rootNode.get("dew_point").asDouble());
weather.setWindSpeed(rootNode.get("wind_speed").asDouble());
weather.setWindDegrees(rootNode.get("wind_deg").asDouble());
if (rootNode.has("precipitation_intensity")) {
weather.setPrecipitationIntensity(rootNode.get("precipitation_intensity").asDouble());
}
if (rootNode.has("visibility")) {
weather.setVisibilityInMetres(rootNode.get("visibility").asDouble());
}
return weather;
}
}
@@ -0,0 +1,85 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.weather;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.github.prominence.openweathermap.api.deserializer.CoordinatesDeserializer;
import com.github.prominence.openweathermap.api.model.Coordinates;
import com.github.prominence.openweathermap.api.model.weather.Location;
import java.io.IOException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.TimeZone;
public class WeatherLocationDeserializer extends JsonDeserializer<Location> {
private final ObjectMapper objectMapper = new ObjectMapper();
public WeatherLocationDeserializer() {
final SimpleModule module = new SimpleModule();
module.addDeserializer(Coordinates.class, new CoordinatesDeserializer());
objectMapper.registerModule(module);
}
@Override
public Location deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
final JsonNode rootNode = p.getCodec().readTree(p);
final Location location = Location.withValues(rootNode.get("id").asInt(), rootNode.get("name").asText());
final JsonNode timezoneNode = rootNode.get("timezone");
if (timezoneNode != null) {
location.setZoneOffset(ZoneOffset.ofTotalSeconds(timezoneNode.asInt()));
}
final JsonNode sysNode = rootNode.get("sys");
if (sysNode != null) {
final JsonNode countryNode = sysNode.get("country");
if (countryNode != null) {
location.setCountryCode(countryNode.asText());
}
final JsonNode sunriseNode = sysNode.get("sunrise");
final JsonNode sunsetNode = sysNode.get("sunset");
if (sunriseNode != null) {
location.setSunriseTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(sunriseNode.asInt()), TimeZone.getDefault().toZoneId()));
}
if (sunsetNode != null) {
location.setSunsetTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(sunsetNode.asInt()), TimeZone.getDefault().toZoneId()));
}
}
final JsonNode coordNode = rootNode.get("coord");
if (coordNode != null) {
location.setCoordinates(objectMapper.readValue(objectMapper.treeAsTokens(coordNode), Coordinates.class));
}
return location;
}
}
@@ -0,0 +1,51 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.weather;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.model.weather.Rain;
import java.io.IOException;
public class WeatherRainDeserializer extends JsonDeserializer<Rain> {
@Override
public Rain deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
final JsonNode rainNode = p.getCodec().readTree(p);
if (rainNode != null) {
final JsonNode oneHourNode = rainNode.get("1h");
final JsonNode threeHourNode = rainNode.get("3h");
if (oneHourNode != null && threeHourNode != null) {
return Rain.withValues(oneHourNode.asDouble(), threeHourNode.asDouble());
} else if (oneHourNode != null) {
return Rain.withOneHourLevelValue(oneHourNode.asDouble());
} else if (threeHourNode != null) {
return Rain.withThreeHourLevelValue(threeHourNode.asDouble());
}
}
return null;
}
}
@@ -0,0 +1,51 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.weather;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.prominence.openweathermap.api.model.weather.Snow;
import java.io.IOException;
public class WeatherSnowDeserializer extends JsonDeserializer<Snow> {
@Override
public Snow deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
final JsonNode snowNode = p.getCodec().readTree(p);
if (snowNode != null) {
final JsonNode oneHourNode = snowNode.get("1h");
final JsonNode threeHourNode = snowNode.get("3h");
if (oneHourNode != null && threeHourNode != null) {
return Snow.withValues(oneHourNode.asDouble(), threeHourNode.asDouble());
} else if (oneHourNode != null) {
return Snow.withOneHourLevelValue(oneHourNode.asDouble());
} else if (threeHourNode != null) {
return Snow.withThreeHourLevelValue(threeHourNode.asDouble());
}
}
return null;
}
}
@@ -0,0 +1,80 @@
/*
*
* * Copyright (c) 2021 Alexey Zinchenko
* *
* * Permission is hereby granted, free of charge, to any person obtaining a copy
* * of this software and associated documentation files (the "Software"), to deal
* * in the Software without restriction, including without limitation the rights
* * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* * copies of the Software, and to permit persons to whom the Software is
* * furnished to do so, subject to the following conditions:
* *
* * The above copyright notice and this permission notice shall be included in all
* * copies or substantial portions of the Software.
* *
* * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* * SOFTWARE.
*
*/
package com.github.prominence.openweathermap.api.enums;
import java.util.Arrays;
import java.util.Optional;
/**
* 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
*/
public static AirQualityIndex getByIndex(int index) {
final Optional<AirQualityIndex> optionalAirQualityIndex = Arrays.stream(values()).filter(airQualityIndex -> airQualityIndex.getValue() == index).findFirst();
return optionalAirQualityIndex.orElse(null);
}
}
@@ -0,0 +1,25 @@
package com.github.prominence.openweathermap.api.enums;
import java.util.Arrays;
public enum EventLevel {
UNKNOWN(0),
GREEN(1),
YELLOW(2),
ORANGE(3),
RED(4);
private final int value;
EventLevel(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public static EventLevel findByValue(int value) {
return Arrays.stream(values()).filter(eventLevel -> eventLevel.getValue() == value).findFirst().orElse(null);
}
}
@@ -27,11 +27,26 @@ package com.github.prominence.openweathermap.api.enums;
* Usually it could be specified to get response with some fields translated into desired language.
*/
public enum Language {
/**
* Afrikaans language.
*/
AFRIKAANS("af"),
/**
* Albanian language.
*/
ALBANIAN("al"),
/**
* Arabic language.
*/
ARABIC("ar"),
/**
* Azerbaijani language.
*/
AZERBAIJANI("az"),
/**
* Bulgarian language.
*/
@@ -47,6 +62,11 @@ public enum Language {
*/
CZECH("cz"),
/**
* Danish language
*/
DANISH("da"),
/**
* German language.
*/
@@ -62,6 +82,11 @@ public enum Language {
*/
ENGLISH("en"),
/**
* Basque language.
*/
BASQUE("eu"),
/**
* Persian language.
*/
@@ -82,6 +107,16 @@ public enum Language {
*/
GALICIAN("gl"),
/**
* Hebrew language.
*/
HEBREW("he"),
/**
* Hindi language.
*/
HINDI("hi"),
/**
* Croatian language.
*/
@@ -92,6 +127,11 @@ public enum Language {
*/
HUNGARIAN("hu"),
/**
* Indonesian language.
*/
INDONESIAN("id"),
/**
* Italian language.
*/
@@ -122,6 +162,11 @@ public enum Language {
*/
MACEDONIAN("mk"),
/**
* Norwegian language.
*/
NORWEGIAN("no"),
/**
* Dutch language.
*/
@@ -137,6 +182,11 @@ public enum Language {
*/
PORTUGUESE("pt"),
/**
* Português Brasil language.
*/
PORTUGUES_BRAZIL("pt_br"),
/**
* Romanian language.
*/
@@ -165,7 +215,17 @@ public enum Language {
/**
* Spanish language.
*/
SPANISH("en"),
SPANISH("es"),
/**
* Serbian language.
*/
SERBIAN("sr"),
/**
* Thai language.
*/
THAI("th"),
/**
* Turkish language.
@@ -173,9 +233,9 @@ public enum Language {
TURKISH("tr"),
/**
* Ukranian language.
* Ukrainian language.
*/
UKRANIAN("uk"),
UKRAINIAN("uk"),
/**
* Vietnamese language.
@@ -190,7 +250,12 @@ public enum Language {
/**
* Chinese traditional language.
*/
CHINESE_TRADITIONAL("zh_tw");
CHINESE_TRADITIONAL("zh_tw"),
/**
* Zulu language.
*/
ZULU("zu");
private final String value;
@@ -0,0 +1,62 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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;
}
return INVALID;
}
private static boolean equals(double d1, double d2) {
return Math.abs(d1 - d2) < precision;
}
}
@@ -20,28 +20,45 @@
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.request.weather.single;
import com.github.prominence.openweathermap.api.model.weather.Weather;
import com.github.prominence.openweathermap.api.request.AsyncRequestTerminator;
import java.util.concurrent.CompletableFuture;
package com.github.prominence.openweathermap.api.enums;
/**
* The current weather async request terminator interface.
* The enum One call result options.
*/
public interface SingleResultCurrentWeatherAsyncRequestTerminator extends AsyncRequestTerminator<Weather, String> {
public enum OneCallResultOptions {
/**
* XML response format.
*
* @return the completable future
* Current one call result options.
*/
CompletableFuture<String> asXML();
CURRENT("current"),
/**
* Minutely one call result options.
*/
MINUTELY("minutely"),
/**
* Hourly one call result options.
*/
HOURLY("hourly"),
/**
* Daily one call result options.
*/
DAILY("daily"),
/**
* Alerts one call result options.
*/
ALERTS("alerts");
/**
* HTML response format.
*
* @return the completable future
*/
CompletableFuture<String> asHTML();
private final String value;
OneCallResultOptions(String value) {
this.value = value;
}
/**
* Gets value.
*
* @return the value
*/
public String getValue() {
return value;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Alexey Zinchenko
* Copyright (c) 2022 Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -20,27 +20,23 @@
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.request;
package com.github.prominence.openweathermap.api.enums;
/**
* The interface Request terminator.
*
* @param <T> the type parameter
* @param <S> the type parameter
*/
public interface RequestTerminator<T, S> {
public enum ResponseType {
HTML("html"),
XML("xml");
/**
* Java object response format.
*
* @return the java object
*/
T asJava();
private final String value;
/**
* JSON response format.
*
* @return the JSON string
*/
S asJSON();
ResponseType(String value) {
this.value = value;
}
/**
* Returns language's value.
* @return value.
*/
public String getValue() {
return value;
}
}
@@ -0,0 +1,39 @@
package com.github.prominence.openweathermap.api.enums;
import java.util.Arrays;
public enum RoadState {
NO_REPORT(0),
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;
}
public static RoadState findByValue(int value) {
return Arrays.stream(values()).filter(roadState -> roadState.getValue() == value).findFirst().orElse(null);
}
}
@@ -28,9 +28,9 @@ package com.github.prominence.openweathermap.api.enums;
*/
public enum SubscriptionPlan {
/**
* Free subscription plan.
* An alias that represents any of paid plans: startup, developer, professional or enterprise.
*/
FREE,
PAID,
/**
* Startup subscription plan.
@@ -52,6 +52,12 @@ public enum SubscriptionPlan {
*/
ENTERPRISE,
/**
* Special subscription plan. You should contact a manager to get an access.
*/
SPECIAL,
/**
* All existing subscription plans.
*/
@@ -52,14 +52,10 @@ public enum UnitSystem {
* @return wind unit.
*/
public String getWindUnit() {
switch (this) {
case IMPERIAL:
return "miles/hour";
case STANDARD:
case METRIC:
default:
return "meter/sec";
}
return switch (this) {
case IMPERIAL -> "miles/hour";
case STANDARD, METRIC -> "meter/sec";
};
}
/**
@@ -67,15 +63,11 @@ public enum UnitSystem {
* @return temperature unit.
*/
public String getTemperatureUnit() {
switch (this) {
case METRIC:
return "";
case IMPERIAL:
return "";
case STANDARD:
default:
return "";
}
return switch (this) {
case METRIC -> "°C";
case IMPERIAL -> "°F";
case STANDARD -> "";
};
}
/**
@@ -0,0 +1,375 @@
/*
* 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.enums;
import java.util.Arrays;
import java.util.Optional;
/**
* Represents weather condition and related information.
* More details <a href="https://openweathermap.org/weather-conditions#Weather-Condition-Codes-2">here</a>.
*/
public enum WeatherCondition {
// Group 2xx: Thunderstorm
/**
* The thunderstorm with light rain.
*/
THUNDERSTORM_LIGHT_RAIN(200, "Thunderstorm", "thunderstorm with light rain", "11"),
/**
* The thunderstorm with rain.
*/
THUNDERSTORM_RAIN(201, "Thunderstorm", "thunderstorm with rain", "11"),
/**
* The thunderstorm with heavy rain.
*/
THUNDERSTORM_HEAVY_RAIN(202, "Thunderstorm", "thunderstorm with heavy rain", "11"),
/**
* The light thunderstorm.
*/
THUNDERSTORM_LIGHT(210, "Thunderstorm", "light thunderstorm", "11"),
/**
* The thunderstorm.
*/
THUNDERSTORM(211, "Thunderstorm", "thunderstorm", "11"),
/**
* The heavy thunderstorm.
*/
THUNDERSTORM_HEAVY(212, "Thunderstorm", "heavy thunderstorm", "11"),
/**
* The ragged thunderstorm.
*/
THUNDERSTORM_RAGGED(221, "Thunderstorm", "ragged thunderstorm", "11"),
/**
* The thunderstorm with light drizzle.
*/
THUNDERSTORM_LIGHT_DRIZZLE(230, "Thunderstorm", "thunderstorm with light drizzle", "11"),
/**
* The thunderstorm with drizzle.
*/
THUNDERSTORM_DRIZZLE(231, "Thunderstorm", "thunderstorm with drizzle", "11"),
/**
* The thunderstorm with heavy drizzle.
*/
THUNDERSTORM_HEAVY_DRIZZLE(232, "Thunderstorm", "thunderstorm with heavy drizzle", "11"),
// Group 3xx: Drizzle
/**
* The light intensity drizzle.
*/
DRIZZLE_LIGHT(300, "Drizzle", "light intensity drizzle", "09"),
/**
* The drizzle.
*/
DRIZZLE(301, "Drizzle", "drizzle", "09"),
/**
* The heavy intensity drizzle.
*/
DRIZZLE_HEAVY(302, "Drizzle", "heavy intensity drizzle", "09"),
/**
* The light intensity drizzle rain.
*/
DRIZZLE_LIGHT_RAIN(310, "Drizzle", "light intensity drizzle rain", "09"),
/**
* The drizzle rain.
*/
DRIZZLE_RAIN(311, "Drizzle", "drizzle rain", "09"),
/**
* The heavy intensity drizzle rain.
*/
DRIZZLE_HEAVY_RAIN(312, "Drizzle", "heavy intensity drizzle rain", "09"),
/**
* The shower rain and drizzle.
*/
DRIZZLE_SHOWER_RAIN(313, "Drizzle", "shower rain and drizzle", "09"),
/**
* The heavy shower rain and drizzle.
*/
DRIZZLE_HEAVY_SHOWER_RAIN(314, "Drizzle", "heavy shower rain and drizzle", "09"),
/**
* The shower drizzle.
*/
DRIZZLE_SHOWER(321, "Drizzle", "shower drizzle", "09"),
// Group 5xx: Rain
/**
* The light rain.
*/
RAIN_LIGHT(500, "Rain", "light rain", "10"),
/**
* The moderate rain.
*/
RAIN_MODERATE(501, "Rain", "moderate rain", "10"),
/**
* The heavy intensity rain.
*/
RAIN_HEAVY(502, "Rain", "heavy intensity rain", "10"),
/**
* The very heavy rain.
*/
RAIN_VERY_HEAVY(503, "Rain", "very heavy rain", "10"),
/**
* The very heavy rain.
*/
RAIN_EXTREME(504, "Rain", "very heavy rain", "10"),
/**
* The freezing rain.
*/
RAIN_FREEZING(511, "Rain", "freezing rain", "10"),
/**
* The light intensity shower rain.
*/
RAIN_LIGHT_SHOWER(520, "Rain", "light intensity shower rain", "10"),
/**
* The shower rain.
*/
RAIN_SHOWER(521, "Rain", "shower rain", "10"),
/**
* The heavy intensity shower rain.
*/
RAIN_HEAVY_SHOWER(522, "Rain", "heavy intensity shower rain", "10"),
/**
* The ragged shower rain.
*/
RAIN_RAGGED_SHOWER(531, "Rain", "ragged shower rain", "10"),
// Group 6xx: Snow
/**
* The light snow.
*/
SNOW_LIGHT(600, "Snow", "light snow", "13"),
/**
* The snow.
*/
SNOW(601, "Snow", "snow", "13"),
/**
* The heavy snow.
*/
SNOW_HEAVY(602, "Snow", "heavy snow", "13"),
/**
* The sleet.
*/
SNOW_SLEET(611, "Snow", "sleet", "13"),
/**
* The light shower sleet.
*/
SNOW_LIGHT_SHOWER_SLEET(612, "Snow", "light shower sleet", "13"),
/**
* The shower sleet.
*/
SNOW_SHOWER_SLEET(613, "Snow", "shower sleet", "13"),
/**
* The light rain and snow.
*/
SNOW_LIGHT_RAIN_AND_SNOW(615, "Snow", "light rain and snow", "13"),
/**
* The rain and snow.
*/
SNOW_RAIN_AND_SNOW(616, "Snow", "rain and snow", "13"),
/**
* The light shower snow.
*/
SNOW_LIGHT_SHOWER_SNOW(620, "Snow", "light shower snow", "13"),
/**
* The shower snow.
*/
SNOW_SHOWER_SNOW(621, "Snow", "shower snow", "13"),
/**
* The heavy shower snow.
*/
SNOW_HEAVY_SHOWER_SNOW(622, "Snow", "heavy shower snow", "13"),
// Group 7xx: Atmosphere
/**
* The mist.
*/
MIST(701, "Mist", "mist", "50"),
/**
* The smoke.
*/
SMOKE(711, "Smoke", "smoke", "50"),
/**
* The haze.
*/
HAZE(721, "Haze", "haze", "50"),
/**
* The sand/dust whirls.
*/
DUST_WHIRLS(731, "Dust", "sand/dust whirls", "50"),
/**
* The fog.
*/
FOG(741, "Fog", "fog", "50"),
/**
* The sand.
*/
SAND(751, "Sand", "sand", "50"),
/**
* The dust.
*/
DUST(761, "Dust", "dust", "50"),
/**
* The volcanic ash.
*/
ASH(762, "Ash", "volcanic ash", "50"),
/**
* The squall.
*/
SQUALL(771, "Squall", "squalls", "50"),
/**
* The tornado.
*/
TORNADO(781, "Tornado", "tornado", "50"),
// Group 800: Clear
/**
* The clear sky.
*/
CLEAR(800, "Clear", "clear sky", "01"),
// Group 80x: Clouds
/**
* A few clouds: 11-25%.
*/
CLOUDS_FEW(801, "Clouds", "few clouds: 11-25%", "02"),
/**
* A scattered clouds: 25-50%.
*/
CLOUDS_SCATTERED(802, "Clouds", "scattered clouds: 25-50%", "03"),
/**
* A broken clouds: 51-84%.
*/
CLOUDS_BROKEN(803, "Clouds", "broken clouds: 51-84%", "04"),
/**
* An overcast clouds: 85-100%.
*/
CLOUDS_OVERCAST(804, "Clouds", "overcast clouds: 85-100%", "04");
private final int id;
private final String name;
private final String description;
private final String iconId;
private WeatherCondition(int id, String name, String description, String iconId) {
this.id = id;
this.name = name;
this.description = description;
this.iconId = iconId;
}
/**
* 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 day icon id.
*
* @return the day icon id
*/
public String getDayIconId() {
return iconId + 'd';
}
/**
* Gets night icon id.
*
* @return the night icon id
*/
public String getNightIconId() {
return iconId + 'n';
}
/**
* Gets day icon url.
*
* @return the day icon url
*/
public String getDayIconUrl() {
return getIconUrl(getDayIconId());
}
/**
* Gets night icon url.
*
* @return the night icon url
*/
public String getNightIconUrl() {
return getIconUrl(getNightIconId());
}
/**
* Gets icon url.
*
* @param iconId the icon id
* @return the icon url
*/
public static String getIconUrl(String iconId) {
return "http://openweathermap.org/img/w/" + iconId + ".png";
}
/**
* Gets {@link WeatherCondition} by id.
*
* @param id the id
* @return the by id
*/
public static WeatherCondition getById(int id) {
final Optional<WeatherCondition> optionalWeatherCondition = Arrays.stream(values()).filter(weatherCondition -> weatherCondition.getId() == id).findFirst();
return optionalWeatherCondition.orElse(null);
}
@Override
public String toString() {
return "Weather condition(" + id + "): " + name + '(' + description + ')';
}
}
@@ -0,0 +1,61 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.mapper;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.prominence.openweathermap.api.model.WeatherState;
import com.github.prominence.openweathermap.api.utils.JsonDeserializationUtils;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
public abstract class AbstractMapper {
protected final ObjectMapper objectMapper = new ObjectMapper();
protected LocalDateTime parseDateTime(JsonNode dateTimeNode) {
return JsonDeserializationUtils.parseDateTime(dateTimeNode);
}
protected ZoneId parseZoneId(JsonNode zoneIdNode) {
return JsonDeserializationUtils.parseZoneId(zoneIdNode);
}
protected ZoneOffset parseZoneOffset(JsonNode zoneOffsetNode) {
return JsonDeserializationUtils.parseZoneOffset(zoneOffsetNode);
}
protected List<WeatherState> parseWeatherStates(JsonNode weatherArrayNode) throws IOException {
List<WeatherState> weatherStateList = new ArrayList<>();
if (weatherArrayNode != null && weatherArrayNode.isArray()) {
for (JsonNode weatherNode : weatherArrayNode) {
weatherStateList.add(objectMapper.readValue(objectMapper.treeAsTokens(weatherNode), WeatherState.class));
}
}
return weatherStateList;
}
}
@@ -0,0 +1,102 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.mapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.prominence.openweathermap.api.enums.AirQualityIndex;
import com.github.prominence.openweathermap.api.model.Coordinates;
import com.github.prominence.openweathermap.api.model.air.pollution.AirPollutionDetails;
import com.github.prominence.openweathermap.api.model.air.pollution.AirPollutionRecord;
import java.time.Instant;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.TimeZone;
/**
* Official API response documentation: <a href="https://openweathermap.org/api/air-pollution#fields">https://openweathermap.org/api/air-pollution#fields</a>.
*/
public class AirPollutionResponseMapper {
/**
* Map to air pollution air pollution.
*
* @param json the json
* @return the air pollution
*/
public AirPollutionDetails mapToAirPollution(String json) {
final ObjectMapper objectMapper = new ObjectMapper();
AirPollutionDetails airPollutionDetails;
try {
final JsonNode root = objectMapper.readTree(json);
airPollutionDetails = mapToAirPollution(root);
} catch (JsonProcessingException e) {
throw new RuntimeException("Cannot parse Air Pollution response");
}
return airPollutionDetails;
}
private AirPollutionDetails mapToAirPollution(JsonNode rootNode) {
final AirPollutionDetails airPollutionDetails = new AirPollutionDetails();
airPollutionDetails.setCoordinates(parseCoordinate(rootNode.get("coord")));
final List<AirPollutionRecord> sampleList = new ArrayList<>();
final JsonNode sampleListNode = rootNode.get("list");
sampleListNode.forEach(sampleNode -> {
sampleList.add(parseAirPollutionSample(sampleNode));
});
airPollutionDetails.setAirPollutionRecords(sampleList);
return airPollutionDetails;
}
private AirPollutionRecord parseAirPollutionSample(JsonNode sampleNode) {
AirPollutionRecord airPollutionRecord = new AirPollutionRecord();
airPollutionRecord.setForecastTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(sampleNode.get("dt").asInt()), TimeZone.getDefault().toZoneId()));
airPollutionRecord.setAirQualityIndex(AirQualityIndex.getByIndex(sampleNode.get("main").get("aqi").asInt()));
final JsonNode componentsNode = sampleNode.get("components");
airPollutionRecord.setCO(componentsNode.get("co").asDouble());
airPollutionRecord.setNO(componentsNode.get("no").asDouble());
airPollutionRecord.setNO2(componentsNode.get("no2").asDouble());
airPollutionRecord.setO3(componentsNode.get("o3").asDouble());
airPollutionRecord.setSO2(componentsNode.get("so2").asDouble());
airPollutionRecord.setPM2_5(componentsNode.get("pm2_5").asDouble());
airPollutionRecord.setPM10(componentsNode.get("pm10").asDouble());
airPollutionRecord.setNH3(componentsNode.get("nh3").asDouble());
return airPollutionRecord;
}
private Coordinates parseCoordinate(JsonNode rootNode) {
final JsonNode latitudeNode = rootNode.get("lat");
final JsonNode longitudeNode = rootNode.get("lon");
if (latitudeNode != null && longitudeNode != null) {
return Coordinates.of(latitudeNode.asDouble(), longitudeNode.asDouble());
}
return null;
}
}
@@ -0,0 +1,84 @@
package com.github.prominence.openweathermap.api.mapper;
import com.fasterxml.jackson.databind.InjectableValues;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.github.prominence.openweathermap.api.deserializer.HumidityDeserializer;
import com.github.prominence.openweathermap.api.deserializer.WeatherStateDeserializer;
import com.github.prominence.openweathermap.api.deserializer.forecast.climatic.*;
import com.github.prominence.openweathermap.api.enums.UnitSystem;
import com.github.prominence.openweathermap.api.model.Clouds;
import com.github.prominence.openweathermap.api.model.Humidity;
import com.github.prominence.openweathermap.api.model.WeatherState;
import com.github.prominence.openweathermap.api.model.Wind;
import com.github.prominence.openweathermap.api.model.forecast.climatic.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class ClimaticForecastResponseMapper extends AbstractMapper {
public ClimaticForecastResponseMapper(UnitSystem unitSystem) {
objectMapper.setInjectableValues(new InjectableValues.Std().addValue("unitSystem", unitSystem != null ? unitSystem : UnitSystem.STANDARD));
final SimpleModule module = new SimpleModule();
module.addDeserializer(WeatherState.class, new WeatherStateDeserializer());
module.addDeserializer(Temperature.class, new ClimaticForecastTemperatureDeserializer());
module.addDeserializer(AtmosphericPressure.class, new ClimaticForecastAtmosphericPressureDeserializer());
module.addDeserializer(Humidity.class, new HumidityDeserializer());
module.addDeserializer(Clouds.class, new ClimaticForecastCloudsDeserializer());
module.addDeserializer(Rain.class, new ClimaticForecastRainDeserializer());
module.addDeserializer(Snow.class, new ClimaticForecastSnowDeserializer());
module.addDeserializer(Wind.class, new ClimaticForecastWindDeserializer());
module.addDeserializer(Location.class, new ClimaticForecastLocationDeserializer());
objectMapper.registerModule(module);
}
public Forecast mapToForecast(String json) {
Forecast forecast;
try {
final JsonNode root = objectMapper.readTree(json);
forecast = mapToForecast(root);
} catch (IOException e) {
throw new RuntimeException("Cannot parse Forecast response", e);
}
return forecast;
}
private Forecast mapToForecast(JsonNode root) throws IOException {
final Forecast forecast = new Forecast();
forecast.setLocation(objectMapper.readValue(objectMapper.treeAsTokens(root.get("city")), Location.class));
final List<WeatherForecast> forecasts = new ArrayList<>();
final JsonNode forecastListNode = root.get("list");
for (JsonNode forecastNode : forecastListNode) {
forecasts.add(parseWeatherForecast(forecastNode));
}
forecast.setWeatherForecasts(forecasts);
return forecast;
}
private WeatherForecast parseWeatherForecast(JsonNode rootNode) throws IOException {
final WeatherForecast weatherForecast = new WeatherForecast();
weatherForecast.setForecastTime(parseDateTime(rootNode.get("dt")));
weatherForecast.setSunriseTime(parseDateTime(rootNode.get("sunrise")));
weatherForecast.setSunsetTime(parseDateTime(rootNode.get("sunset")));
weatherForecast.setWeatherStates(parseWeatherStates(rootNode.get("weather")));
weatherForecast.setTemperature(objectMapper.readValue(objectMapper.treeAsTokens(rootNode), Temperature.class));
weatherForecast.setAtmosphericPressure(objectMapper.readValue(objectMapper.treeAsTokens(rootNode), AtmosphericPressure.class));
weatherForecast.setHumidity(objectMapper.readValue(objectMapper.treeAsTokens(rootNode), Humidity.class));
weatherForecast.setClouds(objectMapper.readValue(objectMapper.treeAsTokens(rootNode), Clouds.class));
weatherForecast.setWind(objectMapper.readValue(objectMapper.treeAsTokens(rootNode), Wind.class));
weatherForecast.setRain(objectMapper.readValue(objectMapper.treeAsTokens(rootNode), Rain.class));
weatherForecast.setSnow(objectMapper.readValue(objectMapper.treeAsTokens(rootNode), Snow.class));
return weatherForecast;
}
}
@@ -0,0 +1,112 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.mapper;
import com.fasterxml.jackson.databind.InjectableValues;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.github.prominence.openweathermap.api.deserializer.*;
import com.github.prominence.openweathermap.api.deserializer.weather.WeatherLocationDeserializer;
import com.github.prominence.openweathermap.api.deserializer.weather.WeatherRainDeserializer;
import com.github.prominence.openweathermap.api.deserializer.weather.WeatherSnowDeserializer;
import com.github.prominence.openweathermap.api.enums.UnitSystem;
import com.github.prominence.openweathermap.api.model.*;
import com.github.prominence.openweathermap.api.model.weather.Location;
import com.github.prominence.openweathermap.api.model.weather.Rain;
import com.github.prominence.openweathermap.api.model.weather.Snow;
import com.github.prominence.openweathermap.api.model.weather.Weather;
import java.io.IOException;
/**
* Official API response documentation: <a href="https://openweathermap.org/current#current_JSON">https://openweathermap.org/current#current_JSON</a>.
* Ignored internal parameters: "root.cod", "sys.type", "sys.id", "sys.message".
*/
public class CurrentWeatherResponseMapper extends AbstractMapper {
/**
* Instantiates a new Current weather response mapper.
*
* @param unitSystem the unit system
*/
public CurrentWeatherResponseMapper(UnitSystem unitSystem) {
objectMapper.setInjectableValues(new InjectableValues.Std().addValue("unitSystem", unitSystem != null ? unitSystem : UnitSystem.STANDARD));
final SimpleModule module = new SimpleModule();
module.addDeserializer(WeatherState.class, new WeatherStateDeserializer());
module.addDeserializer(Temperature.class, new TemperatureDeserializer());
module.addDeserializer(AtmosphericPressure.class, new AtmosphericPressureDeserializer());
module.addDeserializer(Humidity.class, new HumidityDeserializer());
module.addDeserializer(Wind.class, new WindDeserializer());
module.addDeserializer(Rain.class, new WeatherRainDeserializer());
module.addDeserializer(Snow.class, new WeatherSnowDeserializer());
module.addDeserializer(Clouds.class, new CloudsDeserializer());
module.addDeserializer(Location.class, new WeatherLocationDeserializer());
objectMapper.registerModule(module);
}
/**
* Gets single result.
*
* @param json the json string
* @return the weather object
*/
public Weather mapToWeather(String json) {
Weather weather;
try {
final JsonNode root = objectMapper.readTree(json);
weather = mapToWeather(root);
} catch (IOException e) {
throw new RuntimeException("Cannot parse Weather response", e);
}
return weather;
}
private Weather mapToWeather(JsonNode rootNode) throws IOException {
final JsonNode weatherArrayNode = rootNode.get("weather");
final Weather weather = new Weather();
weather.setWeatherStates(parseWeatherStates(weatherArrayNode));
weather.setTemperature(objectMapper.readValue(objectMapper.treeAsTokens(rootNode.get("main")), Temperature.class));
weather.setAtmosphericPressure(objectMapper.readValue(objectMapper.treeAsTokens(rootNode.get("main")), AtmosphericPressure.class));
weather.setHumidity(objectMapper.readValue(objectMapper.treeAsTokens(rootNode.get("main")), Humidity.class));
weather.setWind(objectMapper.readValue(objectMapper.treeAsTokens(rootNode.get("wind")), Wind.class));
if (rootNode.has("rain")) {
weather.setRain(objectMapper.readValue(objectMapper.treeAsTokens(rootNode.get("rain")), Rain.class));
}
if (rootNode.has("snow")) {
weather.setSnow(objectMapper.readValue(objectMapper.treeAsTokens(rootNode.get("snow")), Snow.class));
}
weather.setClouds(objectMapper.readValue(objectMapper.treeAsTokens(rootNode.get("clouds")), Clouds.class));
weather.setLocation(objectMapper.readValue(objectMapper.treeAsTokens(rootNode), Location.class));
final JsonNode dtNode = rootNode.get("dt");
if (dtNode != null) {
weather.setCalculationTime(parseDateTime(dtNode));
}
weather.setBase(rootNode.get("base").asText());
return weather;
}
}
@@ -0,0 +1,119 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.mapper;
import com.fasterxml.jackson.databind.InjectableValues;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.github.prominence.openweathermap.api.deserializer.HumidityDeserializer;
import com.github.prominence.openweathermap.api.deserializer.WeatherStateDeserializer;
import com.github.prominence.openweathermap.api.deserializer.WindDeserializer;
import com.github.prominence.openweathermap.api.deserializer.forecast.daily.*;
import com.github.prominence.openweathermap.api.enums.UnitSystem;
import com.github.prominence.openweathermap.api.model.Clouds;
import com.github.prominence.openweathermap.api.model.Humidity;
import com.github.prominence.openweathermap.api.model.WeatherState;
import com.github.prominence.openweathermap.api.model.Wind;
import com.github.prominence.openweathermap.api.model.forecast.daily.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Official API response documentation: <a href="https://openweathermap.org/forecast16#JSON">https://openweathermap.org/forecast16#JSON</a>.
*/
public class DailyForecastResponseMapper extends AbstractMapper {
public DailyForecastResponseMapper(UnitSystem unitSystem) {
objectMapper.setInjectableValues(new InjectableValues.Std().addValue("unitSystem", unitSystem != null ? unitSystem : UnitSystem.STANDARD));
final SimpleModule module = new SimpleModule();
module.addDeserializer(WeatherState.class, new WeatherStateDeserializer());
module.addDeserializer(Temperature.class, new DailyForecastTemperatureDeserializer());
module.addDeserializer(AtmosphericPressure.class, new DailyForecastAtmosphericPressureDeserializer());
module.addDeserializer(Humidity.class, new HumidityDeserializer());
module.addDeserializer(Clouds.class, new DailyForecastCloudsDeserializer());
module.addDeserializer(Rain.class, new DailyForecastRainDeserializer());
module.addDeserializer(Snow.class, new DailyForecastSnowDeserializer());
module.addDeserializer(Wind.class, new WindDeserializer());
module.addDeserializer(Location.class, new DailyForecastLocationDeserializer());
objectMapper.registerModule(module);
}
/**
* Maps forecast response into java object.
*
* @param json the json string
* @return the forecast
*/
public Forecast mapToForecast(String json) {
Forecast forecast;
try {
final JsonNode root = objectMapper.readTree(json);
forecast = mapToForecast(root);
} catch (IOException e) {
throw new RuntimeException("Cannot parse Forecast response", e);
}
return forecast;
}
private Forecast mapToForecast(JsonNode root) throws IOException {
final Forecast forecast = new Forecast();
forecast.setLocation(objectMapper.readValue(objectMapper.treeAsTokens(root.get("city")), Location.class));
final List<WeatherForecast> forecasts = new ArrayList<>(root.get("cnt").asInt());
final JsonNode forecastListNode = root.get("list");
for (JsonNode forecastNode : forecastListNode) {
forecasts.add(parseWeatherForecast(forecastNode));
}
forecast.setWeatherForecasts(forecasts);
return forecast;
}
private WeatherForecast parseWeatherForecast(JsonNode rootNode) throws IOException {
final WeatherForecast weatherForecast = new WeatherForecast();
weatherForecast.setForecastTime(parseDateTime(rootNode.get("dt")));
weatherForecast.setSunriseTime(parseDateTime(rootNode.get("sunrise")));
weatherForecast.setSunsetTime(parseDateTime(rootNode.get("sunset")));
weatherForecast.setWeatherStates(parseWeatherStates(rootNode.get("weather")));
weatherForecast.setTemperature(objectMapper.readValue(objectMapper.treeAsTokens(rootNode), Temperature.class));
weatherForecast.setAtmosphericPressure(objectMapper.readValue(objectMapper.treeAsTokens(rootNode), AtmosphericPressure.class));
weatherForecast.setHumidity(objectMapper.readValue(objectMapper.treeAsTokens(rootNode), Humidity.class));
weatherForecast.setClouds(objectMapper.readValue(objectMapper.treeAsTokens(rootNode), Clouds.class));
weatherForecast.setWind(objectMapper.readValue(objectMapper.treeAsTokens(rootNode), Wind.class));
weatherForecast.setRain(objectMapper.readValue(objectMapper.treeAsTokens(rootNode), Rain.class));
weatherForecast.setSnow(objectMapper.readValue(objectMapper.treeAsTokens(rootNode), Snow.class));
if (rootNode.has("pop")) {
weatherForecast.setProbabilityOfPrecipitation(rootNode.get("pop").asDouble());
}
return weatherForecast;
}
}
@@ -0,0 +1,137 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.mapper;
import com.fasterxml.jackson.databind.InjectableValues;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.github.prominence.openweathermap.api.deserializer.*;
import com.github.prominence.openweathermap.api.deserializer.forecast.free.FreeForecastLocationDeserializer;
import com.github.prominence.openweathermap.api.deserializer.forecast.free.FreeForecastRainDeserializer;
import com.github.prominence.openweathermap.api.deserializer.forecast.free.FreeForecastSnowDeserializer;
import com.github.prominence.openweathermap.api.enums.UnitSystem;
import com.github.prominence.openweathermap.api.model.*;
import com.github.prominence.openweathermap.api.model.forecast.free.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Official API response documentation: <a href="https://openweathermap.org/forecast5#JSON">https://openweathermap.org/forecast5#JSON</a>.
*/
public class FiveDayThreeHourStepForecastResponseMapper extends AbstractMapper {
/**
* Instantiates a new forecast response mapper.
*
* @param unitSystem the unit system
*/
public FiveDayThreeHourStepForecastResponseMapper(UnitSystem unitSystem) {
objectMapper.setInjectableValues(new InjectableValues.Std().addValue("unitSystem", unitSystem != null ? unitSystem : UnitSystem.STANDARD));
final SimpleModule module = new SimpleModule();
module.addDeserializer(WeatherState.class, new WeatherStateDeserializer());
module.addDeserializer(Temperature.class, new TemperatureDeserializer());
module.addDeserializer(AtmosphericPressure.class, new AtmosphericPressureDeserializer());
module.addDeserializer(Humidity.class, new HumidityDeserializer());
module.addDeserializer(Clouds.class, new CloudsDeserializer());
module.addDeserializer(Wind.class, new WindDeserializer());
module.addDeserializer(Rain.class, new FreeForecastRainDeserializer());
module.addDeserializer(Snow.class, new FreeForecastSnowDeserializer());
module.addDeserializer(Location.class, new FreeForecastLocationDeserializer());
objectMapper.registerModule(module);
}
/**
* Maps forecast response into java object.
*
* @param json the json string
* @return the forecast
*/
public Forecast mapToForecast(String json) {
Forecast forecast;
try {
final JsonNode root = objectMapper.readTree(json);
forecast = mapToForecast(root);
} catch (IOException e) {
throw new RuntimeException("Cannot parse Forecast response", e);
}
return forecast;
}
private Forecast mapToForecast(JsonNode rootNode) throws IOException {
final Forecast forecast = new Forecast();
forecast.setLocation(objectMapper.readValue(objectMapper.treeAsTokens(rootNode.get("city")), Location.class));
final List<WeatherForecast> forecasts = new ArrayList<>(rootNode.get("cnt").asInt());
final JsonNode forecastListNode = rootNode.get("list");
for (JsonNode forecastNode : forecastListNode) {
forecasts.add(parseWeatherForecast(forecastNode));
}
forecast.setWeatherForecasts(forecasts);
return forecast;
}
private WeatherForecast parseWeatherForecast(JsonNode rootNode) throws IOException {
final WeatherForecast weatherForecast = new WeatherForecast();
final JsonNode weatherArrayNode = rootNode.get("weather");
weatherForecast.setWeatherStates(parseWeatherStates(weatherArrayNode));
final JsonNode mainNode = rootNode.get("main");
weatherForecast.setTemperature(objectMapper.readValue(objectMapper.treeAsTokens(mainNode), Temperature.class));
weatherForecast.setAtmosphericPressure(objectMapper.readValue(objectMapper.treeAsTokens(mainNode), AtmosphericPressure.class));
weatherForecast.setHumidity(objectMapper.readValue(objectMapper.treeAsTokens(mainNode), Humidity.class));
weatherForecast.setClouds(objectMapper.readValue(objectMapper.treeAsTokens(rootNode.get("clouds")), Clouds.class));
weatherForecast.setWind(objectMapper.readValue(objectMapper.treeAsTokens(rootNode.get("wind")), Wind.class));
if (rootNode.has("rain")) {
weatherForecast.setRain(objectMapper.readValue(objectMapper.treeAsTokens(rootNode.get("rain")), Rain.class));
}
if (rootNode.has("snow")) {
weatherForecast.setSnow(objectMapper.readValue(objectMapper.treeAsTokens(rootNode.get("snow")), Snow.class));
}
final JsonNode sysNode = rootNode.get("sys");
if (sysNode != null) {
weatherForecast.setDayTime("d".equals(sysNode.get("pod").asText()) ? DayTime.DAY : DayTime.NIGHT);
}
final JsonNode visibilityNode = rootNode.get("visibility");
if (visibilityNode != null) {
weatherForecast.setVisibilityInMetres(visibilityNode.asDouble());
}
final JsonNode popNode = rootNode.get("pop");
if (popNode != null) {
weatherForecast.setProbabilityOfPrecipitation(popNode.asDouble());
}
weatherForecast.setForecastTime(parseDateTime(rootNode.get("dt")));
weatherForecast.setForecastTimeISO(rootNode.get("dt_txt").asText());
return weatherForecast;
}
}
@@ -0,0 +1,64 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.mapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.github.prominence.openweathermap.api.deserializer.GeocodingRecordDeserializer;
import com.github.prominence.openweathermap.api.deserializer.ZipCodeGeocodingDeserializer;
import com.github.prominence.openweathermap.api.model.geocoding.GeocodingRecord;
import com.github.prominence.openweathermap.api.model.geocoding.ZipCodeGeocodingRecord;
import java.util.List;
/**
* Official API response documentation: <a href="https://openweathermap.org/api/geocoding-api">https://openweathermap.org/api/geocoding-api</a>.
*/
public class GeocodingResponseMapper {
private static final ObjectMapper objectMapper = new ObjectMapper();
public GeocodingResponseMapper() {
final SimpleModule module = new SimpleModule();
module.addDeserializer(GeocodingRecord.class, new GeocodingRecordDeserializer());
module.addDeserializer(ZipCodeGeocodingRecord.class, new ZipCodeGeocodingDeserializer());
objectMapper.registerModule(module);
}
public List<GeocodingRecord> mapGeocodingResponse(String json) {
try {
return objectMapper.readValue(json, new TypeReference<List<GeocodingRecord>>() {});
} catch (JsonProcessingException e) {
throw new RuntimeException("Cannot parse ReverseGeocoding response.", e);
}
}
public ZipCodeGeocodingRecord mapZipCodeGeocodingResponse(String json) {
try {
return objectMapper.readValue(json, ZipCodeGeocodingRecord.class);
} catch (JsonProcessingException e) {
throw new RuntimeException("Cannot parse GeocodingInfo response.", e);
}
}
}
@@ -0,0 +1,143 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.mapper;
import com.fasterxml.jackson.databind.InjectableValues;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.github.prominence.openweathermap.api.deserializer.*;
import com.github.prominence.openweathermap.api.deserializer.forecast.hourly.HourlyForecastLocationDeserializer;
import com.github.prominence.openweathermap.api.deserializer.forecast.hourly.HourlyForecastRainDeserializer;
import com.github.prominence.openweathermap.api.deserializer.forecast.hourly.HourlyForecastSnowDeserializer;
import com.github.prominence.openweathermap.api.enums.UnitSystem;
import com.github.prominence.openweathermap.api.model.*;
import com.github.prominence.openweathermap.api.model.forecast.hourly.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Official API response documentation: <a href="https://openweathermap.org/api/hourly-forecast#JSON">https://openweathermap.org/api/hourly-forecast#JSON</a>.
*/
public class HourlyForecastResponseMapper extends AbstractMapper {
/**
* Instantiates a new forecast response mapper.
*
* @param unitSystem the unit system
*/
public HourlyForecastResponseMapper(UnitSystem unitSystem) {
objectMapper.setInjectableValues(new InjectableValues.Std().addValue("unitSystem", unitSystem != null ? unitSystem : UnitSystem.STANDARD));
final SimpleModule module = new SimpleModule();
module.addDeserializer(WeatherState.class, new WeatherStateDeserializer());
module.addDeserializer(Temperature.class, new TemperatureDeserializer());
module.addDeserializer(AtmosphericPressure.class, new AtmosphericPressureDeserializer());
module.addDeserializer(Wind.class, new WindDeserializer());
module.addDeserializer(Humidity.class, new HumidityDeserializer());
module.addDeserializer(Clouds.class, new CloudsDeserializer());
module.addDeserializer(Rain.class, new HourlyForecastRainDeserializer());
module.addDeserializer(Snow.class, new HourlyForecastSnowDeserializer());
module.addDeserializer(Location.class, new HourlyForecastLocationDeserializer());
objectMapper.registerModule(module);
}
/**
* Maps forecast response into java object.
*
* @param json the json string
* @return the forecast
*/
public HourlyForecast mapToForecast(String json) {
HourlyForecast hourlyForecast;
try {
final JsonNode root = objectMapper.readTree(json);
hourlyForecast = mapToForecast(root);
} catch (IOException e) {
throw new RuntimeException("Cannot parse Forecast response");
}
return hourlyForecast;
}
private HourlyForecast mapToForecast(JsonNode root) throws IOException {
final HourlyForecast hourlyForecast = new HourlyForecast();
hourlyForecast.setLocation(objectMapper.readValue(objectMapper.treeAsTokens(root.get("city")), Location.class));
final List<WeatherForecast> forecasts = new ArrayList<>(root.get("cnt").asInt());
final JsonNode forecastListNode = root.get("list");
for (JsonNode forecastNode : forecastListNode) {
forecasts.add(parseWeatherForecast(forecastNode));
}
hourlyForecast.setWeatherForecasts(forecasts);
return hourlyForecast;
}
private WeatherForecast parseWeatherForecast(JsonNode rootNode) throws IOException {
final WeatherForecast weatherForecast = new WeatherForecast();
final JsonNode weatherArrayNode = rootNode.get("weather");
if (weatherArrayNode != null && weatherArrayNode.isArray()) {
List<WeatherState> weatherStateList = new ArrayList<>();
for (JsonNode weatherNode : weatherArrayNode) {
weatherStateList.add(objectMapper.readValue(objectMapper.treeAsTokens(weatherNode), WeatherState.class));
}
weatherForecast.setWeatherStates(weatherStateList);
}
final JsonNode mainNode = rootNode.get("main");
weatherForecast.setTemperature(objectMapper.readValue(objectMapper.treeAsTokens(mainNode), Temperature.class));
weatherForecast.setAtmosphericPressure(objectMapper.readValue(objectMapper.treeAsTokens(mainNode), AtmosphericPressure.class));
weatherForecast.setHumidity(objectMapper.readValue(objectMapper.treeAsTokens(mainNode), Humidity.class));
weatherForecast.setClouds(objectMapper.readValue(objectMapper.treeAsTokens(rootNode.get("clouds")), Clouds.class));
weatherForecast.setWind(objectMapper.readValue(objectMapper.treeAsTokens(rootNode.get("wind")), Wind.class));
if (rootNode.has("rain")) {
weatherForecast.setRain(objectMapper.readValue(objectMapper.treeAsTokens(rootNode.get("rain")), Rain.class));
}
if (rootNode.has("snow")) {
weatherForecast.setSnow(objectMapper.readValue(objectMapper.treeAsTokens(rootNode.get("snow")), Snow.class));
}
final JsonNode sysNode = rootNode.get("sys");
if (sysNode != null) {
weatherForecast.setDayTime("d".equals(sysNode.get("pod").asText()) ? DayTime.DAY : DayTime.NIGHT);
}
if (rootNode.has("visibility")) {
weatherForecast.setAverageVisibilityInMetres(rootNode.get("visibility").asInt());
}
if (rootNode.has("pop")) {
weatherForecast.setProbabilityOfPrecipitation(rootNode.get("pop").asDouble());
}
weatherForecast.setForecastTime(parseDateTime(rootNode.get("dt")));
weatherForecast.setForecastTimeISO(rootNode.get("dt_txt").asText());
return weatherForecast;
}
}
@@ -0,0 +1,334 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
*
* 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.mapper;
import com.fasterxml.jackson.databind.InjectableValues;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.github.prominence.openweathermap.api.deserializer.*;
import com.github.prominence.openweathermap.api.deserializer.onecall.*;
import com.github.prominence.openweathermap.api.enums.UnitSystem;
import com.github.prominence.openweathermap.api.model.*;
import com.github.prominence.openweathermap.api.model.onecall.AtmosphericPressure;
import com.github.prominence.openweathermap.api.model.onecall.Temperature;
import com.github.prominence.openweathermap.api.model.onecall.*;
import com.github.prominence.openweathermap.api.model.onecall.current.*;
import com.github.prominence.openweathermap.api.model.onecall.historical.HistoricalWeather;
import com.github.prominence.openweathermap.api.model.onecall.historical.HistoricalWeatherData;
import com.github.prominence.openweathermap.api.model.onecall.historical.HourlyHistorical;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Official API response documentation:
* <ul>
* <li><a href="https://openweathermap.org/api/one-call-api#parameter">https://openweathermap.org/api/one-call-api#parameter</a></li>
* <li><a href="https://openweathermap.org/api/one-call-api#hist_parameter">https://openweathermap.org/api/one-call-api#hist_parameter</a></li>
* </ul>
*/
public class OneCallWeatherResponseMapper extends AbstractMapper {
/**
* Instantiates a new forecast response mapper.
*
* @param unitSystem the unit system
*/
public OneCallWeatherResponseMapper(UnitSystem unitSystem) {
objectMapper.setInjectableValues(new InjectableValues.Std().addValue("unitSystem", unitSystem != null ? unitSystem : UnitSystem.STANDARD));
final SimpleModule module = new SimpleModule();
module.addDeserializer(Coordinates.class, new CoordinatesDeserializer());
module.addDeserializer(AtmosphericPressure.class, new OneCallAtmosphericPressureDeserializer());
module.addDeserializer(Temperature.class, new OneCallTemperatureDeserializer());
module.addDeserializer(WeatherState.class, new WeatherStateDeserializer());
module.addDeserializer(Humidity.class, new HumidityDeserializer());
module.addDeserializer(Wind.class, new WindDeserializer());
module.addDeserializer(Clouds.class, new CloudsDeserializer());
module.addDeserializer(Rain.class, new OneCallRainDeserializer());
module.addDeserializer(Snow.class, new OneCallSnowDeserializer());
module.addDeserializer(DailyTemperature.class, new OneCallDailyTemperatureDeserializer());
module.addDeserializer(DailyRain.class, new OneCallDailyRainDeserializer());
module.addDeserializer(DailySnow.class, new OneCallDailySnowDeserializer());
module.addDeserializer(Alert.class, new AlertDeserializer());
objectMapper.registerModule(module);
}
/**
* Maps current weather data response into java object.
*
* @param json the json string
* @return the current data object
*/
public CurrentWeatherData mapToCurrent(String json) {
CurrentWeatherData currentData;
try {
final JsonNode root = objectMapper.readTree(json);
currentData = mapToCurrent(root);
} catch (IOException e) {
throw new RuntimeException("Cannot parse OneCall response", e);
}
return currentData;
}
/**
* Maps current weather data response into java object.
*
* @param json the json string
* @return the current data object
*/
public HistoricalWeatherData mapToHistorical(String json) {
HistoricalWeatherData historicalData;
try {
final JsonNode root = objectMapper.readTree(json);
historicalData = mapToHistorical(root);
} catch (IOException e) {
throw new RuntimeException("Cannot parse OneCall response");
}
return historicalData;
}
private CurrentWeatherData mapToCurrent(JsonNode rootNode) throws IOException {
final CurrentWeatherData currentData = new CurrentWeatherData();
currentData.setCoordinates(objectMapper.readValue(objectMapper.treeAsTokens(rootNode), Coordinates.class));
currentData.setTimezone(parseZoneId(rootNode.get("timezone")));
currentData.setTimezoneOffset(parseZoneOffset(rootNode.get("timezone_offset")));
currentData.setCurrent(parseCurrent(rootNode.get("current")));
currentData.setMinutelyList(parseMinutelyList(rootNode.get("minutely")));
currentData.setHourlyList(parseHourlyList(rootNode.get("hourly")));
currentData.setDailyList(parseDailyList(rootNode.get("daily")));
currentData.setAlerts(parseAlerts(rootNode.get("alerts")));
return currentData;
}
private Current parseCurrent(JsonNode currentNode) throws IOException {
if (currentNode == null) {
return null;
}
final Current current = new Current();
current.setForecastTime(parseDateTime(currentNode.get("dt")));
current.setSunriseTime(parseDateTime(currentNode.get("sunrise")));
current.setSunsetTime(parseDateTime(currentNode.get("sunset")));
current.setWeatherStates(parseWeatherStates(currentNode.get("weather")));
current.setTemperature(objectMapper.readValue(objectMapper.treeAsTokens(currentNode), Temperature.class));
current.setAtmosphericPressure(objectMapper.readValue(objectMapper.treeAsTokens(currentNode), AtmosphericPressure.class));
current.setHumidity(objectMapper.readValue(objectMapper.treeAsTokens(currentNode), Humidity.class));
current.setClouds(objectMapper.readValue(objectMapper.treeAsTokens(currentNode), Clouds.class));
current.setUvIndex(currentNode.get("uvi").asDouble());
final JsonNode visibilityNode = currentNode.get("visibility");
if (visibilityNode != null) {
current.setVisibilityInMetres(visibilityNode.asDouble());
}
current.setWind(objectMapper.readValue(objectMapper.treeAsTokens(currentNode), Wind.class));
current.setRain(objectMapper.readValue(objectMapper.treeAsTokens(currentNode), Rain.class));
current.setSnow(objectMapper.readValue(objectMapper.treeAsTokens(currentNode), Snow.class));
return current;
}
private List<Minutely> parseMinutelyList(JsonNode minutelyListNode) {
if (minutelyListNode == null) {
return null;
}
final List<Minutely> minutelyList = new ArrayList<>();
for (final JsonNode minutelyNode : minutelyListNode) {
minutelyList.add(Minutely.withValue(
parseDateTime(minutelyNode.get("dt")),
minutelyNode.get("precipitation").asDouble()
));
}
return minutelyList;
}
private List<Hourly> parseHourlyList(JsonNode hourlyListNode) throws IOException {
if (hourlyListNode == null) {
return null;
}
final List<Hourly> hourlyList = new ArrayList<>();
for (final JsonNode hourlyNode : hourlyListNode) {
final Hourly hourly = new Hourly();
hourly.setForecastTime(parseDateTime(hourlyNode.get("dt")));
hourly.setWeatherStates(parseWeatherStates(hourlyNode.get("weather")));
hourly.setTemperature(objectMapper.readValue(objectMapper.treeAsTokens(hourlyNode), Temperature.class));
hourly.setAtmosphericPressure(objectMapper.readValue(objectMapper.treeAsTokens(hourlyNode), AtmosphericPressure.class));
hourly.setHumidity(objectMapper.readValue(objectMapper.treeAsTokens(hourlyNode), Humidity.class));
hourly.setClouds(objectMapper.readValue(objectMapper.treeAsTokens(hourlyNode), Clouds.class));
final JsonNode uviNode = hourlyNode.get("uvi");
if (uviNode != null) {
hourly.setUvIndex(uviNode.asDouble());
}
final JsonNode visibilityNode = hourlyNode.get("visibility");
if (visibilityNode != null) {
hourly.setVisibilityInMetres(visibilityNode.asDouble());
}
hourly.setWind(objectMapper.readValue(objectMapper.treeAsTokens(hourlyNode), Wind.class));
final JsonNode popNode = hourlyNode.get("pop");
if (popNode != null) {
hourly.setProbabilityOfPrecipitation(popNode.asDouble());
}
hourly.setRain(objectMapper.readValue(objectMapper.treeAsTokens(hourlyNode), Rain.class));
hourly.setSnow(objectMapper.readValue(objectMapper.treeAsTokens(hourlyNode), Snow.class));
hourlyList.add(hourly);
}
return hourlyList;
}
private List<Daily> parseDailyList(JsonNode dailyListNode) throws IOException {
if (dailyListNode == null) {
return null;
}
final List<Daily> dailyList = new ArrayList<>();
for (final JsonNode dailyNode : dailyListNode) {
final Daily daily = new Daily();
daily.setForecastTime(parseDateTime(dailyNode.get("dt")));
daily.setSunriseTime(parseDateTime(dailyNode.get("sunrise")));
daily.setSunsetTime(parseDateTime(dailyNode.get("sunset")));
final JsonNode moonriseTimeNode = dailyNode.get("moonrise");
if (moonriseTimeNode != null) {
daily.setMoonriseTime(parseDateTime(moonriseTimeNode));
}
final JsonNode moonsetTimeNode = dailyNode.get("moonset");
if (moonsetTimeNode != null) {
daily.setMoonsetTime(parseDateTime(moonsetTimeNode));
}
final JsonNode moonPhaseNode = dailyNode.get("moon_phase");
if (moonPhaseNode != null) {
daily.setMoonPhase(new MoonPhase(moonPhaseNode.asDouble()));
}
daily.setWeatherStates(parseWeatherStates(dailyNode.get("weather")));
daily.setTemperature(objectMapper.readValue(objectMapper.treeAsTokens(dailyNode), DailyTemperature.class));
daily.setAtmosphericPressure(objectMapper.readValue(objectMapper.treeAsTokens(dailyNode), AtmosphericPressure.class));
daily.setHumidity(objectMapper.readValue(objectMapper.treeAsTokens(dailyNode), Humidity.class));
daily.setWind(objectMapper.readValue(objectMapper.treeAsTokens(dailyNode), Wind.class));
daily.setClouds(objectMapper.readValue(objectMapper.treeAsTokens(dailyNode), Clouds.class));
daily.setUvIndex(dailyNode.get("uvi").asDouble());
daily.setProbabilityOfPrecipitation(dailyNode.get("pop").asDouble());
daily.setRain(objectMapper.readValue(objectMapper.treeAsTokens(dailyNode), DailyRain.class));
daily.setSnow(objectMapper.readValue(objectMapper.treeAsTokens(dailyNode), DailySnow.class));
dailyList.add(daily);
}
return dailyList;
}
private List<Alert> parseAlerts(JsonNode alertsNode) throws IOException {
if (alertsNode == null || !alertsNode.isArray()) {
return null;
}
final List<Alert> alerts = new ArrayList<>();
for (final JsonNode alertNode : alertsNode) {
alerts.add(objectMapper.readValue(objectMapper.treeAsTokens(alertNode), Alert.class));
}
return alerts;
}
private HistoricalWeatherData mapToHistorical(JsonNode rootNode) throws IOException {
final HistoricalWeatherData historicalData = new HistoricalWeatherData();
historicalData.setCoordinates(Coordinates.of(rootNode.get("lat").asDouble(), rootNode.get("lon").asDouble()));
historicalData.setTimezone(parseZoneId(rootNode.get("timezone")));
historicalData.setTimezoneOffset(parseZoneOffset(rootNode.get("timezone_offset")));
historicalData.setHistoricalWeather(parseHistoricalWeather(rootNode.get("current")));
historicalData.setHourlyList(parseHourlyHistoricalList(rootNode.get("hourly")));
return historicalData;
}
private HistoricalWeather parseHistoricalWeather(JsonNode currentNode) throws IOException {
if (currentNode == null) {
return null;
}
final HistoricalWeather historicalWeather = new HistoricalWeather();
historicalWeather.setForecastTime(parseDateTime(currentNode.get("dt")));
historicalWeather.setSunriseTime(parseDateTime(currentNode.get("sunrise")));
historicalWeather.setSunsetTime(parseDateTime(currentNode.get("sunset")));
historicalWeather.setWeatherStates(parseWeatherStates(currentNode.get("weather")));
historicalWeather.setTemperature(objectMapper.readValue(objectMapper.treeAsTokens(currentNode), Temperature.class));
historicalWeather.setAtmosphericPressure(objectMapper.readValue(objectMapper.treeAsTokens(currentNode), AtmosphericPressure.class));
historicalWeather.setHumidity(objectMapper.readValue(objectMapper.treeAsTokens(currentNode), Humidity.class));
historicalWeather.setClouds(objectMapper.readValue(objectMapper.treeAsTokens(currentNode), Clouds.class));
final JsonNode uviNode = currentNode.get("uvi");
if (uviNode != null) {
historicalWeather.setUvIndex(uviNode.asDouble());
}
final JsonNode visibilityNode = currentNode.get("visibility");
if (visibilityNode != null) {
historicalWeather.setVisibilityInMetres(visibilityNode.asDouble());
}
historicalWeather.setWind(objectMapper.readValue(objectMapper.treeAsTokens(currentNode), Wind.class));
historicalWeather.setRain(objectMapper.readValue(objectMapper.treeAsTokens(currentNode), Rain.class));
historicalWeather.setSnow(objectMapper.readValue(objectMapper.treeAsTokens(currentNode), Snow.class));
return historicalWeather;
}
private List<HourlyHistorical> parseHourlyHistoricalList(JsonNode hourlyListNode) throws IOException {
if (hourlyListNode == null) {
return null;
}
final List<HourlyHistorical> hourlyList = new ArrayList<>();
for (final JsonNode hourlyNode : hourlyListNode) {
final HourlyHistorical hourly = new HourlyHistorical();
hourly.setForecastTime(parseDateTime(hourlyNode.get("dt")));
hourly.setWeatherStates(parseWeatherStates(hourlyNode.get("weather")));
hourly.setTemperature(objectMapper.readValue(objectMapper.treeAsTokens(hourlyNode), Temperature.class));
hourly.setAtmosphericPressure(objectMapper.readValue(objectMapper.treeAsTokens(hourlyNode), AtmosphericPressure.class));
hourly.setHumidity(objectMapper.readValue(objectMapper.treeAsTokens(hourlyNode), Humidity.class));
hourly.setClouds(objectMapper.readValue(objectMapper.treeAsTokens(hourlyNode), Clouds.class));
final JsonNode visibilityNode = hourlyNode.get("visibility");
if (visibilityNode != null) {
hourly.setVisibilityInMetres(visibilityNode.asDouble());
}
hourly.setWind(objectMapper.readValue(objectMapper.treeAsTokens(hourlyNode), Wind.class));
hourly.setRain(objectMapper.readValue(objectMapper.treeAsTokens(hourlyNode), Rain.class));
hourly.setSnow(objectMapper.readValue(objectMapper.treeAsTokens(hourlyNode), Snow.class));
hourlyList.add(hourly);
}
return hourlyList;
}
}
@@ -0,0 +1,72 @@
package com.github.prominence.openweathermap.api.mapper;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.github.prominence.openweathermap.api.deserializer.roadrisk.RoadRiskAlertDeserializer;
import com.github.prominence.openweathermap.api.deserializer.roadrisk.RoadRiskRoadDetailsDeserializer;
import com.github.prominence.openweathermap.api.deserializer.roadrisk.RoadRiskWeatherDeserializer;
import com.github.prominence.openweathermap.api.model.Coordinates;
import com.github.prominence.openweathermap.api.model.roadrisk.Alert;
import com.github.prominence.openweathermap.api.model.roadrisk.RoadDetails;
import com.github.prominence.openweathermap.api.model.roadrisk.RoadRiskRecord;
import com.github.prominence.openweathermap.api.model.roadrisk.Weather;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class RoadRiskResponseMapper extends AbstractMapper {
public RoadRiskResponseMapper() {
final SimpleModule module = new SimpleModule();
module.addDeserializer(Weather.class, new RoadRiskWeatherDeserializer());
module.addDeserializer(RoadDetails.class, new RoadRiskRoadDetailsDeserializer());
module.addDeserializer(Alert.class, new RoadRiskAlertDeserializer());
objectMapper.registerModule(module);
}
public List<RoadRiskRecord> mapToObjects(String jsonResponse) {
List<RoadRiskRecord> roadRiskRecords;
try {
final JsonNode root = objectMapper.readTree(jsonResponse);
roadRiskRecords = mapToObjects(root);
} catch (IOException e) {
throw new RuntimeException("Cannot parse SolarRadiation response", e);
}
return roadRiskRecords;
}
private List<RoadRiskRecord> mapToObjects(JsonNode rootNode) throws IOException {
List<RoadRiskRecord> roadRiskRecords = new ArrayList<>();
if (rootNode.isArray()) {
for (JsonNode recordNode : rootNode) {
RoadRiskRecord roadRiskRecord = new RoadRiskRecord();
roadRiskRecord.setForecastTime(parseDateTime(recordNode.get("dt")));
final JsonNode coordNode = recordNode.get("coord");
roadRiskRecord.setCoordinates(Coordinates.of(coordNode.get(0).asDouble(), coordNode.get(1).asDouble()));
roadRiskRecord.setWeather(objectMapper.readValue(objectMapper.treeAsTokens(recordNode.get("weather")), Weather.class));
if (recordNode.has("road")) {
roadRiskRecord.setRoadDetails(objectMapper.readValue(objectMapper.treeAsTokens(recordNode.get("road")), RoadDetails.class));
}
final JsonNode alertsNode = recordNode.get("alerts");
if (alertsNode != null && alertsNode.isArray()) {
List<Alert> alerts = new ArrayList<>();
for (JsonNode alertNode : alertsNode) {
alerts.add(objectMapper.readValue(objectMapper.treeAsTokens(alertNode), Alert.class));
}
roadRiskRecord.setAlerts(alerts);
}
roadRiskRecords.add(roadRiskRecord);
}
}
return roadRiskRecords;
}
}
@@ -0,0 +1,49 @@
package com.github.prominence.openweathermap.api.mapper;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.github.prominence.openweathermap.api.deserializer.CoordinatesDeserializer;
import com.github.prominence.openweathermap.api.deserializer.radiation.SolarRadiationRecordDeserializer;
import com.github.prominence.openweathermap.api.model.Coordinates;
import com.github.prominence.openweathermap.api.model.radiation.SolarRadiation;
import com.github.prominence.openweathermap.api.model.radiation.SolarRadiationRecord;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class SolarRadiationResponseMapper extends AbstractMapper {
public SolarRadiationResponseMapper() {
final SimpleModule module = new SimpleModule();
module.addDeserializer(SolarRadiationRecord.class, new SolarRadiationRecordDeserializer());
module.addDeserializer(Coordinates.class, new CoordinatesDeserializer());
objectMapper.registerModule(module);
}
public SolarRadiation mapToObject(String jsonResponse) {
SolarRadiation solarRadiation;
try {
final JsonNode root = objectMapper.readTree(jsonResponse);
solarRadiation = mapToObject(root);
} catch (IOException e) {
throw new RuntimeException("Cannot parse SolarRadiation response", e);
}
return solarRadiation;
}
private SolarRadiation mapToObject(JsonNode rootNode) throws IOException {
final SolarRadiation solarRadiation = new SolarRadiation();
solarRadiation.setCoordinates(objectMapper.readValue(objectMapper.treeAsTokens(rootNode.get("coord")), Coordinates.class));
final JsonNode listRecordsNode = rootNode.get("list");
List<SolarRadiationRecord> radiationRecords = new ArrayList<>();
for (JsonNode recordNode : listRecordsNode) {
radiationRecords.add(objectMapper.readValue(objectMapper.treeAsTokens(recordNode), SolarRadiationRecord.class));
}
solarRadiation.setSolarRadiationRecords(radiationRecords);
return solarRadiation;
}
}
@@ -48,6 +48,7 @@ public class AtmosphericPressure {
/**
* Static method for {@link AtmosphericPressure} creation with value checking.
*
* @param value atmospheric pressure value.
* @return instantiated {@link AtmosphericPressure} object.
*/
@@ -45,6 +45,7 @@ public class Clouds {
/**
* Static method for {@link Clouds} creation with value checking.
*
* @param value clouds percentage value.
* @return instantiated {@link Clouds} object.
*/
@@ -22,38 +22,40 @@
package com.github.prominence.openweathermap.api.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Objects;
/**
* Represents some location by its latitude and longitude.
*/
public class Coordinate {
public class Coordinates {
@JsonProperty("lat")
private double latitude;
@JsonProperty("lon")
private double longitude;
private Coordinate(double latitude, double longitude) {
this.latitude = latitude;
this.longitude = longitude;
private Coordinates() {
}
/**
* Method for {@link Coordinate} creation with correctness check.
* Method for {@link Coordinates} creation with correctness check.
*
* @param latitude latitude
* @param longitude longitude
* @return coordinate object.
*/
public static Coordinate withValues(double latitude, double longitude) {
if (latitude < -90 || latitude > 90) {
throw new IllegalArgumentException("Latitude value must be in the next range: [-90.0; 90.0].");
}
if (longitude < -180 || longitude > 180) {
throw new IllegalArgumentException("Longitude value must be in the next range: [-180.0; 180.0].");
}
return new Coordinate(latitude, longitude);
public static Coordinates of(double latitude, double longitude) {
final Coordinates coordinates = new Coordinates();
coordinates.setLatitude(latitude);
coordinates.setLongitude(longitude);
return coordinates;
}
/**
* Sets latitude with checks.
*
* @param latitude latitude value
*/
public void setLatitude(double latitude) {
@@ -65,6 +67,7 @@ public class Coordinate {
/**
* Sets longitude with checks.
*
* @param longitude longitude value
*/
public void setLongitude(double longitude) {
@@ -76,6 +79,7 @@ public class Coordinate {
/**
* Returns latitude.
*
* @return latitude
*/
public double getLatitude() {
@@ -84,6 +88,7 @@ public class Coordinate {
/**
* Returns longitude.
*
* @return longitude
*/
public double getLongitude() {
@@ -93,8 +98,8 @@ public class Coordinate {
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Coordinate)) return false;
Coordinate that = (Coordinate) o;
if (!(o instanceof Coordinates)) return false;
Coordinates that = (Coordinates) o;
return Double.compare(that.latitude, latitude) == 0 &&
Double.compare(that.longitude, longitude) == 0;
}
@@ -27,13 +27,13 @@ import java.util.Objects;
/**
* Represents coordinate rectangle by its bottom-left and top-right coordinates.
*/
public class CoordinateRectangle {
public class CoordinatesRectangle {
private final double longitudeLeft;
private final double latitudeBottom;
private final double longitudeRight;
private final double latitudeTop;
private CoordinateRectangle(double longitudeLeft, double latitudeBottom, double longitudeRight, double latitudeTop) {
private CoordinatesRectangle(double longitudeLeft, double latitudeBottom, double longitudeRight, double latitudeTop) {
this.longitudeLeft = longitudeLeft;
this.latitudeBottom = latitudeBottom;
this.longitudeRight = longitudeRight;
@@ -41,21 +41,21 @@ public class CoordinateRectangle {
}
/**
* Method for {@link CoordinateRectangle} creation with correctness check.
* Method for {@link CoordinatesRectangle} creation with correctness check.
* @param longitudeLeft left longitude
* @param latitudeBottom bottom latitude
* @param longitudeRight right longitude
* @param latitudeTop tip latitude
* @return coordinate rectangle object.
*/
public static CoordinateRectangle withValues(double longitudeLeft, double latitudeBottom, double longitudeRight, double latitudeTop) {
public static CoordinatesRectangle withValues(double longitudeLeft, double latitudeBottom, double longitudeRight, double latitudeTop) {
if (latitudeBottom < -90 || latitudeTop < -90 || latitudeBottom > 90 || latitudeTop > 90) {
throw new IllegalArgumentException("Latitude value must be in the next range: [-90.0; 90.0].");
}
if (longitudeLeft < -180 || longitudeRight < -180 || longitudeLeft > 180 || longitudeRight > 180) {
throw new IllegalArgumentException("Longitude value must be in the next range: [-180.0; 180.0].");
}
return new CoordinateRectangle(longitudeLeft, latitudeBottom, longitudeRight, latitudeTop);
return new CoordinatesRectangle(longitudeLeft, latitudeBottom, longitudeRight, latitudeTop);
}
/**
@@ -101,8 +101,8 @@ public class CoordinateRectangle {
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof CoordinateRectangle)) return false;
CoordinateRectangle rectangle = (CoordinateRectangle) o;
if (!(o instanceof CoordinatesRectangle)) return false;
CoordinatesRectangle rectangle = (CoordinatesRectangle) o;
return Double.compare(rectangle.longitudeLeft, longitudeLeft) == 0 &&
Double.compare(rectangle.latitudeBottom, latitudeBottom) == 0 &&
Double.compare(rectangle.longitudeRight, longitudeRight) == 0 &&
@@ -187,14 +187,14 @@ public class CoordinateRectangle {
}
/**
* Builds {@link CoordinateRectangle} object with correctness check.
* @return {@link CoordinateRectangle} built object.
* Builds {@link CoordinatesRectangle} object with correctness check.
* @return {@link CoordinatesRectangle} built object.
*/
public CoordinateRectangle build() {
public CoordinatesRectangle build() {
if (longitudeLeft == null || latitudeBottom == null || longitudeRight == null || latitudeTop == null) {
throw new IllegalStateException("Not all fields were set.");
}
return new CoordinateRectangle(longitudeLeft, latitudeBottom, longitudeRight, latitudeTop);
return new CoordinatesRectangle(longitudeLeft, latitudeBottom, longitudeRight, latitudeTop);
}
}
}
@@ -45,6 +45,7 @@ public class Humidity {
/**
* Creates {@link Humidity} object with correctness check.
*
* @param value humidity
* @return created {@link Humidity} object
*/
@@ -41,6 +41,7 @@ public class Temperature {
/**
* Creates {@link Temperature} object with correctness check.
*
* @param value temperature value
* @param unit temperature unit
* @return temperature object
@@ -54,6 +55,7 @@ public class Temperature {
/**
* Returns temperature value.
*
* @return value
*/
public double getValue() {
@@ -62,6 +64,7 @@ public class Temperature {
/**
* Sets temperature value.
*
* @param value temperature
*/
public void setValue(double value) {
@@ -70,6 +73,7 @@ public class Temperature {
/**
* Returns maximal temperature value.
*
* @return maximal temperature value
*/
public Double getMaxTemperature() {
@@ -78,6 +82,7 @@ public class Temperature {
/**
* Sets maximal temperature value.
*
* @param maxTemperature maximal temperature
*/
public void setMaxTemperature(Double maxTemperature) {
@@ -86,6 +91,7 @@ public class Temperature {
/**
* Returns minimal temperature value.
*
* @return minimal temperature value
*/
public Double getMinTemperature() {
@@ -94,6 +100,7 @@ public class Temperature {
/**
* Sets minimal temperature value.
*
* @param minTemperature minimal temperature
*/
public void setMinTemperature(Double minTemperature) {
@@ -102,6 +109,7 @@ public class Temperature {
/**
* Returns 'feels like' temperature value.
*
* @return 'feels like' temperature value
*/
public Double getFeelsLike() {
@@ -110,6 +118,7 @@ public class Temperature {
/**
* Sets 'feels like' temperature value.
*
* @param feelsLike 'feels like' temperature
*/
public void setFeelsLike(Double feelsLike) {
@@ -118,6 +127,7 @@ public class Temperature {
/**
* Returns temperature unit.
*
* @return unit
*/
public String getUnit() {
@@ -126,6 +136,7 @@ public class Temperature {
/**
* Sets temperature unit with correctness check.
*
* @param unit temperature unit
*/
public void setUnit(String unit) {
@@ -138,8 +149,7 @@ public class Temperature {
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Temperature)) return false;
Temperature that = (Temperature) o;
if (!(o instanceof Temperature that)) return false;
return Double.compare(that.value, value) == 0 &&
Objects.equals(maxTemperature, that.maxTemperature) &&
Objects.equals(minTemperature, that.minTemperature) &&
@@ -154,7 +164,7 @@ public class Temperature {
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
final StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("Temperature: ");
stringBuilder.append(value);
stringBuilder.append(' ');
@@ -0,0 +1,136 @@
/*
* 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 + ").";
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Alexey Zinchenko
* Copyright (c) 2022 Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -20,7 +20,7 @@
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model.weather;
package com.github.prominence.openweathermap.api.model;
import java.util.Objects;
@@ -46,6 +46,7 @@ public class Wind {
/**
* Creates {@link Wind} object with correctness check.
*
* @param speed the speed
* @param unit the unitSystem
* @return wind object
@@ -83,6 +84,7 @@ public class Wind {
/**
* Gets gust value.
*
* @return the gust
*/
public Double getGust() {
@@ -91,6 +93,7 @@ public class Wind {
/**
* Sets gust value.
*
* @param gust the gust.
*/
public void setGust(double gust) {

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