52 Commits

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

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

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

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

* New mapping approach - Code review
- Add more tests

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-17 01:05:17 +03:00
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 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
406 changed files with 17896 additions and 17471 deletions
+13
View File
@@ -0,0 +1,13 @@
container:
image: gradle:jdk8
testCoverage_task:
gradle_cache:
folder: ~/.gradle/caches
testCoverage_script: gradle jacocoTestReport && bash <(curl -s https://codecov.io/bash)
cleanup_before_cache_script:
- rm -rf ~/.gradle/caches/$GRADLE_VERSION/
- rm -rf ~/.gradle/caches/transforms-1
- rm -rf ~/.gradle/caches/journal-1
- rm -rf ~/.gradle/caches/jars-3/*/buildSrc.jar
- find ~/.gradle/caches/ -name "*.lock" -type f -delete
-31
View File
@@ -1,31 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: "[BUG] Change me"
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.
-10
View File
@@ -1,10 +0,0 @@
---
name: Custom issue template
about: Describe this issue template's purpose here.
title: ''
labels: ''
assignees: ''
---
-20
View File
@@ -1,20 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: "[FEATURE] Change me"
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
+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)
-128
View File
@@ -1,128 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
alexey.zinchenko@protonmail.com.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.
+61 -15
View File
@@ -1,4 +1,4 @@
# OpenWeatherMap Java API [![Build Status][ci-shield]][ci-link] [![codecov][codecov-shield]][codecov-link]
# OpenWeatherMap Java API [![Build Status][ci-shield]][ci-link] [![codecov][codecov-shield]][codecov-link] [![FOSSA Status][FOSSA-shield]][FOSSA-link]
Java API for OpenWeatherMap services.
### Implemented features:
@@ -7,6 +7,14 @@ Free:
* 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
@@ -14,29 +22,66 @@ Other:
### Will be implemented later:
Free:
* Geocoding API
* Weather Stations
* Weather Triggers
Paid:
* Daily Forecast 16 days
* Hourly Forecast 4 days
* probably others...
* Bulk Downloading
* Historical Weather API
* Historical Weather API 40 years by timestamp
* Historical Weather API 40 years full archive
* History Bulk
* History Forecast Bulk
* Statistical Weather Data API
* Accumulated Parameters
* Historical Weather Data by State for all ZIP codes, USA
### Maven coordinates:
```xml
<dependency>
<groupId>com.github.prominence</groupId>
<artifactId>openweathermap-api</artifactId>
<version>2.4.2</version>
<groupId>com.github.prominence</groupId>
<artifactId>openweathermap-api</artifactId>
<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
implementation 'com.github.prominence:openweathermap-api:2.4.2'
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
@@ -49,16 +94,17 @@ implementation 'com.github.prominence:openweathermap-api:2.4.2'
* [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 - 2.4.0](docs/Release_2.4.0.md)
* [OpenWeatherMap Java API - 2.4.1](docs/Release_2.4.1.md)
* [OpenWeatherMap Java API - 2.4.2](docs/Release_2.4.2.md)
* [OpenWeatherMap Java API - SNAPSHOT](docs/SNAPSHOT.md)
### License
MIT
[ci-shield]: https://travis-ci.org/Prominence/openweathermap-java-api.svg?branch=master
[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/master/graph/badge.svg
[codecov-shield]: https://codecov.io/gh/Prominence/openweathermap-java-api/branch/dev/graph/badge.svg
[codecov-link]: https://codecov.io/gh/Prominence/openweathermap-java-api
[FOSSA-shield]: https://app.fossa.com/api/projects/git%2Bgithub.com%2FProminence%2Fopenweathermap-java-api.svg?type=shield
[FOSSA-link]: https://app.fossa.com/projects/git%2Bgithub.com%2FProminence%2Fopenweathermap-java-api?ref=badge_shield
+118
View File
@@ -0,0 +1,118 @@
plugins {
id 'java-library'
id 'maven-publish'
id 'signing'
id 'jacoco'
id 'io.freefair.lombok' version '6.5.0.3'
}
repositories {
mavenCentral()
}
dependencies {
implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.4'
implementation 'org.slf4j:slf4j-api:1.7.36'
testImplementation 'org.junit.platform:junit-platform-runner:1.9.0'
testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.9.0'
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.9.0'
testImplementation 'ch.qos.logback:logback-classic:1.2.11'
testImplementation 'commons-io:commons-io:2.11.0'
testImplementation 'org.mockito:mockito-core:4.8.0'
}
group = 'com.github.prominence'
version = '3.0.0-SNAPSHOT'
description = 'Java OpenWeatherMap API'
configure([tasks.compileJava]) {
sourceCompatibility = 8
}
ext {
isReleaseVersion = !version.endsWith("SNAPSHOT")
}
java {
withSourcesJar()
withJavadocJar()
}
test {
useJUnitPlatform()
}
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
pom {
name = 'Java OpenWeatherMap API'
description = 'Java API for OpenWeatherMap services.'
url = 'https://github.com/Prominence/openweathermap-java-api'
licenses {
license {
name = 'MIT License'
url = 'https://www.opensource.org/licenses/mit-license.php'
}
}
developers {
developer {
id = 'Prominence'
name = 'Alexey Zinchenko'
email = 'alexey.zinchenko@protonmail.com'
url = 'https://github.com/prominence'
}
}
scm {
connection = 'scm:git:git://github.com/Prominence/openweathermap-java-api.git'
developerConnection = 'scm:git:git@github.com:prominence/openweathermap-java-api.git'
url = 'https://github.com/Prominence/openweathermap-java-api'
}
issueManagement {
url = 'https://github.com/Prominence/openweathermap-java-api/issues'
system = 'GitHub Issues'
}
}
}
}
repositories {
maven {
credentials {
username = project.findProperty('ossrhUsername')
password = project.findProperty('ossrhPassword')
}
url = isReleaseVersion ?
'https://oss.sonatype.org/service/local/staging/deploy/maven2/' :
'https://oss.sonatype.org/content/repositories/snapshots/'
}
}
}
signing {
sign publishing.publications.mavenJava
}
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
tasks.withType(GenerateModuleMetadata) {
enabled = false
}
jacocoTestReport {
dependsOn test // tests are required to run before generating the report
reports {
csv.required = false
xml.required = true
xml.outputLocation = layout.buildDirectory.file('reports/jacoco/report.xml')
html.outputLocation = layout.buildDirectory.dir('jacocoHtml')
}
}
+1 -1
View File
@@ -15,7 +15,7 @@
### Gradle coordinates:
```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:
+1 -1
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:
+1 -1
View File
@@ -15,7 +15,7 @@
### Gradle coordinates:
```groovy
compile('com.github.prominence:openweathermap-api:2.0.1')
implementation 'com.github.prominence:openweathermap-api:2.0.1'
```
### How to use:
+1 -1
View File
@@ -16,7 +16,7 @@
### Gradle coordinates:
```groovy
compile('com.github.prominence:openweathermap-api:2.1.0')
implementation 'com.github.prominence:openweathermap-api:2.1.0'
```
### How to use:
+1 -1
View File
@@ -16,7 +16,7 @@
### Gradle coordinates:
```groovy
compile('com.github.prominence:openweathermap-api:2.1.1')
implementation 'com.github.prominence:openweathermap-api:2.1.1'
```
### How to use:
+1 -1
View File
@@ -17,7 +17,7 @@
### Gradle coordinates:
```groovy
compile('com.github.prominence:openweathermap-api:2.2.0')
implementation 'com.github.prominence:openweathermap-api:2.2.0'
```
### How to use:
+1 -1
View File
@@ -21,7 +21,7 @@ Other:
### Gradle coordinates:
```groovy
compile('com.github.prominence:openweathermap-api:2.3.0')
implementation 'com.github.prominence:openweathermap-api:2.3.0'
```
### How to use:
-566
View File
@@ -1,566 +0,0 @@
### Implemented features:
* Current weather data
* 5 day / 3-hour forecast
* One Call API
* One Call 3 API
* Air Pollution
Other:
* Request timeout settings
### Maven coordinates:
```xml
<dependency>
<groupId>com.github.prominence</groupId>
<artifactId>openweathermap-api</artifactId>
<version>2.4.1</version>
</dependency>
```
### Gradle coordinates:
```groovy
compile('com.github.prominence:openweathermap-api:2.4.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()`
* `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 3 API
Examples:
```java
final CurrentWeatherData currentWeatherData = getClient()
.oneCall3()
.current()
.byCoordinate(Coordinate.of(53.54, 27.34))
.language(Language.ENGLISH)
.unitSystem(UnitSystem.METRIC)
.retrieve()
.asJava();
```
#### One Call API (Deprecated)
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.4.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*)
-566
View File
@@ -1,566 +0,0 @@
### Implemented features:
* Current weather data
* 5 day / 3-hour forecast
* One Call API
* One Call 3 API
* Air Pollution
Other:
* Request timeout settings
### Maven coordinates:
```xml
<dependency>
<groupId>com.github.prominence</groupId>
<artifactId>openweathermap-api</artifactId>
<version>2.4.2</version>
</dependency>
```
### Gradle coordinates:
```groovy
compile('com.github.prominence:openweathermap-api:2.4.2')
```
### 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 3 API
Examples:
```java
final CurrentWeatherData currentWeatherData = getClient()
.oneCall3()
.current()
.byCoordinate(Coordinate.of(53.54, 27.34))
.language(Language.ENGLISH)
.unitSystem(UnitSystem.METRIC)
.retrieve()
.asJava();
```
#### One Call API (Deprecated)
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.4.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*)
+50 -27
View File
@@ -1,9 +1,13 @@
### Implemented features:
* Current weather data
* 5 day / 3-hour forecast
* Hourly forecast
* One Call API
* One Call 3 API
* Daily forecast
* Solar Radiation API
* 5 day / 3-hour forecast
* Road Risk API
* Air Pollution
* Geocoding API
Other:
@@ -13,16 +17,48 @@ Other:
```xml
<dependency>
<groupId>com.github.prominence</groupId>
<artifactId>openweathermap-api</artifactId>
<version>2.4.0</version>
<groupId>com.github.prominence</groupId>
<artifactId>openweathermap-api</artifactId>
<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.4.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()
}
}
...
}
```
### How to use:
@@ -128,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:
@@ -187,7 +223,7 @@ You are able to set preferable options(via chain methods) and execute appropriat
| 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. |
@@ -196,7 +232,7 @@ 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 |
|-------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
@@ -213,20 +249,7 @@ 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 3 API
Examples:
```java
final CurrentWeatherData currentWeatherData = getClient()
.oneCall3()
.current()
.byCoordinate(Coordinate.of(53.54, 27.34))
.language(Language.ENGLISH)
.unitSystem(UnitSystem.METRIC)
.retrieve()
.asJava();
```
#### One Call API (Deprecated)
#### One Call API
Examples:
```java
final CurrentWeatherData currentWeatherData = openWeatherClient
@@ -323,7 +346,7 @@ You are able to set preferable options(via chain methods) and execute appropriat
| Method | Description |
|-------------------------------|--------------------------------------------------------------------------------|
| `getCoordinate()` | Returns `Coordinate` object. Available fields: `latitude`, `longitude`. |
| `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. |
@@ -411,7 +434,7 @@ You are able to set preferable options(via chain methods) and execute appropriat
| Method | Description |
|-------------------------------|-------------------------------------------------------------------------------|
| `getCoordinate()` | Returns `Coordinate` object. Available fields: `latitude`, `longitude`. |
| `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. |
@@ -474,7 +497,7 @@ final AirPollutionDetails airPollutionDetails = openWeatherClient
| Method | Description |
|-------------------------------|---------------------------------------------------------------------------|
| `getCoordinate()` | Returns `Coordinate` object. Available fields: `latitude`, `longitude`. |
| `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):
@@ -560,7 +583,7 @@ final AirPollutionDetails airPollutionDetails = openWeatherClient
| Unit.STANDARD_SYSTEM | Kelvin, meter/sec, hPa, mm(rain, snow). |
### Dependencies
* com.fasterxml.jackson.core:jackson-databind:2.13.4.2
* 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
+5
View File
@@ -0,0 +1,5 @@
# This file is generated by the 'io.freefair.lombok' Gradle plugin
config.stopBubbling = true
lombok.addSuppressWarnings = true
lombok.addLombokGeneratedAnnotation = true
lombok.nonNull.exceptionType = IllegalArgumentException
-185
View File
@@ -1,185 +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.4.2</version>
<packaging>jar</packaging>
<name>Java OpenWeatherMap API</name>
<description>Java API for OpenWeatherMap services.</description>
<url>https://github.com/Prominence/openweathermap-java-api</url>
<scm>
<url>https://github.com/Prominence/openweathermap-java-api</url>
<connection>scm:git:git://github.com/Prominence/openweathermap-java-api.git</connection>
<developerConnection>scm:git:git@github.com:prominence/openweathermap-java-api.git</developerConnection>
</scm>
<issueManagement>
<url>https://github.com/Prominence/openweathermap-java-api/issues</url>
<system>GitHub Issues</system>
</issueManagement>
<licenses>
<license>
<name>MIT License</name>
<url>https://www.opensource.org/licenses/mit-license.php</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<email>alexey.zinchenko@protonmail.com</email>
<name>Alexey Zinchenko</name>
<url>https://github.com/prominence</url>
<id>Prominence</id>
</developer>
</developers>
<distributionManagement>
<snapshotRepository>
<id>ossrh</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
<repository>
<id>ossrh</id>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
</distributionManagement>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<excludes>
<exclude>**/test/*</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.sonatype.central</groupId>
<artifactId>central-publishing-maven-plugin</artifactId>
<version>0.9.0</version>
<extensions>true</extensions>
<configuration>
<publishingServerId>central</publishingServerId>
</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.3.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>3.0.1</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.7</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.4.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-runner</artifactId>
<version>1.8.2</version>
</dependency>
</dependencies>
</project>
+1
View File
@@ -0,0 +1 @@
rootProject.name = 'openweathermap-api'
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Alexey Zinchenko
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -23,14 +23,26 @@
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.context.ApiConfiguration;
import com.github.prominence.openweathermap.api.context.ApiConfigurationHolder;
import com.github.prominence.openweathermap.api.request.RequestSettings;
import com.github.prominence.openweathermap.api.request.air.pollution.AirPollutionRequester;
import com.github.prominence.openweathermap.api.request.forecast.climatic.ClimaticForecastRequester;
import com.github.prominence.openweathermap.api.request.forecast.daily.DailyForecastRequester;
import com.github.prominence.openweathermap.api.request.forecast.free.FiveDayThreeHourStepForecastRequester;
import com.github.prominence.openweathermap.api.request.forecast.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 lombok.NonNull;
import static com.github.prominence.openweathermap.api.enums.SubscriptionPlan.ALL;
import static com.github.prominence.openweathermap.api.enums.SubscriptionPlan.DEVELOPER;
import static com.github.prominence.openweathermap.api.enums.SubscriptionPlan.ENTERPRISE;
import static com.github.prominence.openweathermap.api.enums.SubscriptionPlan.PAID;
import static com.github.prominence.openweathermap.api.enums.SubscriptionPlan.PROFESSIONAL;
import static com.github.prominence.openweathermap.api.enums.SubscriptionPlan.SPECIAL;
/**
@@ -38,79 +50,119 @@ import static com.github.prominence.openweathermap.api.enums.SubscriptionPlan.SP
* Requires API key for usage. More info on the website <a href="https://openweathermap.org/api">https://openweathermap.org/api</a>.
*/
public class OpenWeatherMapClient {
private final String apiKey;
private final TimeoutSettings timeoutSettings = new TimeoutSettings();
private final ApiConfiguration apiConfiguration;
public OpenWeatherMapClient() {
this(ApiConfigurationHolder.getConfiguration());
}
/**
* Created OpenWeatherMap client object.
* @param apiKey API key obtained on <a href="https://home.openweathermap.org/api_keys">OpenWeatherMap site</a>.
*
* @param apiConfiguration configuration options.
*/
public OpenWeatherMapClient(String apiKey) {
this.apiKey = apiKey;
}
public void setConnectionTimeout(int connectionTimeout) {
timeoutSettings.setConnectionTimeout(connectionTimeout);
}
public void setReadTimeout(int readTimeout) {
timeoutSettings.setReadTimeout(readTimeout);
public OpenWeatherMapClient(@NonNull ApiConfiguration apiConfiguration) {
this.apiConfiguration = apiConfiguration;
}
/**
* 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 CurrentWeatherRequester(new RequestSettings(apiKey, timeoutSettings));
return new CurrentWeatherRequester(getRequestSettings());
}
/**
* 5 Day / 3 Hour Forecast <a href="https://openweathermap.org/forecast5">API</a>.
* @return requester for retrieving 5 day/3-hour weather forecast information.
* 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 = ALL)
public FiveDayThreeHourStepForecastRequester forecast5Day3HourStep() {
return new FiveDayThreeHourStepForecastRequester(new RequestSettings(apiKey, timeoutSettings));
@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)
@Deprecated
public OneCallWeatherRequester oneCall() {
return new OneCallWeatherRequester(new RequestSettings(apiKey, timeoutSettings));
return new OneCallWeatherRequester(getRequestSettings());
}
/**
* One Call 3 API <a href="https://openweathermap.org/api/one-call-3">API</a>.
* Includes a weather summary statement in addition to the information provided by {@link #oneCall()}
* Daily forecast <a href="https://openweathermap.org/api/hourly-forecast">API</a>.
*
* Please note, that One Call API 3.0 is included in the "One Call by Call" subscription only.
* This separate subscription includes 1,000 calls/day for free and allows you to pay only for the number of API calls made to this product.
* Please note, that you do not need to subscribe to any other OpenWeather subscription plans to get access to the One Call API 3.0.
* Please find more details on the pricing page and FAQ or ask Ulla, OpenWeather AI assistant.
* @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 one call weather information for the OneCall 3 API.
* @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 OneCallWeatherRequester oneCall3() {
RequestSettings requestSettings = new RequestSettings(apiKey, timeoutSettings);
requestSettings.setUseApi3();
return new OneCallWeatherRequester(requestSettings);
public SolarRadiationRequester solarRadiation() {
return new SolarRadiationRequester(getRequestSettings());
}
/**
* 5 Day / 3 Hour Forecast <a href="https://openweathermap.org/forecast5">API</a>.
*
* @return requester for retrieving 5 day/3-hour weather forecast information.
*/
@SubscriptionAvailability(plans = ALL)
public FiveDayThreeHourStepForecastRequester forecast5Day3HourStep() {
return new FiveDayThreeHourStepForecastRequester(getRequestSettings());
}
/**
* Road Risk <a href="https://openweathermap.org/api/road-risk">API</a>.
*
* @return requester for retrieving road risk information.
*/
@SubscriptionAvailability(plans = SPECIAL)
public RoadRiskRequester roadRisk() {
return new RoadRiskRequester(getRequestSettings());
}
/**
* Air Pollution <a href="https://openweathermap.org/api/air-pollution">API</a>.
* Air Pollution API provides current, forecast and historical air pollution data for any coordinates on the globe.
*
* @return requester for air pollution information retrieval.
*/
@SubscriptionAvailability(plans = ALL)
public AirPollutionRequester airPollution() {
return new AirPollutionRequester(new RequestSettings(apiKey, timeoutSettings));
return new AirPollutionRequester(getRequestSettings());
}
@SubscriptionAvailability(plans = ALL)
public GeocodingRequester geocoding() {
return new GeocodingRequester(getRequestSettings());
}
private RequestSettings getRequestSettings() {
return new RequestSettings(apiConfiguration);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Alexey Zinchenko
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -22,9 +22,12 @@
package com.github.prominence.openweathermap.api.conf;
public class TimeoutSettings {
private Integer connectionTimeout;
private Integer readTimeout;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode
public final class TimeoutSettings {
private final Integer connectionTimeout;
private final Integer readTimeout;
public TimeoutSettings() {
this(2000, 2000);
@@ -44,15 +47,7 @@ public class TimeoutSettings {
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,121 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.context;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.github.prominence.openweathermap.api.conf.TimeoutSettings;
import com.github.prominence.openweathermap.api.core.net.HttpClient;
import com.github.prominence.openweathermap.api.core.net.HttpURLConnectionBasedHttpClient;
import com.github.prominence.openweathermap.api.enums.ApiVariant;
import lombok.Getter;
import lombok.NonNull;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
@Getter
public class ApiConfiguration {
@NonNull
private final String apiKey;
@NonNull
private final Map<ApiVariant, String> baseUrls;
@NonNull
private final HttpClient httpClient;
@NonNull
private final TimeoutSettings defaultTimeoutSettings;
private final ObjectReader objectReader;
private final ObjectWriter objectWriter;
private ApiConfiguration(String apiKey, Map<ApiVariant, String> baseUrls, HttpClient httpClient,
ObjectMapper objectMapper, TimeoutSettings defaultTimeoutSettings) {
this.apiKey = apiKey;
this.baseUrls = Collections.unmodifiableMap(baseUrls);
this.httpClient = httpClient;
this.defaultTimeoutSettings = defaultTimeoutSettings;
this.objectReader = objectMapper.reader();
this.objectWriter = objectMapper.writer();
}
public static ApiConfigurationBuilder builder() {
return new ApiConfigurationBuilder();
}
public static class ApiConfigurationBuilder {
private String apiKey;
private Map<ApiVariant, String> baseUrls;
private HttpClient httpClient = new HttpURLConnectionBasedHttpClient();
private TimeoutSettings defaultTimeoutSettings = new TimeoutSettings();
private ObjectMapper objectMapper = new ObjectMapper();
public ApiConfigurationBuilder() {
baseUrls = Arrays.stream(ApiVariant.values())
.collect(Collectors.toMap(Function.identity(), ApiVariant::getBaseUrl));
}
public ApiConfigurationBuilder apiKey(@NonNull String apiKey) {
this.apiKey = apiKey;
return this;
}
public ApiConfigurationBuilder baseUrls(@NonNull Map<ApiVariant, String> baseUrls) {
final List<ApiVariant> variants = Arrays.stream(ApiVariant.values()).collect(Collectors.toList());
if (!baseUrls.keySet().containsAll(variants)) {
throw new IllegalArgumentException("Not all API variants were found: " + baseUrls.keySet() + " , expected: " + variants);
}
this.baseUrls = new HashMap<>(baseUrls);
return this;
}
public ApiConfigurationBuilder httpClient(@NonNull HttpClient httpClient) {
this.httpClient = httpClient;
return this;
}
public ApiConfigurationBuilder objectMapper(@NonNull ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
return this;
}
public ApiConfigurationBuilder defaultTimeoutSettings(@NonNull TimeoutSettings defaultTimeoutSettings) {
this.defaultTimeoutSettings = new TimeoutSettings(defaultTimeoutSettings);
return this;
}
public ApiConfiguration build() {
return new ApiConfiguration(apiKey, baseUrls, httpClient, objectMapper, defaultTimeoutSettings);
}
public String toString() {
return "ApiConfiguration.ApiConfigurationBuilder(apiKey=" + this.apiKey + ")";
}
}
}
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.context;
import lombok.NonNull;
public class ApiConfigurationHolder {
private static ApiConfiguration configuration = ApiConfiguration.builder()
.apiKey(System.getenv("OPENWEATHER_API_KEY"))
.build();
public static ApiConfiguration getConfiguration() {
return configuration;
}
public static void setConfiguration(@NonNull ApiConfiguration configuration) {
ApiConfigurationHolder.configuration = configuration;
}
}
@@ -0,0 +1,32 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.core.net;
import com.github.prominence.openweathermap.api.conf.TimeoutSettings;
public interface HttpClient {
void setTimeoutSettings(TimeoutSettings timeoutSettings);
String executeGetRequest(String url);
String executePostRequest(String url, String body);
}
@@ -0,0 +1,151 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.core.net;
import com.github.prominence.openweathermap.api.conf.TimeoutSettings;
import com.github.prominence.openweathermap.api.exception.InvalidAuthTokenException;
import com.github.prominence.openweathermap.api.exception.NoDataFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Optional;
import java.util.stream.Collectors;
public class HttpURLConnectionBasedHttpClient implements HttpClient {
private static final Logger logger = LoggerFactory.getLogger(HttpURLConnectionBasedHttpClient.class);
private TimeoutSettings timeoutSettings;
@Override
public void setTimeoutSettings(TimeoutSettings timeoutSettings) {
this.timeoutSettings = timeoutSettings;
}
@Override
public String executeGetRequest(String url) {
return doExecute(url, RequestExecutor.Method.GET, null);
}
private String doExecute(String url, RequestExecutor.Method method, String body) {
InputStream resultStream = null;
try {
HttpURLConnection connection = getConnection(url);
configureTimeouts(connection);
configureConnection(connection, method, body);
resultStream = evaluateResponse(connection);
logger.debug("Executing OpenWeatherMap API request: " + url);
return convertInputStreamToString(resultStream);
} catch (IllegalStateException | IOException ex) {
logger.error("An error occurred during OpenWeatherMap API response parsing: ", ex);
throw new NoDataFoundException(ex);
} finally {
closeQuietly(resultStream);
}
}
HttpURLConnection getConnection(String url) throws IOException {
return (HttpURLConnection) new URL(url).openConnection();
}
private void closeQuietly(InputStream resultStream) {
if (resultStream != null) {
try {
resultStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
private InputStream evaluateResponse(HttpURLConnection connection) throws IOException {
final int responseCode = connection.getResponseCode();
switch (responseCode) {
case HttpURLConnection.HTTP_OK:
return connection.getInputStream();
case HttpURLConnection.HTTP_UNAUTHORIZED:
throw new InvalidAuthTokenException();
case HttpURLConnection.HTTP_NOT_FOUND:
case HttpURLConnection.HTTP_BAD_REQUEST:
throw new NoDataFoundException();
default:
throw new IllegalStateException("Unexpected value: " + responseCode);
}
}
private void configureTimeouts(HttpURLConnection connection) {
Optional.ofNullable(timeoutSettings)
.ifPresent(ts -> {
Optional.ofNullable(ts.getConnectionTimeout())
.ifPresent(connection::setConnectTimeout);
Optional.ofNullable(ts.getReadTimeout())
.ifPresent(connection::setReadTimeout);
});
}
private void configureConnection(HttpURLConnection connection, RequestExecutor.Method method, String body) throws IOException {
connection.setRequestMethod(method.name());
connection.setRequestProperty("Content-Type", "application/json; utf-8");
connection.setRequestProperty("Accept", "application/json");
addOptionalBodyContent(connection, body);
}
@Override
public String executePostRequest(String url, String body) {
return doExecute(url, RequestExecutor.Method.POST, body);
}
private void addOptionalBodyContent(HttpURLConnection connection, String body) throws IOException {
if (body != null) {
connection.setDoOutput(true);
try (OutputStream os = connection.getOutputStream()) {
byte[] input = body.getBytes(StandardCharsets.UTF_8);
os.write(input, 0, input.length);
}
}
}
/**
* Reads the input stream line-by-line and returns its content in <code>String</code> representation.
*
* @param inputStream input stream to convert.
* @return converted <code>InputStream</code> content.
* @throws IllegalArgumentException in case if input stream is unable to be read.
*/
private String convertInputStreamToString(InputStream inputStream) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
return reader.lines().collect(Collectors.joining(System.lineSeparator()));
} catch (IOException ex) {
logger.error("Error during response reading: ", ex);
throw new IllegalArgumentException(ex);
}
}
}
@@ -0,0 +1,92 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.core.net;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.github.prominence.openweathermap.api.enums.ApiVariant;
import com.github.prominence.openweathermap.api.request.RequestSettings;
import java.net.URL;
import java.util.stream.Collectors;
public final class RequestExecutor {
private final RequestSettings requestSettings;
public RequestExecutor(RequestSettings requestSettings) {
this.requestSettings = requestSettings;
}
public String getResponse(ApiVariant variant) {
return getResponse(variant, Method.GET);
}
public String getResponse(ApiVariant variant, Method httpMethod) {
return getResponse(selectRequestUrl(variant), httpMethod);
}
/**
* Executes call to provided API url and retrieves response in <code>String</code> representation.
*
* @param url the url to make API request.
* @param httpMethod HTTP method to execute.
* @return response from the request in <code>String</code> representation.
* @throws IllegalArgumentException in case if provided parameter isn't a valid url for {@link URL} instance.
*/
private String getResponse(String url, Method httpMethod) {
final HttpClient httpClient = requestSettings.getApiConfiguration().getHttpClient();
httpClient.setTimeoutSettings(requestSettings.getTimeoutSettings());
if (httpMethod == Method.GET) {
return httpClient.executeGetRequest(url);
} else {
return httpClient.executePostRequest(url, getSerializedPayload());
}
}
private String selectRequestUrl(ApiVariant variant) {
StringBuilder requestUrlBuilder = new StringBuilder(requestSettings.getApiConfiguration().getBaseUrls().get(variant));
requestUrlBuilder.append(requestSettings.getUrlAppender());
requestUrlBuilder.append('?');
String parameters = requestSettings.getRequestParameters().entrySet().stream()
.map(entry -> entry.getKey() + "=" + entry.getValue())
.collect(Collectors.joining("&"));
requestUrlBuilder.append(parameters);
return requestUrlBuilder.toString();
}
private String getSerializedPayload() {
final ObjectWriter objectWriter = requestSettings.getApiConfiguration().getObjectWriter();
try {
return objectWriter.writeValueAsString(requestSettings.getPayloadObject());
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
public enum Method {
GET,
POST
}
}
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.deserializer;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.github.prominence.openweathermap.api.model.air.pollution.Concentration;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Optional;
public class ConcentrationDeserializer extends JsonDeserializer<Concentration> {
@Override
public Concentration deserialize(JsonParser parser, DeserializationContext context) throws IOException {
return Optional.ofNullable(parser.readValueAs(BigDecimal.class))
.map(Concentration::new)
.orElse(null);
}
}
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.deserializer;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.Optional;
public class EpochSecondsDeserializer extends JsonDeserializer<OffsetDateTime> {
@Override
public OffsetDateTime deserialize(final JsonParser parser, final DeserializationContext context) throws IOException {
return Optional.ofNullable(parser.readValueAs(Long.class))
.map(Instant::ofEpochSecond)
.map((Instant instant) -> OffsetDateTime.ofInstant(instant, ZoneOffset.UTC))
.orElse(null);
}
}
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.deserializer;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Optional;
public class PercentageZeroToOneDeserializer extends JsonDeserializer<Integer> {
@Override
public Integer deserialize(JsonParser parser, DeserializationContext context) throws IOException {
return Optional.ofNullable(parser.readValueAs(BigDecimal.class))
.map(v -> v.multiply(BigDecimal.valueOf(100)))
.map(v -> v.setScale(0, RoundingMode.HALF_EVEN))
.map(BigDecimal::intValue)
.orElse(null);
}
}
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.deserializer;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.github.prominence.openweathermap.api.model.generic.precipitation.PrecipitationIntensity;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Optional;
public class PrecipitationIntensityDeserializer extends JsonDeserializer<PrecipitationIntensity> {
@Override
public PrecipitationIntensity deserialize(JsonParser parser, DeserializationContext context) throws IOException {
return Optional.ofNullable(parser.readValueAs(BigDecimal.class))
.map(PrecipitationIntensity::new)
.orElse(null);
}
}
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.deserializer;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
import java.util.Optional;
public class RequiredPercentageDeserializer extends JsonDeserializer<Integer> {
@Override
public Integer deserialize(JsonParser parser, DeserializationContext context) throws IOException {
return Optional.ofNullable(parser.readValueAs(Integer.class))
.filter(v -> v <= 100)
.filter(v -> v >= 0)
.orElseThrow(() -> new IllegalArgumentException("Invalid data found for percentage"));
}
}
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.deserializer;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.github.prominence.openweathermap.api.model.generic.temperature.TemperatureValue;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Optional;
public class TemperatureValueDeserializer extends JsonDeserializer<TemperatureValue> {
@Override
public TemperatureValue deserialize(JsonParser parser, DeserializationContext context) throws IOException {
return Optional.ofNullable(parser.readValueAs(BigDecimal.class))
.map(TemperatureValue::new)
.orElse(null);
}
}
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.deserializer;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.github.prominence.openweathermap.api.model.generic.visibility.Visibility;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Optional;
public class VisibilityDeserializer extends JsonDeserializer<Visibility> {
@Override
public Visibility deserialize(JsonParser parser, DeserializationContext context) throws IOException {
return Optional.ofNullable(parser.readValueAs(BigDecimal.class))
.map(Visibility::new)
.orElse(null);
}
}
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.deserializer;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.github.prominence.openweathermap.api.model.generic.wind.WindSpeed;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Optional;
public class WindSpeedDeserializer extends JsonDeserializer<WindSpeed> {
@Override
public WindSpeed deserialize(JsonParser parser, DeserializationContext context) throws IOException {
return Optional.ofNullable(parser.readValueAs(BigDecimal.class))
.map(WindSpeed::new)
.orElse(null);
}
}
@@ -0,0 +1,41 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.deserializer;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
import java.time.ZoneId;
import java.util.Optional;
public class ZoneIdDeserializer extends JsonDeserializer<ZoneId> {
@Override
public ZoneId deserialize(final JsonParser parser, final DeserializationContext context) throws IOException {
return Optional.ofNullable(parser.readValueAs(String.class))
.map(ZoneId::of)
.orElse(null);
}
}
@@ -0,0 +1,41 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.deserializer;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
import java.time.ZoneOffset;
import java.util.Optional;
public class ZoneOffsetDeserializer extends JsonDeserializer<ZoneOffset> {
@Override
public ZoneOffset deserialize(final JsonParser parser, final DeserializationContext context) throws IOException {
return Optional.ofNullable(parser.readValueAs(Integer.class))
.map(ZoneOffset::ofTotalSeconds)
.orElse(null);
}
}
@@ -1,31 +1,31 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* * Copyright (c) 2021 Alexey Zinchenko
* *
* * Permission is hereby granted, free of charge, to any person obtaining a copy
* * of this software and associated documentation files (the "Software"), to deal
* * 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.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Arrays;
import java.util.Optional;
/**
* The enum Air quality index.
@@ -73,8 +73,11 @@ public enum AirQualityIndex {
* @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);
@JsonCreator
public static AirQualityIndex getByIndex(@JsonProperty("aqi") int index) {
return Arrays.stream(values())
.filter(airQualityIndex -> airQualityIndex.getValue() == index)
.findFirst()
.orElse(null);
}
}
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.enums;
public enum ApiVariant {
BASE("https://api.openweathermap.org/"),
PRO("https://pro.openweathermap.org/");
private final String baseUrl;
ApiVariant(String baseUrl) {
this.baseUrl = baseUrl;
}
public String getBaseUrl() {
return baseUrl;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Alexey Zinchenko
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -20,7 +20,11 @@
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model;
package com.github.prominence.openweathermap.api.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import java.util.Arrays;
/**
* Enumeration for time of a day representation.
@@ -44,9 +48,24 @@ public enum DayTime {
/**
* Returns time of a day value.
*
* @return string value
*/
public String getValue() {
return value;
}
/**
* Finds the appropriate day time based on the short form value.
*
* @param value the short form value (d/n).
* @return day time
*/
@JsonCreator
public static DayTime findByValue(String value) {
return Arrays.stream(values())
.filter(dayTime -> dayTime.getValue().equals(value))
.findFirst()
.orElse(null);
}
}
@@ -0,0 +1,74 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import java.util.Arrays;
public enum EventLevel {
/**
* Unknown event severity.
*/
UNKNOWN(0),
/**
* Green alert.
*/
GREEN(1),
/**
* Yellow alert.
*/
YELLOW(2),
/**
* Orange alert.
*/
ORANGE(3),
/**
* Red alert.
*/
RED(4);
private final int value;
EventLevel(int value) {
this.value = value;
}
public int getValue() {
return value;
}
/**
* Finds the appropriate event level based on the numerical level.
*
* @param value the numerical level.
* @return event level
*/
@JsonCreator
public static EventLevel findByValue(int value) {
return Arrays.stream(values())
.filter(eventLevel -> eventLevel.getValue() == value)
.findFirst()
.orElse(null);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Alexey Zinchenko
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -52,8 +52,9 @@ public enum MoonType {
return WANING_GIBBOUS;
} else if (numericValue > 0.75 && numericValue < 1) {
return WANING_CRESCENT;
} else {
return INVALID;
}
return INVALID;
}
private static boolean equals(double d1, double d2) {
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Alexey Zinchenko
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 Alexey Zinchenko
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -23,6 +23,7 @@
package com.github.prominence.openweathermap.api.enums;
public enum ResponseType {
JSON("json"),
HTML("html"),
XML("xml");
@@ -0,0 +1,70 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
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;
}
/**
* Finds the appropriate road state based on the numerical code.
*
* @param value the numerical code.
* @return road state
*/
@JsonCreator
public static RoadState findByValue(int value) {
return Arrays.stream(values()).filter(roadState -> roadState.getValue() == value).findFirst().orElse(null);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Alexey Zinchenko
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -28,9 +28,9 @@ package com.github.prominence.openweathermap.api.enums;
*/
public enum SubscriptionPlan {
/**
* Free subscription plan.
* An alias that represents any of paid plans: startup, developer, professional or enterprise.
*/
FREE,
PAID,
/**
* Startup subscription plan.
@@ -52,13 +52,14 @@ public enum SubscriptionPlan {
*/
ENTERPRISE,
/**
* Special subscription plan. You should contact a manager to get an access.
*/
SPECIAL,
/**
* All existing subscription plans.
*/
ALL,
/**
* Special subscription cases.
*/
SPECIAL,
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Alexey Zinchenko
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -47,37 +47,6 @@ public enum UnitSystem {
this.value = value;
}
/**
* Returns wind unit for current unit system.
* @return wind unit.
*/
public String getWindUnit() {
switch (this) {
case IMPERIAL:
return "miles/hour";
case STANDARD:
case METRIC:
default:
return "meter/sec";
}
}
/**
* Returns temperature unit for current unit system.
* @return temperature unit.
*/
public String getTemperatureUnit() {
switch (this) {
case METRIC:
return "°C";
case IMPERIAL:
return "°F";
case STANDARD:
default:
return "";
}
}
/**
* Returns unit system value.
* @return value unit system.
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Alexey Zinchenko
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -22,6 +22,9 @@
package com.github.prominence.openweathermap.api.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Arrays;
import java.util.Optional;
@@ -277,7 +280,7 @@ public enum WeatherCondition {
private final String description;
private final String iconId;
private WeatherCondition(int id, String name, String description, String iconId) {
WeatherCondition(int id, String name, String description, String iconId) {
this.id = id;
this.name = name;
this.description = description;
@@ -311,13 +314,24 @@ public enum WeatherCondition {
return description;
}
/**
* Gets icon id based on part of day.
*
* @param partOfDay The part of day we need the icon for.
* @return the icon id
*/
public String getIconId(DayTime partOfDay) {
return iconId + partOfDay.getValue();
}
/**
* Gets day icon id.
*
* @return the day icon id
*/
public String getDayIconId() {
return iconId + 'd';
return getIconId(DayTime.DAY);
}
/**
@@ -326,35 +340,42 @@ public enum WeatherCondition {
* @return the night icon id
*/
public String getNightIconId() {
return iconId + 'n';
return getIconId(DayTime.NIGHT);
}
/**
* Gets day icon url.
*
* @param secure Determines whether we need to use secure channel (HTTPS) for loading the image.
* @return the day icon url
*/
public String getDayIconUrl() {
return getIconUrl(getDayIconId());
public String getDayIconUrl(boolean secure) {
return getIconUrl(getDayIconId(), secure);
}
/**
* Gets night icon url.
*
* @param secure Determines whether we need to use secure channel (HTTPS) for loading the image.
* @return the night icon url
*/
public String getNightIconUrl() {
return getIconUrl(getNightIconId());
public String getNightIconUrl(boolean secure) {
return getIconUrl(getNightIconId(), secure);
}
/**
* Gets icon url.
*
* @param iconId the icon id
* @param secure Determines whether we need to use secure channel (HTTPS) for loading the image.
* @return the icon url
*/
public static String getIconUrl(String iconId) {
return "http://openweathermap.org/img/w/" + iconId + ".png";
public static String getIconUrl(String iconId, boolean secure) {
String scheme = "http";
if (secure) {
scheme = "https";
}
return scheme + "://openweathermap.org/img/w/" + iconId + ".png";
}
/**
@@ -363,8 +384,10 @@ public enum WeatherCondition {
* @param id the id
* @return the by id
*/
public static WeatherCondition getById(int id) {
final Optional<WeatherCondition> optionalWeatherCondition = Arrays.stream(values()).filter(weatherCondition -> weatherCondition.getId() == id).findFirst();
@JsonCreator
public static WeatherCondition getById(@JsonProperty("id") int id) {
final Optional<WeatherCondition> optionalWeatherCondition =
Arrays.stream(values()).filter(weatherCondition -> weatherCondition.getId() == id).findFirst();
return optionalWeatherCondition.orElse(null);
}
@@ -0,0 +1,29 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.exception;
public class ApiPayloadParseException extends RuntimeException {
public ApiPayloadParseException(String message, Throwable cause) {
super(message, cause);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Alexey Zinchenko
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Alexey Zinchenko
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -1,102 +0,0 @@
/*
* 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.Coordinate;
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;
/**
* The type Air pollution response mapper.
*/
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.setCoordinate(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 Coordinate parseCoordinate(JsonNode rootNode) {
final JsonNode latitudeNode = rootNode.get("lat");
final JsonNode longitudeNode = rootNode.get("lon");
if (latitudeNode != null && longitudeNode != null) {
return Coordinate.of(latitudeNode.asDouble(), longitudeNode.asDouble());
}
return null;
}
}
@@ -1,317 +0,0 @@
/*
* 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.model.weather.*;
import com.github.prominence.openweathermap.api.enums.UnitSystem;
import com.github.prominence.openweathermap.api.model.*;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
import java.util.TimeZone;
/**
* Official API response documentation:
* Parameters:
* --- coord
* |- coord.lon City geo location, longitude
* |- coord.lat City geo location, latitude
* --- weather (more info Weather condition codes)
* |- weather.id Weather condition id
* |- weather.main Group of weather parameters (Rain, Snow, Extreme etc.)
* |- weather.description Weather condition within the group
* |- weather.icon Weather icon id
* --- base Internal parameter
* --- main
* |- main.temp Temperature. UnitSystem Default: Kelvin, Metric: Celsius, Imperial: Fahrenheit.
* |- main.feels_like Temperature. This temperature parameter accounts for the human perception of weather. Unit Default: Kelvin, Metric: Celsius, Imperial: Fahrenheit.
* |- main.pressure Atmospheric pressure (on the sea level, if there is no sea_level or grnd_level data), hPa
* |- main.humidity Humidity, %
* |- main.temp_min Minimum temperature at the moment. This is deviation from current temp that is possible for large cities and megalopolises geographically expanded (use these parameter optionally). UnitSystem Default: Kelvin, Metric: Celsius, Imperial: Fahrenheit.
* |- main.temp_max Maximum temperature at the moment. This is deviation from current temp that is possible for large cities and megalopolises geographically expanded (use these parameter optionally). UnitSystem Default: Kelvin, Metric: Celsius, Imperial: Fahrenheit.
* |- main.sea_level Atmospheric pressure on the sea level, hPa
* |- main.grnd_level Atmospheric pressure on the ground level, hPa
* --- wind
* |- wind.speed Wind speed. UnitSystem Default: meter/sec, Metric: meter/sec, Imperial: miles/hour.
* |- wind.deg Wind direction, degrees (meteorological)
* |- wind.gust Wind gust. Unit Default: meter/sec, Metric: meter/sec, Imperial: miles/hour
* --- clouds
* |- clouds.all Cloudiness, %
* --- rain
* |- rain.1h Rain volume for the last 1 hour, mm
* |- rain.3h Rain volume for the last 3 hours, mm
* --- snow
* |- snow.1h Snow volume for the last 1 hour, mm
* |- snow.3h Snow volume for the last 3 hours, mm
* --- dt Time of data calculation, unix, UTC
* --- sys
* |- sys.type Internal parameter
* |- sys.id Internal parameter
* |- sys.message Internal parameter
* |- sys.country Country code (GB, JP etc.)
* |- sys.sunrise Sunrise time, unix, UTC
* |- sys.sunset Sunset time, unix, UTC
* --- timezone Shift in seconds from UTC
* --- id City ID
* --- name City name
* --- cod Internal parameter
*/
public class CurrentWeatherResponseMapper {
private final UnitSystem unitSystem;
/**
* Instantiates a new Current weather response mapper.
*
* @param unitSystem the unit system
*/
public CurrentWeatherResponseMapper(UnitSystem unitSystem) {
this.unitSystem = unitSystem != null ? unitSystem : UnitSystem.STANDARD;
}
/**
* Gets single result.
*
* @param json the json string
* @return the weather object
*/
public Weather getSingle(String json) {
final ObjectMapper objectMapper = new ObjectMapper();
Weather weather;
try {
final JsonNode root = objectMapper.readTree(json);
weather = getSingle(root);
} catch (JsonProcessingException e) {
throw new RuntimeException("Cannot parse Weather response");
}
return weather;
}
private Weather getSingle(JsonNode rootNode) {
final JsonNode weatherArrayNode = rootNode.get("weather");
final JsonNode weatherNode = weatherArrayNode != null ? weatherArrayNode.get(0) : null;
final Weather weather = new Weather();
weather.setWeatherState(parseWeatherState(weatherNode));
weather.setTemperature(parseTemperature(rootNode));
weather.setAtmosphericPressure(parsePressure(rootNode));
weather.setHumidity(parseHumidity(rootNode));
weather.setWind(parseWind(rootNode));
weather.setRain(parseRain(rootNode));
weather.setSnow(parseSnow(rootNode));
weather.setClouds(parseClouds(rootNode));
weather.setLocation(parseLocation(rootNode));
final JsonNode dtNode = rootNode.get("dt");
if (dtNode != null) {
weather.setCalculationTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(dtNode.asInt()), TimeZone.getDefault().toZoneId()));
}
return weather;
}
/**
* Gets list of results.
*
* @param json the json string
* @return the list of weathers
*/
public List<Weather> getList(String json) {
final ObjectMapper objectMapper = new ObjectMapper();
final List<Weather> weatherList = new ArrayList<>();
try {
final JsonNode root = objectMapper.readTree(json);
final JsonNode listNode = root.get("list");
listNode.forEach(jsonNode -> weatherList.add(getSingle(jsonNode)));
} catch (JsonProcessingException e) {
throw new RuntimeException("Cannot parse Weather response");
}
return weatherList;
}
private WeatherState parseWeatherState(JsonNode weatherNode) {
if (weatherNode == null) {
return null;
}
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;
}
private Temperature parseTemperature(JsonNode rootNode) {
final JsonNode mainNode = rootNode.get("main");
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;
}
private AtmosphericPressure parsePressure(JsonNode rootNode) {
final JsonNode mainNode = rootNode.get("main");
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;
}
private Humidity parseHumidity(JsonNode rootNode) {
final JsonNode mainNode = rootNode.get("main");
return Humidity.withValue((byte) (mainNode.get("humidity").asInt()));
}
private Wind parseWind(JsonNode rootNode) {
final JsonNode windNode = rootNode.get("wind");
double speed = windNode.get("speed").asDouble();
final Wind wind = Wind.withValue(speed, unitSystem.getWindUnit());
final JsonNode degNode = windNode.get("deg");
if (degNode != null) {
wind.setDegrees(degNode.asDouble());
}
final JsonNode gustNode = windNode.get("gust");
if (gustNode != null) {
wind.setGust(gustNode.asDouble());
}
return wind;
}
private Rain parseRain(JsonNode rootNode) {
final JsonNode rainNode = rootNode.get("rain");
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;
}
private Snow parseSnow(JsonNode rootNode) {
final JsonNode snowNode = rootNode.get("snow");
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;
}
private Clouds parseClouds(JsonNode rootNode) {
final JsonNode cloudsNode = rootNode.get("clouds");
final JsonNode allValueNode = cloudsNode.get("all");
if (allValueNode != null) {
return Clouds.withValue((byte) allValueNode.asInt());
}
return null;
}
private Location parseLocation(JsonNode rootNode) {
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.setCoordinate(parseCoordinate(coordNode));
}
return location;
}
private Coordinate parseCoordinate(JsonNode rootNode) {
final JsonNode latitudeNode = rootNode.get("lat");
final JsonNode longitudeNode = rootNode.get("lon");
if (latitudeNode != null && longitudeNode != null) {
return Coordinate.of(latitudeNode.asDouble(), longitudeNode.asDouble());
}
return null;
}
}
@@ -1,303 +0,0 @@
/*
* 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.UnitSystem;
import com.github.prominence.openweathermap.api.model.*;
import com.github.prominence.openweathermap.api.model.forecast.*;
import com.github.prominence.openweathermap.api.model.forecast.Location;
import com.github.prominence.openweathermap.api.model.forecast.Rain;
import com.github.prominence.openweathermap.api.model.forecast.Snow;
import com.github.prominence.openweathermap.api.model.Temperature;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
import java.util.TimeZone;
/**
* Official API response documentation.
* Parameters(but the real response can differ):
* --- cod Internal parameter
* --- message Internal parameter
* --- cnt A number of timestamps returned in the API response
* --- list
* |- list.dt Time of data forecasted, unix, UTC
* |- list.main
* |- list.main.temp Temperature. Unit Default: Kelvin, Metric: Celsius, Imperial: Fahrenheit.
* |- list.main.feels_like This temperature parameter accounts for the human perception of weather. Unit Default: Kelvin, Metric: Celsius, Imperial: Fahrenheit.
* |- list.main.temp_min Minimum temperature at the moment of calculation. This is minimal forecasted temperature (within large megalopolises and urban areas), use this parameter optionally. Unit Default: Kelvin, Metric: Celsius, Imperial: Fahrenheit.
* |- list.main.temp_max Maximum temperature at the moment of calculation. This is maximal forecasted temperature (within large megalopolises and urban areas), use this parameter optionally. Unit Default: Kelvin, Metric: Celsius, Imperial: Fahrenheit.
* |- list.main.pressure Atmospheric pressure on the sea level by default, hPa
* |- list.main.sea_level Atmospheric pressure on the sea level, hPa
* |- list.main.grnd_level Atmospheric pressure on the ground level, hPa
* |- list.main.humidity Humidity, %
* |- list.main.temp_kf Internal par
* |- list.weather
* |- list.weather.id Weather condition id
* |- list.weather.main Group of weather parameters (Rain, Snow, Extreme etc.)
* |- list.weather.description Weather condition within the group. You can get the output in your language.
* |- list.weather.icon Weather icon id
* |- list.clouds
* |- list.clouds.all Cloudiness, %
* |- list.wind
* |- list.wind.speed Wind speed. Unit Default: meter/sec, Metric: meter/sec, Imperial: miles/hour.
* |- list.wind.deg Wind direction, degrees (meteorological)
* |- list.visibility Average visibility, metres
* |- list.pop Probability of precipitation
* |- list.rain
* |- list.rain.3h Rain volume for last 3 hours, mm
* |- list.snow
* |- list.snow.3h Snow volume for last 3 hours
* |- list.sys
* |- list.sys.pod Part of the day (n - night, d - day)
* |- list.dt_txt Time of data forecasted, ISO, UTC
* --- city
* |- city.id City ID
* |- city.name City name
* |- city.coord
* |- city.coord.lat City geo location, latitude
* |- city.coord.lon City geo location, longitude
* |- city.country Country code (GB, JP etc.)
* |- city.timezone Shift in seconds from UTC
*/
public class FiveDayThreeHourStepForecastResponseMapper {
private final UnitSystem unitSystem;
/**
* Instantiates a new forecast response mapper.
*
* @param unitSystem the unit system
*/
public FiveDayThreeHourStepForecastResponseMapper(UnitSystem unitSystem) {
this.unitSystem = unitSystem;
}
/**
* Maps forecast response into java object.
*
* @param json the json string
* @return the forecast
*/
public Forecast mapToForecast(String json) {
final ObjectMapper objectMapper = new ObjectMapper();
Forecast forecast;
try {
final JsonNode root = objectMapper.readTree(json);
forecast = mapToForecast(root);
} catch (JsonProcessingException e) {
throw new RuntimeException("Cannot parse Forecast response");
}
return forecast;
}
private Forecast mapToForecast(JsonNode root) {
final Forecast forecast = new Forecast();
forecast.setLocation(parseLocation(root.get("city")));
final List<WeatherForecast> forecasts = new ArrayList<>(root.get("cnt").asInt());
final JsonNode forecastListNode = root.get("list");
forecastListNode.forEach(forecastNode -> forecasts.add(parseWeatherForecast(forecastNode)));
forecast.setWeatherForecasts(forecasts);
return forecast;
}
private WeatherForecast parseWeatherForecast(JsonNode rootNode) {
final WeatherForecast weatherForecast = new WeatherForecast();
final JsonNode weatherArrayNode = rootNode.get("weather");
if (weatherArrayNode != null) {
final JsonNode weatherNode = weatherArrayNode.get(0);
weatherForecast.setWeatherState(parseWeatherState(weatherNode));
}
final JsonNode mainNode = rootNode.get("main");
weatherForecast.setTemperature(parseTemperature(mainNode));
weatherForecast.setAtmosphericPressure(parsePressure(mainNode));
weatherForecast.setHumidity(parseHumidity(mainNode));
weatherForecast.setClouds(parseClouds(rootNode));
weatherForecast.setWind(parseWind(rootNode));
weatherForecast.setRain(parseRain(rootNode));
weatherForecast.setSnow(parseSnow(rootNode));
final JsonNode sysNode = rootNode.get("sys");
if (sysNode != null) {
weatherForecast.setDayTime("d".equals(sysNode.get("pod").asText()) ? DayTime.DAY : DayTime.NIGHT);
}
weatherForecast.setForecastTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(rootNode.get("dt").asLong()), TimeZone.getDefault().toZoneId()));
weatherForecast.setForecastTimeISO(rootNode.get("dt_txt").asText());
return weatherForecast;
}
private WeatherState parseWeatherState(JsonNode weatherNode) {
if (weatherNode == null) {
return null;
}
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;
}
private Temperature parseTemperature(JsonNode rootNode) {
final double tempValue = rootNode.get("temp").asDouble();
final Temperature temperature = Temperature.withValue(tempValue, unitSystem.getTemperatureUnit());
final JsonNode tempMaxNode = rootNode.get("temp_max");
if (tempMaxNode != null) {
temperature.setMaxTemperature(tempMaxNode.asDouble());
}
final JsonNode tempMinNode = rootNode.get("temp_min");
if (tempMinNode != null) {
temperature.setMinTemperature(tempMinNode.asDouble());
}
final JsonNode tempFeelsLike = rootNode.get("feels_like");
if (tempFeelsLike != null) {
temperature.setFeelsLike(tempFeelsLike.asDouble());
}
return temperature;
}
private AtmosphericPressure parsePressure(JsonNode rootNode) {
final AtmosphericPressure atmosphericPressure = AtmosphericPressure.withValue(rootNode.get("pressure").asDouble());
final JsonNode seaLevelNode = rootNode.get("sea_level");
final JsonNode groundLevelNode = rootNode.get("grnd_level");
if (seaLevelNode != null) {
atmosphericPressure.setSeaLevelValue(seaLevelNode.asDouble());
}
if (groundLevelNode != null) {
atmosphericPressure.setGroundLevelValue(groundLevelNode.asDouble());
}
return atmosphericPressure;
}
private Humidity parseHumidity(JsonNode rootNode) {
return Humidity.withValue((byte) (rootNode.get("humidity").asInt()));
}
private Wind parseWind(JsonNode root) {
final JsonNode windNode = root.get("wind");
double speed = windNode.get("speed").asDouble();
final Wind wind = Wind.withValue(speed, unitSystem.getWindUnit());
final JsonNode degNode = windNode.get("deg");
if (degNode != null) {
wind.setDegrees(degNode.asDouble());
}
return wind;
}
private Rain parseRain(JsonNode root) {
final JsonNode rainNode = root.get("rain");
if (rainNode != null) {
final JsonNode threeHourNode = rainNode.get("3h");
if (threeHourNode != null) {
return Rain.withThreeHourLevelValue(threeHourNode.asDouble());
}
}
return null;
}
private Snow parseSnow(JsonNode root) {
final JsonNode snowNode = root.get("snow");
if (snowNode != null) {
final JsonNode threeHourNode = snowNode.get("3h");
if (threeHourNode != null) {
return Snow.withThreeHourLevelValue(threeHourNode.asDouble());
}
}
return null;
}
private Clouds parseClouds(JsonNode rootNode) {
final JsonNode cloudsNode = rootNode.get("clouds");
final JsonNode allValueNode = cloudsNode.get("all");
if (allValueNode != null) {
return Clouds.withValue((byte) allValueNode.asInt());
}
return null;
}
private Location parseLocation(JsonNode rootNode) {
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.setCoordinate(parseCoordinate(coordNode));
}
final JsonNode populationNode = rootNode.get("population");
if (populationNode != null) {
location.setPopulation(populationNode.asLong());
}
return location;
}
private Coordinate parseCoordinate(JsonNode rootNode) {
final JsonNode latitudeNode = rootNode.get("lat");
final JsonNode longitudeNode = rootNode.get("lon");
if (latitudeNode != null && longitudeNode != null) {
return Coordinate.of(latitudeNode.asDouble(), longitudeNode.asDouble());
}
return null;
}
}
@@ -1,451 +0,0 @@
/*
* 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.UnitSystem;
import com.github.prominence.openweathermap.api.model.Clouds;
import com.github.prominence.openweathermap.api.model.Coordinate;
import com.github.prominence.openweathermap.api.model.Humidity;
import com.github.prominence.openweathermap.api.model.WeatherState;
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.HourlyHistorical;
import com.github.prominence.openweathermap.api.model.onecall.historical.HistoricalWeatherData;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
import java.util.TimeZone;
/**
* Object mapper for OneCall API response.
*/
public class OneCallWeatherResponseMapper {
private final UnitSystem unitSystem;
/**
* Instantiates a new forecast response mapper.
*
* @param unitSystem the unit system
*/
public OneCallWeatherResponseMapper(UnitSystem unitSystem) {
this.unitSystem = unitSystem;
}
/**
* Maps current weather data response into java object.
*
* @param json the json string
* @return the current data object
*/
public CurrentWeatherData mapToCurrent(String json) {
final ObjectMapper objectMapper = new ObjectMapper();
CurrentWeatherData currentData;
try {
final JsonNode root = objectMapper.readTree(json);
currentData = mapToCurrent(root);
} catch (JsonProcessingException e) {
throw new RuntimeException("Cannot parse OneCall response");
}
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) {
final ObjectMapper objectMapper = new ObjectMapper();
HistoricalWeatherData historicalData;
try {
final JsonNode root = objectMapper.readTree(json);
historicalData = mapToHistorical(root);
} catch (JsonProcessingException e) {
throw new RuntimeException("Cannot parse OneCall response");
}
return historicalData;
}
private CurrentWeatherData mapToCurrent(JsonNode rootNode) {
final CurrentWeatherData currentData = new CurrentWeatherData();
currentData.setCoordinate(Coordinate.of(rootNode.get("lat").asDouble(), rootNode.get("lon").asDouble()));
currentData.setTimezone(ZoneId.of(rootNode.get("timezone").asText()));
currentData.setTimezoneOffset(ZoneOffset.ofTotalSeconds(rootNode.get("timezone_offset").asInt()));
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) {
if (currentNode == null) {
return null;
}
final Current current = new Current();
current.setForecastTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(currentNode.get("dt").asInt()), TimeZone.getDefault().toZoneId()));
current.setSunriseTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(currentNode.get("sunrise").asInt()), TimeZone.getDefault().toZoneId()));
current.setSunsetTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(currentNode.get("sunset").asInt()), TimeZone.getDefault().toZoneId()));
current.setWeatherState(parseWeatherState(currentNode.get("weather").get(0)));
current.setTemperature(parseTemperature(currentNode));
current.setAtmosphericPressure(parsePressure(currentNode));
current.setHumidity(parseHumidity(currentNode));
current.setClouds(parseClouds(currentNode));
current.setUvIndex(currentNode.get("uvi").asDouble());
final JsonNode visibilityNode = currentNode.get("visibility");
if (visibilityNode != null) {
current.setVisibilityInMetres(visibilityNode.asDouble());
}
current.setWind(parseWind(currentNode));
current.setRain(parseRain(currentNode));
current.setSnow(parseSnow(currentNode));
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(
LocalDateTime.ofInstant(Instant.ofEpochSecond(minutelyNode.get("dt").asInt()), TimeZone.getDefault().toZoneId()),
minutelyNode.get("precipitation").asDouble()
));
}
return minutelyList;
}
private List<Hourly> parseHourlyList(JsonNode hourlyListNode) {
if (hourlyListNode == null) {
return null;
}
final List<Hourly> hourlyList = new ArrayList<>();
for (final JsonNode hourlyNode : hourlyListNode) {
final Hourly hourly = new Hourly();
hourly.setForecastTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(hourlyNode.get("dt").asInt()), TimeZone.getDefault().toZoneId()));
hourly.setWeatherState(parseWeatherState(hourlyNode.get("weather").get(0)));
hourly.setTemperature(parseTemperature(hourlyNode));
hourly.setAtmosphericPressure(parsePressure(hourlyNode));
hourly.setHumidity(parseHumidity(hourlyNode));
hourly.setClouds(parseClouds(hourlyNode));
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(parseWind(hourlyNode));
final JsonNode popNode = hourlyNode.get("pop");
if (popNode != null) {
hourly.setProbabilityOfPrecipitation(popNode.asDouble());
}
hourly.setRain(parseRain(hourlyNode));
hourly.setSnow(parseSnow(hourlyNode));
hourlyList.add(hourly);
}
return hourlyList;
}
private List<Daily> parseDailyList(JsonNode dailyListNode) {
if (dailyListNode == null) {
return null;
}
final List<Daily> dailyList = new ArrayList<>();
for (final JsonNode dailyNode : dailyListNode) {
final Daily daily = new Daily();
daily.setForecastTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(dailyNode.get("dt").asInt()), TimeZone.getDefault().toZoneId()));
daily.setSunriseTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(dailyNode.get("sunrise").asInt()), TimeZone.getDefault().toZoneId()));
daily.setSunsetTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(dailyNode.get("sunset").asInt()), TimeZone.getDefault().toZoneId()));
final JsonNode moonriseTimeNode = dailyNode.get("moonrise");
if (moonriseTimeNode != null) {
daily.setMoonriseTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(moonriseTimeNode.asInt()), TimeZone.getDefault().toZoneId()));
}
final JsonNode moonsetTimeNode = dailyNode.get("moonset");
if (moonsetTimeNode != null) {
daily.setMoonsetTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(moonsetTimeNode.asInt()), TimeZone.getDefault().toZoneId()));
}
final JsonNode moonPhaseNode = dailyNode.get("moon_phase");
if (moonPhaseNode != null) {
daily.setMoonPhase(new MoonPhase(moonPhaseNode.asDouble()));
}
daily.setSummary(parseSummary(dailyNode));
daily.setWeatherState(parseWeatherState(dailyNode.get("weather").get(0)));
daily.setTemperature(parseDailyTemperature(dailyNode));
daily.setAtmosphericPressure(parsePressure(dailyNode));
daily.setHumidity(parseHumidity(dailyNode));
daily.setWind(parseWind(dailyNode));
daily.setClouds(parseClouds(dailyNode));
daily.setUvIndex(dailyNode.get("uvi").asDouble());
daily.setProbabilityOfPrecipitation(dailyNode.get("pop").asDouble());
daily.setRain(parseDailyRain(dailyNode));
daily.setSnow(parseDailySnow(dailyNode));
dailyList.add(daily);
}
return dailyList;
}
private List<Alert> parseAlerts(JsonNode alertsNode) {
if (alertsNode == null) {
return null;
}
final List<Alert> alerts = new ArrayList<>();
for (final JsonNode alertNode : alertsNode) {
Alert alert = new Alert();
alert.setSenderName(alertNode.get("sender_name").asText());
alert.setEventName(alertNode.get("event").asText());
alert.setStartTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(alertNode.get("start").asInt()), TimeZone.getDefault().toZoneId()));
alert.setEndTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(alertNode.get("end").asInt()), TimeZone.getDefault().toZoneId()));
alert.setDescription(alertNode.get("description").asText());
alerts.add(alert);
}
return alerts;
}
private HistoricalWeatherData mapToHistorical(JsonNode rootNode) {
final HistoricalWeatherData historicalData = new HistoricalWeatherData();
historicalData.setCoordinate(Coordinate.of(rootNode.get("lat").asDouble(), rootNode.get("lon").asDouble()));
historicalData.setTimezone(ZoneId.of(rootNode.get("timezone").asText()));
historicalData.setTimezoneOffset(ZoneOffset.ofTotalSeconds(rootNode.get("timezone_offset").asInt()));
historicalData.setHistoricalWeather(parseHistoricalWeather(rootNode.get("current")));
historicalData.setHourlyList(parseHourlyHistoricalList(rootNode.get("hourly")));
return historicalData;
}
private HistoricalWeather parseHistoricalWeather(JsonNode currentNode) {
if (currentNode == null) {
return null;
}
final HistoricalWeather historicalWeather = new HistoricalWeather();
historicalWeather.setForecastTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(currentNode.get("dt").asInt()), TimeZone.getDefault().toZoneId()));
historicalWeather.setSunriseTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(currentNode.get("sunrise").asInt()), TimeZone.getDefault().toZoneId()));
historicalWeather.setSunsetTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(currentNode.get("sunset").asInt()), TimeZone.getDefault().toZoneId()));
final JsonNode weatherListNode = currentNode.get("weather");
if (weatherListNode != null) {
historicalWeather.setWeatherState(parseWeatherState(weatherListNode.get(0)));
}
historicalWeather.setTemperature(parseTemperature(currentNode));
historicalWeather.setAtmosphericPressure(parsePressure(currentNode));
historicalWeather.setHumidity(parseHumidity(currentNode));
historicalWeather.setClouds(parseClouds(currentNode));
historicalWeather.setUvIndex(currentNode.get("uvi").asDouble());
final JsonNode visibilityMode = currentNode.get("visibility");
if (visibilityMode != null) {
historicalWeather.setVisibilityInMetres(visibilityMode.asDouble());
}
historicalWeather.setWind(parseWind(currentNode));
historicalWeather.setRain(parseRain(currentNode));
historicalWeather.setSnow(parseSnow(currentNode));
return historicalWeather;
}
private List<HourlyHistorical> parseHourlyHistoricalList(JsonNode hourlyListNode) {
if (hourlyListNode == null) {
return null;
}
final List<HourlyHistorical> hourlyList = new ArrayList<>();
for (final JsonNode hourlyNode : hourlyListNode) {
final HourlyHistorical hourly = new HourlyHistorical();
hourly.setForecastTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(hourlyNode.get("dt").asInt()), TimeZone.getDefault().toZoneId()));
hourly.setWeatherState(parseWeatherState(hourlyNode.get("weather").get(0)));
hourly.setTemperature(parseTemperature(hourlyNode));
hourly.setAtmosphericPressure(parsePressure(hourlyNode));
hourly.setHumidity(parseHumidity(hourlyNode));
hourly.setClouds(parseClouds(hourlyNode));
final JsonNode visibilityNode = hourlyNode.get("visibility");
if (visibilityNode != null) {
hourly.setVisibilityInMetres(visibilityNode.asDouble());
}
hourly.setWind(parseWind(hourlyNode));
hourly.setRain(parseRain(hourlyNode));
hourly.setSnow(parseSnow(hourlyNode));
hourlyList.add(hourly);
}
return hourlyList;
}
private WeatherState parseWeatherState(JsonNode weatherNode) {
if (weatherNode == null) {
return null;
}
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;
}
private Temperature parseTemperature(JsonNode rootNode) {
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;
}
private DailyTemperature parseDailyTemperature(JsonNode dailyNode) {
final DailyTemperature temperature = new DailyTemperature();
final JsonNode tempNode = dailyNode.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 = dailyNode.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;
}
private AtmosphericPressure parsePressure(JsonNode rootNode) {
return AtmosphericPressure.withValue(rootNode.get("pressure").asDouble());
}
private Humidity parseHumidity(JsonNode rootNode) {
return Humidity.withValue((byte) (rootNode.get("humidity").asInt()));
}
private Wind parseWind(JsonNode rootNode) {
final JsonNode windSpeedNode = rootNode.get("wind_speed");
if (windSpeedNode == null) {
return null;
}
final Wind wind = Wind.withValue(windSpeedNode.asDouble(), unitSystem.getWindUnit());
final JsonNode degNode = rootNode.get("wind_deg");
if (degNode != null) {
wind.setDegrees(degNode.asDouble());
}
final JsonNode gustNode = rootNode.get("wind_gust");
if (gustNode != null) {
wind.setGust(gustNode.asDouble());
}
return wind;
}
private Rain parseRain(JsonNode root) {
final JsonNode rainNode = root.get("rain");
if (rainNode != null) {
final JsonNode oneHourNode = rainNode.get("1h");
if (oneHourNode != null) {
return Rain.withOneHourLevelValue(oneHourNode.asDouble());
}
}
return null;
}
private DailyRain parseDailyRain(JsonNode dailyNode) {
final JsonNode valueNode = dailyNode.get("rain");
if (valueNode != null) {
return DailyRain.withValue(valueNode.asDouble());
}
return null;
}
private Snow parseSnow(JsonNode root) {
final JsonNode snowNode = root.get("snow");
if (snowNode != null) {
final JsonNode OneHourNode = snowNode.get("1h");
if (OneHourNode != null) {
return Snow.withOneHourLevelValue(OneHourNode.asDouble());
}
}
return null;
}
private DailySnow parseDailySnow(JsonNode dailyNode) {
final JsonNode valueNode = dailyNode.get("snow");
if (valueNode != null) {
return DailySnow.withValue(valueNode.asDouble());
}
return null;
}
private Clouds parseClouds(JsonNode rootNode) {
final JsonNode cloudsNode = rootNode.get("clouds");
if (cloudsNode != null) {
return Clouds.withValue((byte) cloudsNode.asInt());
}
return null;
}
private String parseSummary(JsonNode dailyNode) {
final JsonNode summaryNode = dailyNode.get("summary");
if(summaryNode != null) {
return summaryNode.asText();
}
return null;
}
}
@@ -1,155 +0,0 @@
/*
* Copyright (c) 2021 Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model;
import java.util.Objects;
/**
* The AtmosphericPressure type represents atmospheric pressure value.
* Its value can only be a double in [0, +) range.
*/
public class AtmosphericPressure {
private static final String DEFAULT_UNIT = "hPa";
private double value;
private Double seaLevelValue;
private Double groundLevelValue;
/**
* Instantiates a new Pressure.
*
* @param value the value representing pressure value.
* @throws IllegalArgumentException in case if provided value isn't in allowed range.
*/
private AtmosphericPressure(double value) {
this.value = value;
}
/**
* Static method for {@link AtmosphericPressure} creation with value checking.
* @param value atmospheric pressure value.
* @return instantiated {@link AtmosphericPressure} object.
*/
public static AtmosphericPressure withValue(double value) {
if (value < 0) {
throw new IllegalArgumentException("Atmospheric pressure value must be in [0, +∞) range.");
}
return new AtmosphericPressure(value);
}
/**
* Returns pressure value.
*
* @return pressure value.
*/
public double getValue() {
return value;
}
/**
* Sets pressure value.
*
* @param value new pressure value.
* @throws IllegalArgumentException in case if provided value isn't in allowed range.
*/
public void setValue(double value) {
if (value < 0) {
throw new IllegalArgumentException("Atmospheric pressure value must be in [0, +∞) range.");
}
this.value = value;
}
/**
* Gets sea level value.
*
* @return the sea level value.
*/
public Double getSeaLevelValue() {
return seaLevelValue;
}
/**
* Sets sea level value.
*
* @param seaLevelValue the sea level value.
* @throws IllegalArgumentException in case if provided value isn't in allowed range.
*/
public void setSeaLevelValue(double seaLevelValue) {
if (seaLevelValue < 0) {
throw new IllegalArgumentException("Atmospheric pressure value must be in [0, +∞) range.");
}
this.seaLevelValue = seaLevelValue;
}
/**
* Gets ground level value.
*
* @return the ground level value.
*/
public Double getGroundLevelValue() {
return groundLevelValue;
}
/**
* Sets ground level value.
*
* @param groundLevelValue the ground level value.
* @throws IllegalArgumentException in case if provided value isn't in allowed range.
*/
public void setGroundLevelValue(double groundLevelValue) {
if (groundLevelValue < 0) {
throw new IllegalArgumentException("Atmospheric pressure value must be in [0, +∞) range.");
}
this.groundLevelValue = groundLevelValue;
}
/**
* Returns pressure unitSystem. Constantly equals to 'hPa'.
*
* @return the pressure unitSystem.
*/
public String getUnit() {
return DEFAULT_UNIT;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof AtmosphericPressure)) return false;
AtmosphericPressure atmosphericPressure = (AtmosphericPressure) o;
return Double.compare(atmosphericPressure.value, value) == 0 &&
Objects.equals(seaLevelValue, atmosphericPressure.seaLevelValue) &&
Objects.equals(groundLevelValue, atmosphericPressure.groundLevelValue);
}
@Override
public int hashCode() {
return Objects.hash(value, seaLevelValue, groundLevelValue);
}
@Override
public String toString() {
return "Pressure: " + value + ' ' + getUnit();
}
}
@@ -1,106 +0,0 @@
/*
* Copyright (c) 2021 Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model;
import java.util.Objects;
/**
* The Clouds type represents cloudiness value percentage.
* Its value can only be an integer in [0, 100] range.
*/
public class Clouds {
private static final String DEFAULT_UNIT = "%";
private byte value;
/**
* Instantiates a new Clouds.
*
* @param value the value representing cloudiness percentage.
* @throws IllegalArgumentException in case if provided value isn't in allowed range.
*/
private Clouds(byte value) {
this.value = value;
}
/**
* Static method for {@link Clouds} creation with value checking.
* @param value clouds percentage value.
* @return instantiated {@link Clouds} object.
*/
public static Clouds withValue(byte value) {
if (value < 0 || value > 100) {
throw new IllegalArgumentException("Cloudiness value must be in [0, 100] range.");
}
return new Clouds(value);
}
/**
* Returns cloudiness percentage value.
*
* @return cloudiness percentage.
*/
public byte getValue() {
return value;
}
/**
* Sets cloudiness percentage value.
*
* @param value new cloudiness value.
* @throws IllegalArgumentException in case if provided value isn't in allowed range.
*/
public void setValue(byte value) {
if (value < 0 || value > 100) {
throw new IllegalArgumentException("Cloudiness value must be in [0, 100] range.");
}
this.value = value;
}
/**
* Returns cloudiness unitSystem. Constantly equals to '%'.
*
* @return the cloudiness unitSystem.
*/
public String getUnit() {
return DEFAULT_UNIT;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Clouds)) return false;
Clouds clouds = (Clouds) o;
return value == clouds.value;
}
@Override
public int hashCode() {
return Objects.hash(value);
}
@Override
public String toString() {
return "Clouds: " + value + getUnit();
}
}
@@ -1,117 +0,0 @@
/*
* Copyright (c) 2021 Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model;
import java.util.Objects;
/**
* Represents some location by its latitude and longitude.
*/
public class Coordinate {
private double latitude;
private double longitude;
private Coordinate() {
}
/**
* Method for {@link Coordinate} creation with correctness check.
* @param latitude latitude
* @param longitude longitude
* @return coordinate object.
*/
public static Coordinate of(double latitude, double longitude) {
final Coordinate coordinate = new Coordinate();
coordinate.setLatitude(latitude);
coordinate.setLongitude(longitude);
return coordinate;
}
/**
* Sets latitude with checks.
* @param latitude latitude value
*/
public void setLatitude(double latitude) {
if (latitude < -90 || latitude > 90) {
throw new IllegalArgumentException("Latitude value must be in the next range: [-90.0; 90.0].");
}
this.latitude = latitude;
}
/**
* Sets longitude with checks.
* @param longitude longitude value
*/
public void setLongitude(double longitude) {
if (longitude < -180 || longitude > 180) {
throw new IllegalArgumentException("Longitude value must be in the next range: [-180.0; 180.0].");
}
this.longitude = longitude;
}
/**
* Returns latitude.
* @return latitude
*/
public double getLatitude() {
return latitude;
}
/**
* Returns longitude.
* @return longitude
*/
public double getLongitude() {
return longitude;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Coordinate)) return false;
Coordinate that = (Coordinate) o;
return Double.compare(that.latitude, latitude) == 0 &&
Double.compare(that.longitude, longitude) == 0;
}
@Override
public int hashCode() {
return Objects.hash(latitude, longitude);
}
@Override
public String toString() {
return formatAsDegree(latitude) +
", " + formatAsDegree(longitude);
}
private String formatAsDegree(double value) {
int degrees = (int) value;
double secondsDouble = value % 1 * 60;
int minutes = (int) secondsDouble;
int seconds = (int) (secondsDouble % 1 * 60);
return String.format("%s° %s %s″", degrees, minutes, seconds);
}
}
@@ -1,101 +0,0 @@
/*
* Copyright (c) 2021 Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model;
import java.util.Objects;
/**
* The Humidity type represents humidity value percentage.
* Its value can only be an integer in [0, 100] range.
*/
public class Humidity {
private static final String DEFAULT_UNIT = "%";
private int value;
/**
* Instantiates a new Humidity.
*
* @param value the value representing humidity percentage.
* @throws IllegalArgumentException in case if provided value isn't in allowed range.
*/
private Humidity(byte value) {
this.value = value;
}
/**
* Creates {@link Humidity} object with safeguard to have min 0 and max 100 as value
* @param value humidity
* @return created {@link Humidity} object
*/
public static Humidity withValue(byte value) {
int v = Math.max(0, Math.min(100, value));
return new Humidity((byte) v);
}
/**
* Returns humidity percentage value.
*
* @return humidity percentage.
*/
public int getValue() {
return value;
}
/**
* Sets humidity percentage value.
*
* @param value new humidity value.
* Rounds to 0 or 100 if provided value isn't in allowed range.
*/
public void setValue(int value) {
this.value = Math.max(0, Math.min(100, value));
}
/**
* Returns humidity unitSystem. Constantly equals to '%'.
*
* @return the humidity unitSystem.
*/
public String getUnit() {
return DEFAULT_UNIT;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Humidity)) return false;
Humidity humidity = (Humidity) o;
return value == humidity.value;
}
@Override
public int hashCode() {
return Objects.hash(value);
}
@Override
public String toString() {
return "Humidity: " + value + getUnit();
}
}
@@ -1,183 +0,0 @@
/*
* Copyright (c) 2021 Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model;
import java.util.Objects;
/**
* Represents temperature values and unit.
*/
public class Temperature {
private double value;
private Double maxTemperature;
private Double minTemperature;
private Double feelsLike;
private String unit;
private Temperature(double value, String unit) {
this.value = value;
this.unit = unit;
}
/**
* Creates {@link Temperature} object with correctness check.
* @param value temperature value
* @param unit temperature unit
* @return temperature object
*/
public static Temperature withValue(double value, String unit) {
if (unit == null) {
throw new IllegalArgumentException("Unit must be set.");
}
return new Temperature(value, unit);
}
/**
* Returns temperature value.
* @return value
*/
public double getValue() {
return value;
}
/**
* Sets temperature value.
* @param value temperature
*/
public void setValue(double value) {
this.value = value;
}
/**
* Returns maximal temperature value.
* @return maximal temperature value
*/
public Double getMaxTemperature() {
return maxTemperature;
}
/**
* Sets maximal temperature value.
* @param maxTemperature maximal temperature
*/
public void setMaxTemperature(Double maxTemperature) {
this.maxTemperature = maxTemperature;
}
/**
* Returns minimal temperature value.
* @return minimal temperature value
*/
public Double getMinTemperature() {
return minTemperature;
}
/**
* Sets minimal temperature value.
* @param minTemperature minimal temperature
*/
public void setMinTemperature(Double minTemperature) {
this.minTemperature = minTemperature;
}
/**
* Returns 'feels like' temperature value.
* @return 'feels like' temperature value
*/
public Double getFeelsLike() {
return feelsLike;
}
/**
* Sets 'feels like' temperature value.
* @param feelsLike 'feels like' temperature
*/
public void setFeelsLike(Double feelsLike) {
this.feelsLike = feelsLike;
}
/**
* Returns temperature unit.
* @return unit
*/
public String getUnit() {
return unit;
}
/**
* Sets temperature unit with correctness check.
* @param unit temperature unit
*/
public void setUnit(String unit) {
if (unit == null) {
throw new IllegalArgumentException("Unit must be set.");
}
this.unit = unit;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Temperature)) return false;
Temperature that = (Temperature) o;
return Double.compare(that.value, value) == 0 &&
Objects.equals(maxTemperature, that.maxTemperature) &&
Objects.equals(minTemperature, that.minTemperature) &&
Objects.equals(feelsLike, that.feelsLike) &&
Objects.equals(unit, that.unit);
}
@Override
public int hashCode() {
return Objects.hash(value, maxTemperature, minTemperature, feelsLike, unit);
}
@Override
public String toString() {
final StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("Temperature: ");
stringBuilder.append(value);
stringBuilder.append(' ');
stringBuilder.append(unit);
if (maxTemperature != null) {
stringBuilder.append(", Maximum value: ");
stringBuilder.append(maxTemperature);
stringBuilder.append(' ');
stringBuilder.append(unit);
}
if (minTemperature != null) {
stringBuilder.append(", Minimum value: ");
stringBuilder.append(minTemperature);
stringBuilder.append(' ');
stringBuilder.append(unit);
}
if (feelsLike != null) {
stringBuilder.append(", Feels like: ");
stringBuilder.append(feelsLike);
stringBuilder.append(' ');
stringBuilder.append(unit);
}
return stringBuilder.toString();
}
}
@@ -1,136 +0,0 @@
/*
* Copyright (c) 2021 Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model;
import com.github.prominence.openweathermap.api.enums.WeatherCondition;
import java.util.Objects;
/**
* The type Weather state.
*/
public class WeatherState {
private final int id;
private final String name;
private final String description;
private String iconId;
private final WeatherCondition weatherConditionEnum;
public WeatherState(Integer id, String name, String description) {
this.id = id;
this.name = name;
this.description = description;
this.weatherConditionEnum = WeatherCondition.getById(id);
}
/**
* Gets id.
*
* @return the id
*/
public int getId() {
return id;
}
/**
* Gets name.
*
* @return the name
*/
public String getName() {
return name;
}
/**
* Gets description.
*
* @return the description
*/
public String getDescription() {
return description;
}
/**
* Gets icon id.
*
* @return the icon id
*/
public String getIconId() {
return iconId;
}
/**
* Sets icon id.
*
* @param iconId the icon id
*/
public void setIconId(String iconId) {
this.iconId = iconId;
}
/**
* Gets weather condition enum.
*
* @return the weather condition enum
*/
public WeatherCondition getWeatherConditionEnum() {
return weatherConditionEnum;
}
/**
* Gets weather icon url.
*
* @return the weather icon url
*/
public String getWeatherIconUrl() {
if (iconId != null) {
return WeatherCondition.getIconUrl(iconId);
}
if (weatherConditionEnum != null) {
// return the default one for the current weather condition
return weatherConditionEnum.getDayIconUrl();
}
return null;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
WeatherState that = (WeatherState) o;
return Objects.equals(id, that.id) &&
Objects.equals(name, that.name) &&
Objects.equals(description, that.description) &&
Objects.equals(iconId, that.iconId);
}
@Override
public int hashCode() {
return Objects.hash(id, name, description, iconId, weatherConditionEnum);
}
@Override
public String toString() {
return "Weather state: " + name + "(" + description + ").";
}
}
@@ -0,0 +1,102 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model.air.pollution;
import com.github.prominence.openweathermap.api.enums.AirQualityIndex;
import java.time.OffsetDateTime;
/**
* Interface of air pollution concentration measurements.
*/
public interface AirPollutionConcentration {
/**
* The date time when the measurement happened.
*
* @return datetime
*/
OffsetDateTime getMeasurementTime();
/**
* The air quality index as an (overview).
*
* @return index
*/
AirQualityIndex getAirQualityIndex();
/**
* The concentration of CO in the air.
*
* @return CO
*/
Concentration getCarbonMonoxide();
/**
* The concentration of NO in the air.
*
* @return NO
*/
Concentration getNitrogenMonoxide();
/**
* The concentration of NO2 in the air.
*
* @return NO2
*/
Concentration getNitrogenDioxide();
/**
* The concentration of O3 in the air.
*
* @return O3
*/
Concentration getOzone();
/**
* The concentration of SO2 in the air.
*
* @return SO2
*/
Concentration getSulphurDioxide();
/**
* The concentration of pine particles matter in the air.
*
* @return fine particles
*/
Concentration getFineParticlesMatter();
/**
* The concentration of coarse particulate matter in the air.
*
* @return coarse particles
*/
Concentration getCoarseParticulateMatter();
/**
* The concentration of NH3 in the air.
*
* @return NH3
*/
Concentration getAmmonia();
}
@@ -1,87 +1,39 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* * Copyright (c) 2021 Alexey Zinchenko
* *
* * Permission is hereby granted, free of charge, to any person obtaining a copy
* * of this software and associated documentation files (the "Software"), to deal
* * 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.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model.air.pollution;
import com.github.prominence.openweathermap.api.model.Coordinate;
import com.github.prominence.openweathermap.api.model.generic.location.CoordinateAware;
import java.util.List;
import java.util.Objects;
/**
* The type Air pollution.
* Interface of air pollution overview.
*/
public class AirPollutionDetails {
private Coordinate coordinate;
private List<AirPollutionRecord> airPollutionRecords;
public interface AirPollutionDetails extends CoordinateAware {
/**
* Gets coordinate.
*
* @return the coordinate
* The pollution details.
* @return pollution
*/
public Coordinate getCoordinate() {
return coordinate;
}
/**
* Sets coordinate.
*
* @param coordinate the coordinate
*/
public void setCoordinate(Coordinate coordinate) {
this.coordinate = coordinate;
}
/**
* Gets air pollution details.
*
* @return the air pollution details
*/
public List<AirPollutionRecord> getAirPollutionRecords() {
return airPollutionRecords;
}
/**
* Sets air pollution details.
*
* @param airPollutionRecords the air pollution details
*/
public void setAirPollutionRecords(List<AirPollutionRecord> airPollutionRecords) {
this.airPollutionRecords = airPollutionRecords;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AirPollutionDetails that = (AirPollutionDetails) o;
return Objects.equals(coordinate, that.coordinate) && Objects.equals(airPollutionRecords, that.airPollutionRecords);
}
@Override
public int hashCode() {
return Objects.hash(coordinate, airPollutionRecords);
}
List<AirPollutionConcentration> getAirPollutionConcentration();
}
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model.air.pollution;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.github.prominence.openweathermap.api.model.generic.location.Coordinates;
import lombok.Data;
import java.util.List;
import java.util.stream.Collectors;
/**
* The type representing Air pollution data.
*/
@Data
public class AirPollutionDetailsModel implements AirPollutionDetails {
@JsonProperty("coord")
private Coordinates coordinates;
@JsonProperty("list")
private List<AirPollutionRecord> airPollutionRecords;
@JsonIgnore
@Override
public List<AirPollutionConcentration> getAirPollutionConcentration() {
return airPollutionRecords.stream()
.map(AirPollutionConcentration.class::cast)
.collect(Collectors.toList());
}
}
@@ -0,0 +1,61 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model.air.pollution;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.github.prominence.openweathermap.api.deserializer.ConcentrationDeserializer;
import lombok.Data;
/**
* The type Air pollution record.
*/
@Data
public class AirPollutionMeasurements {
@JsonDeserialize(using = ConcentrationDeserializer.class)
@JsonProperty("co")
private Concentration carbonMonoxide;
@JsonDeserialize(using = ConcentrationDeserializer.class)
@JsonProperty("no")
private Concentration nitrogenMonoxide;
@JsonDeserialize(using = ConcentrationDeserializer.class)
@JsonProperty("no2")
private Concentration nitrogenDioxide;
@JsonDeserialize(using = ConcentrationDeserializer.class)
@JsonProperty("o3")
private Concentration ozone;
@JsonDeserialize(using = ConcentrationDeserializer.class)
@JsonProperty("so2")
private Concentration sulphurDioxide;
@JsonDeserialize(using = ConcentrationDeserializer.class)
@JsonProperty("pm2_5")
private Concentration fineParticlesMatter;
@JsonDeserialize(using = ConcentrationDeserializer.class)
@JsonProperty("pm10")
private Concentration coarseParticulateMatter;
@JsonDeserialize(using = ConcentrationDeserializer.class)
@JsonProperty("nh3")
private Concentration ammonia;
}
@@ -1,376 +1,105 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* * Copyright (c) 2021 Alexey Zinchenko
* *
* * Permission is hereby granted, free of charge, to any person obtaining a copy
* * of this software and associated documentation files (the "Software"), to deal
* * 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.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model.air.pollution;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.github.prominence.openweathermap.api.deserializer.EpochSecondsDeserializer;
import com.github.prominence.openweathermap.api.enums.AirQualityIndex;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.Objects;
import java.util.stream.Stream;
import java.time.OffsetDateTime;
import java.util.Optional;
/**
* The type Air pollution record.
* The type representing an Air pollution record.
*/
public class AirPollutionRecord {
private LocalDateTime forecastTime;
@Data
public class AirPollutionRecord implements AirPollutionConcentration {
@JsonDeserialize(using = EpochSecondsDeserializer.class)
@JsonProperty("dt")
private OffsetDateTime measurementTime;
@JsonProperty("main")
private AirQualityIndex airQualityIndex;
@JsonProperty("components")
private AirPollutionMeasurements components;
private Double CO;
private Double NO;
private Double NO2;
private Double O3;
private Double SO2;
private Double PM2_5;
private Double PM10;
private Double NH3;
/**
* Gets forecast time.
*
* @return the forecast time
*/
public LocalDateTime getForecastTime() {
return forecastTime;
@Override
public OffsetDateTime getMeasurementTime() {
return measurementTime;
}
/**
* Sets forecast time.
*
* @param forecastTime the forecast time
*/
public void setForecastTime(LocalDateTime forecastTime) {
this.forecastTime = forecastTime;
}
/**
* Gets air quality index.
*
* @return the air quality index
*/
@Override
public AirQualityIndex getAirQualityIndex() {
return airQualityIndex;
}
/**
* Sets air quality index.
*
* @param airQualityIndex the air quality index
*/
public void setAirQualityIndex(AirQualityIndex airQualityIndex) {
this.airQualityIndex = airQualityIndex;
}
/**
* Gets carbon monoxide concentration value in μg/m^3.
*
* @return the carbon monoxide value
*/
public Double getCO() {
return CO;
}
/**
* Gets carbon monoxide concentration value in μg/m^3.
*
* @return the carbon monoxide value
*/
public Double getCarbonMonoxide() {
return getCO();
}
/**
* Sets carbon monoxide concentration value in μg/m^3.
*
* @param CO the carbon monoxide value
*/
public void setCO(Double CO) {
this.CO = CO;
}
/**
* Gets nitrogen monoxide concentration value in μg/m^3.
*
* @return the nitrogen monoxide value
*/
public Double getNO() {
return NO;
}
/**
* Gets nitrogen monoxide concentration value in μg/m^3.
*
* @return the nitrogen monoxide value
*/
public Double getNitrogenMonoxide() {
return getNO();
}
/**
* Sets nitrogen monoxide concentration value in μg/m^3.
*
* @param NO the nitrogen monoxide value
*/
public void setNO(Double NO) {
this.NO = NO;
}
/**
* Gets nitrogen dioxide concentration value in μg/m^3.
*
* @return the nitrogen dioxide value
*/
public Double getNO2() {
return NO2;
}
/**
* Gets nitrogen dioxide concentration value in μg/m^3.
*
* @return the nitrogen dioxide value
*/
public Double getNitrogenDioxide() {
return getNO2();
}
/**
* Sets nitrogen dioxide concentration value in μg/m^3.
*
* @param NO2 the nitrogen dioxide value
*/
public void setNO2(Double NO2) {
this.NO2 = NO2;
}
/**
* Gets ozone concentration value in μg/m^3.
*
* @return the ozone value
*/
public Double getO3() {
return O3;
}
/**
* Gets ozone concentration value in μg/m^3.
*
* @return the ozone value
*/
public Double getOzone() {
return getO3();
}
/**
* Sets ozone concentration value in μg/m^3.
*
* @param o3 the ozone value
*/
public void setO3(Double o3) {
O3 = o3;
}
/**
* Gets sulphur dioxide concentration value in μg/m^3.
*
* @return the sulphur dioxide value
*/
public Double getSO2() {
return SO2;
}
/**
* Gets sulphur dioxide concentration value in μg/m^3.
*
* @return the sulphur dioxide value
*/
public Double getSulphurDioxide() {
return getSO2();
}
/**
* Sets sulphur dioxide concentration value in μg/m^3.
*
* @param SO2 the sulphur dioxide value
*/
public void setSO2(Double SO2) {
this.SO2 = SO2;
}
/**
* Gets fine particles matter concentration value in μg/m^3.
*
* @return the fine particles matter value
*/
public Double getPM2_5() {
return PM2_5;
}
/**
* Gets fine particles matter concentration value in μg/m^3.
*
* @return the fine particles matter value
*/
public Double getFineParticlesMatter() {
return getPM2_5();
}
/**
* Sets fine particles matter concentration value in μg/m^3.
*
* @param PM2_5 the fine particles matter value
*/
public void setPM2_5(Double PM2_5) {
this.PM2_5 = PM2_5;
}
/**
* Gets coarse particulate matter concentration value in μg/m^3.
*
* @return the coarse particulate matter value
*/
public Double getPM10() {
return PM10;
}
/**
* Gets coarse particulate matter concentration value in μg/m^3.
*
* @return the coarse particulate matter value
*/
public Double getCoarseParticulateMatter() {
return getPM10();
}
/**
* Sets coarse particulate matter concentration value in μg/m^3.
*
* @param PM10 the coarse particulate matter value
*/
public void setPM10(Double PM10) {
this.PM10 = PM10;
}
/**
* Gets ammonia concentration value in μg/m^3.
*
* @return the ammonia value
*/
public Double getNH3() {
return NH3;
}
/**
* Gets ammonia concentration value in μg/m^3.
*
* @return the ammonia value
*/
public Double getAmmonia() {
return getNH3();
}
/**
* Sets ammonia concentration value in μg/m^3.
*
* @param NH3 the ammonia value
*/
public void setNH3(Double NH3) {
this.NH3 = NH3;
}
@JsonIgnore
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AirPollutionRecord that = (AirPollutionRecord) o;
return Objects.equals(forecastTime, that.forecastTime) && airQualityIndex == that.airQualityIndex && Objects.equals(CO, that.CO) && Objects.equals(NO, that.NO) && Objects.equals(NO2, that.NO2) && Objects.equals(O3, that.O3) && Objects.equals(SO2, that.SO2) && Objects.equals(PM2_5, that.PM2_5) && Objects.equals(PM10, that.PM10) && Objects.equals(NH3, that.NH3);
public Concentration getCarbonMonoxide() {
return Optional.ofNullable(components).map(AirPollutionMeasurements::getCarbonMonoxide).orElse(null);
}
@JsonIgnore
@Override
public int hashCode() {
return Objects.hash(forecastTime, airQualityIndex, CO, NO, NO2, O3, SO2, PM2_5, PM10, NH3);
public Concentration getNitrogenMonoxide() {
return Optional.ofNullable(components).map(AirPollutionMeasurements::getNitrogenMonoxide).orElse(null);
}
@JsonIgnore
@Override
public String toString() {
final StringBuilder stringBuilder = new StringBuilder()
.append("Air Pollution Record for ")
.append(forecastTime)
.append(", AQI=")
.append(airQualityIndex.name())
.append(".");
final boolean anyConcentrationAvailable = Stream.of(CO, NO, NO2, O3, SO2, PM2_5, PM10, NH3).anyMatch(Objects::nonNull);
if (anyConcentrationAvailable) {
stringBuilder.append(" Concentrations:");
if (CO != null) {
stringBuilder
.append(" CO(Carbon monoxide) = ")
.append(CO)
.append(" μg/m^3;");
}
if (NO != null) {
stringBuilder
.append(" NO(Nitrogen monoxide) = ")
.append(NO)
.append(" μg/m^3;");
}
if (NO2 != null) {
stringBuilder
.append(" NO2(Nitrogen dioxide) = ")
.append(NO2)
.append(" μg/m^3;");
}
if (O3 != null) {
stringBuilder
.append(" O3(Ozone) = ")
.append(O3)
.append(" μg/m^3;");
}
if (SO2 != null) {
stringBuilder
.append(" SO2(Sulphur dioxide) = ")
.append(SO2)
.append(" μg/m^3;");
}
if (PM2_5 != null) {
stringBuilder
.append(" PM2.5(Fine particles matter) = ")
.append(PM2_5)
.append(" μg/m^3;");
}
if (PM10 != null) {
stringBuilder
.append(" PM10(Coarse particulate matter) = ")
.append(PM10)
.append(" μg/m^3;");
}
if (NH3 != null) {
stringBuilder
.append(" NH3(Ammonia) = ")
.append(NH3)
.append(" μg/m^3;");
}
}
return stringBuilder.toString();
public Concentration getNitrogenDioxide() {
return Optional.ofNullable(components).map(AirPollutionMeasurements::getNitrogenDioxide).orElse(null);
}
@JsonIgnore
@Override
public Concentration getOzone() {
return Optional.ofNullable(components).map(AirPollutionMeasurements::getOzone).orElse(null);
}
@JsonIgnore
@Override
public Concentration getSulphurDioxide() {
return Optional.ofNullable(components).map(AirPollutionMeasurements::getSulphurDioxide).orElse(null);
}
@JsonIgnore
@Override
public Concentration getFineParticlesMatter() {
return Optional.ofNullable(components).map(AirPollutionMeasurements::getFineParticlesMatter).orElse(null);
}
@JsonIgnore
@Override
public Concentration getCoarseParticulateMatter() {
return Optional.ofNullable(components).map(AirPollutionMeasurements::getCoarseParticulateMatter).orElse(null);
}
@JsonIgnore
@Override
public Concentration getAmmonia() {
return Optional.ofNullable(components).map(AirPollutionMeasurements::getAmmonia).orElse(null);
}
}
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model.air.pollution;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.NonNull;
import lombok.ToString;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
* Entity for air pollution concentration measurement.
*/
@EqualsAndHashCode
@ToString
@AllArgsConstructor
public class Concentration {
private static final int DECIMAL_PLACES = 10;
@NonNull
private final BigDecimal value;
/**
* Returns the measured value in micrograms/m^3.
*
* @return value
*/
@JsonIgnore
public BigDecimal asMicrogramsPerCubicMeters() {
return value.setScale(DECIMAL_PLACES, RoundingMode.HALF_EVEN);
}
}
@@ -1,84 +0,0 @@
/*
* Copyright (c) 2021 Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model.forecast;
import java.util.List;
import java.util.Objects;
/**
* Represents information about forecast for different timestamps.
*/
public class Forecast {
private Location location;
private List<WeatherForecast> weatherForecasts;
/**
* Returns location information.
* @return location
*/
public Location getLocation() {
return location;
}
/**
* Sets forecast location.
* @param location forecast location
*/
public void setLocation(Location location) {
this.location = location;
}
/**
* Returns list of weather forecasts for different timestamps.
* @return list of forecast-per-timestamp information.
*/
public List<WeatherForecast> getWeatherForecasts() {
return weatherForecasts;
}
/**
* Sets list of weather forecasts for different timestamps.
* @param weatherForecasts list of forecast information
*/
public void setWeatherForecasts(List<WeatherForecast> weatherForecasts) {
this.weatherForecasts = weatherForecasts;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Forecast forecast = (Forecast) o;
return Objects.equals(location, forecast.location) && Objects.equals(weatherForecasts, forecast.weatherForecasts);
}
@Override
public int hashCode() {
return Objects.hash(location, weatherForecasts);
}
@Override
public String toString() {
return "A forecast for " + location.getName() + " with " + weatherForecasts.size() + " timestamps.";
}
}
@@ -1,235 +0,0 @@
/*
* Copyright (c) 2021 Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model.forecast;
import com.github.prominence.openweathermap.api.model.Coordinate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Objects;
/**
* Represents location information.
*/
public class Location {
private int id;
private String name;
private String countryCode;
private LocalDateTime sunriseTime;
private LocalDateTime sunsetTime;
private ZoneOffset zoneOffset;
private Coordinate coordinate;
private Long population;
private Location(int id, String name) {
this.id = id;
this.name = name;
}
/**
* Creates {@link Location} object with correctness check.
* @param id location id
* @param name location name
* @return location object
*/
public static Location withValues(int id, String name) {
if (name == null) {
throw new IllegalArgumentException("Name must be set.");
}
return new Location(id, name);
}
/**
* Returns ID.
* @return location ID
*/
public int getId() {
return id;
}
/**
* Sets location ID.
* @param id location id
*/
public void setId(int id) {
this.id = id;
}
/**
* Returns location name.
* @return location name
*/
public String getName() {
return name;
}
/**
* Sets location name.
* @param name location name
*/
public void setName(String name) {
this.name = name;
}
/**
* Returns country code.
* @return location country code
*/
public String getCountryCode() {
return countryCode;
}
/**
* Sets location country code.
* @param countryCode location country code
*/
public void setCountryCode(String countryCode) {
this.countryCode = countryCode;
}
/**
* Returns location sunrise time.
* @return sunrise time
*/
public LocalDateTime getSunriseTime() {
return sunriseTime;
}
/**
* Sets location sunrise time.
* @param sunriseTime sunrise time
*/
public void setSunriseTime(LocalDateTime sunriseTime) {
this.sunriseTime = sunriseTime;
}
/**
* Returns location sunset time.
* @return sunset time
*/
public LocalDateTime getSunsetTime() {
return sunsetTime;
}
/**
* Sets location sunset time.
* @param sunsetTime sunset time
*/
public void setSunsetTime(LocalDateTime sunsetTime) {
this.sunsetTime = sunsetTime;
}
/**
* Returns location timezone offset.
* @return timezone offset
*/
public ZoneOffset getZoneOffset() {
return zoneOffset;
}
/**
* Sets location timezone offset.
* @param zoneOffset timezone offset
*/
public void setZoneOffset(ZoneOffset zoneOffset) {
this.zoneOffset = zoneOffset;
}
/**
* Returns location coordinates.
* @return location coordinates.
*/
public Coordinate getCoordinate() {
return coordinate;
}
/**
* Sets location coordinates.
* @param coordinate location coordinates
*/
public void setCoordinate(Coordinate coordinate) {
this.coordinate = coordinate;
}
/**
* Sets location population.
* @return location population
*/
public Long getPopulation() {
return population;
}
/**
* Sets location population.
* @param population location population
*/
public void setPopulation(Long population) {
this.population = population;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Location)) return false;
Location location = (Location) o;
return id == location.id &&
Objects.equals(name, location.name) &&
Objects.equals(countryCode, location.countryCode) &&
Objects.equals(sunriseTime, location.sunriseTime) &&
Objects.equals(sunsetTime, location.sunsetTime) &&
Objects.equals(zoneOffset, location.zoneOffset) &&
Objects.equals(coordinate, location.coordinate) &&
Objects.equals(population, location.population);
}
@Override
public int hashCode() {
return Objects.hash(id, name, countryCode, sunriseTime, sunsetTime, zoneOffset, coordinate, population);
}
@Override
public String toString() {
final StringBuilder stringBuilder = new StringBuilder();
if (coordinate != null) {
stringBuilder.append(coordinate.toString());
stringBuilder.append(". ");
}
stringBuilder.append("ID: ");
stringBuilder.append(id);
stringBuilder.append(", Name: ");
stringBuilder.append(name);
if (countryCode != null) {
stringBuilder.append('(');
stringBuilder.append(countryCode);
stringBuilder.append(')');
}
if (population != null) {
stringBuilder.append(", Population: ");
stringBuilder.append(population);
}
return stringBuilder.toString();
}
}
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model.forecast;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.github.prominence.openweathermap.api.enums.DayTime;
import lombok.Data;
@Data
public class MetaData {
@JsonProperty("pod")
private DayTime partOfDay;
}
@@ -1,97 +0,0 @@
/*
* Copyright (c) 2021 Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model.forecast;
import java.util.Objects;
/**
* Represents rain information.
*/
public class Rain {
private static final String DEFAULT_UNIT = "mm";
private double threeHourLevel;
private Rain(double threeHourLevel) {
this.threeHourLevel = threeHourLevel;
}
/**
* Creates {@link Rain} object with correctness check.
* @param threeHourLevel 3-hour rain level value
* @return rain object.
*/
public static Rain withThreeHourLevelValue(double threeHourLevel) {
if (threeHourLevel < 0) {
throw new IllegalArgumentException("Rain level value cannot be negative.");
}
return new Rain(threeHourLevel);
}
/**
* Returns 3-hour rain level value.
* @return 3-hour rain level value
*/
public double getThreeHourLevel() {
return threeHourLevel;
}
/**
* Sets 3-hour rain level value with correctness check.
* @param threeHourLevel 3-hour rain level value
*/
public void setThreeHourLevel(double threeHourLevel) {
if (threeHourLevel < 0) {
throw new IllegalArgumentException("Rain level value cannot be negative.");
}
this.threeHourLevel = threeHourLevel;
}
/**
* Returns rain level unit of measure. Currently is constant.
* @return rain level unit of measure
*/
public String getUnit() {
return DEFAULT_UNIT;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Rain rain = (Rain) o;
return Double.compare(rain.threeHourLevel, threeHourLevel) == 0;
}
@Override
public int hashCode() {
return Objects.hash(threeHourLevel);
}
@Override
public String toString() {
return "3-hour rain level: " +
threeHourLevel + ' ' +
getUnit();
}
}
@@ -1,97 +0,0 @@
/*
* Copyright (c) 2021 Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model.forecast;
import java.util.Objects;
/**
* Represents snow information.
*/
public class Snow {
private static final String DEFAULT_UNIT = "mm";
private double threeHourLevel;
private Snow(double threeHourLevel) {
this.threeHourLevel = threeHourLevel;
}
/**
* Creates {@link Snow} object with correctness check.
* @param threeHourLevel 3-hour snow level value
* @return snow object.
*/
public static Snow withThreeHourLevelValue(double threeHourLevel) {
if (threeHourLevel < 0) {
throw new IllegalArgumentException("Snow level value cannot be negative.");
}
return new Snow(threeHourLevel);
}
/**
* Returns 3-hour snow level value.
* @return 3-hour snow level value
*/
public double getThreeHourLevel() {
return threeHourLevel;
}
/**
* Sets 3-hour snow level value with correctness check.
* @param threeHourLevel 3-hour snow level value
*/
public void setThreeHourLevel(double threeHourLevel) {
if (threeHourLevel < 0) {
throw new IllegalArgumentException("Snow level value cannot be negative.");
}
this.threeHourLevel = threeHourLevel;
}
/**
* Returns snow level unit of measure. Currently is constant.
* @return snow level unit of measure
*/
public String getUnit() {
return DEFAULT_UNIT;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Snow snow = (Snow) o;
return Double.compare(snow.threeHourLevel, threeHourLevel) == 0;
}
@Override
public int hashCode() {
return Objects.hash(threeHourLevel);
}
@Override
public String toString() {
return "3-hour snow level: " +
threeHourLevel + ' ' +
getUnit();
}
}
@@ -1,309 +0,0 @@
/*
* Copyright (c) 2021 Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model.forecast;
import com.github.prominence.openweathermap.api.model.*;
import java.time.LocalDateTime;
import java.util.Objects;
/**
* Represents weather forecast information for a particular timestamp.
*/
public class WeatherForecast {
private LocalDateTime forecastTime;
private WeatherState weatherState;
private Temperature temperature;
private AtmosphericPressure atmosphericPressure;
private Humidity humidity;
private Wind wind;
private Rain rain;
private Snow snow;
private Clouds clouds;
private String forecastTimeISO;
private DayTime dayTime;
/**
* Gets forecast time.
*
* @return the forecast time
*/
public LocalDateTime getForecastTime() {
return forecastTime;
}
/**
* Sets forecast time.
*
* @param forecastTime the forecast time
*/
public void setForecastTime(LocalDateTime forecastTime) {
this.forecastTime = forecastTime;
}
/**
* Gets weather state.
*
* @return the weather state
*/
public WeatherState getWeatherState() {
return weatherState;
}
/**
* Sets weather state.
*
* @param weatherState the weather state
*/
public void setWeatherState(WeatherState weatherState) {
this.weatherState = weatherState;
}
/**
* Gets temperature.
*
* @return the temperature
*/
public Temperature getTemperature() {
return temperature;
}
/**
* Sets temperature.
*
* @param temperature the temperature
*/
public void setTemperature(Temperature temperature) {
this.temperature = temperature;
}
/**
* Gets atmospheric pressure.
*
* @return the atmospheric pressure
*/
public AtmosphericPressure getAtmosphericPressure() {
return atmosphericPressure;
}
/**
* Sets atmospheric pressure.
*
* @param atmosphericPressure the atmospheric pressure
*/
public void setAtmosphericPressure(AtmosphericPressure atmosphericPressure) {
this.atmosphericPressure = atmosphericPressure;
}
/**
* Gets humidity.
*
* @return the humidity
*/
public Humidity getHumidity() {
return humidity;
}
/**
* Sets humidity.
*
* @param humidity the humidity
*/
public void setHumidity(Humidity humidity) {
this.humidity = humidity;
}
/**
* Gets wind.
*
* @return the wind
*/
public Wind getWind() {
return wind;
}
/**
* Sets wind.
*
* @param wind the wind
*/
public void setWind(Wind wind) {
this.wind = wind;
}
/**
* Gets rain.
*
* @return the rain
*/
public Rain getRain() {
return rain;
}
/**
* Sets rain.
*
* @param rain the rain
*/
public void setRain(Rain rain) {
this.rain = rain;
}
/**
* Gets snow.
*
* @return the snow
*/
public Snow getSnow() {
return snow;
}
/**
* Sets snow.
*
* @param snow the snow
*/
public void setSnow(Snow snow) {
this.snow = snow;
}
/**
* Gets clouds.
*
* @return the clouds
*/
public Clouds getClouds() {
return clouds;
}
/**
* Sets clouds.
*
* @param clouds the clouds
*/
public void setClouds(Clouds clouds) {
this.clouds = clouds;
}
/**
* Gets forecast time iso.
*
* @return the forecast time iso
*/
public String getForecastTimeISO() {
return forecastTimeISO;
}
/**
* Sets forecast time iso.
*
* @param forecastTimeISO the forecast time iso
*/
public void setForecastTimeISO(String forecastTimeISO) {
this.forecastTimeISO = forecastTimeISO;
}
/**
* Gets day time.
*
* @return the day time
*/
public DayTime getDayTime() {
return dayTime;
}
/**
* Sets day time.
*
* @param dayTime the day time
*/
public void setDayTime(DayTime dayTime) {
this.dayTime = dayTime;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
WeatherForecast that = (WeatherForecast) o;
return Objects.equals(forecastTime, that.forecastTime) &&
Objects.equals(weatherState, that.weatherState) &&
Objects.equals(temperature, that.temperature) &&
Objects.equals(atmosphericPressure, that.atmosphericPressure) &&
Objects.equals(humidity, that.humidity) &&
Objects.equals(wind, that.wind) &&
Objects.equals(rain, that.rain) &&
Objects.equals(snow, that.snow) &&
Objects.equals(clouds, that.clouds) &&
Objects.equals(forecastTimeISO, that.forecastTimeISO) &&
dayTime == that.dayTime;
}
@Override
public int hashCode() {
return Objects.hash(forecastTime, weatherState, temperature, atmosphericPressure, humidity, wind, rain, snow, clouds, forecastTimeISO, dayTime);
}
@Override
public String toString() {
final StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("Timestamp: ");
stringBuilder.append(forecastTimeISO);
if (weatherState != null) {
stringBuilder.append(", Weather: ");
stringBuilder.append(weatherState.getDescription());
}
if (temperature != null) {
stringBuilder.append(", ");
stringBuilder.append(temperature.getValue());
stringBuilder.append(' ');
stringBuilder.append(temperature.getUnit());
}
if (atmosphericPressure != null) {
stringBuilder.append(", ");
stringBuilder.append(atmosphericPressure.getValue());
stringBuilder.append(' ');
stringBuilder.append(atmosphericPressure.getUnit());
}
if (clouds != null) {
stringBuilder.append(", ");
stringBuilder.append(clouds.toString());
}
if (rain != null) {
stringBuilder.append(", Rain: ");
stringBuilder.append(rain.getThreeHourLevel());
stringBuilder.append(' ');
stringBuilder.append(rain.getUnit());
}
if (snow != null) {
stringBuilder.append(", Snow: ");
stringBuilder.append(snow.getThreeHourLevel());
stringBuilder.append(' ');
stringBuilder.append(snow.getUnit());
}
return stringBuilder.toString();
}
}
@@ -1,145 +0,0 @@
/*
* Copyright (c) 2021 Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model.forecast;
import java.util.Objects;
/**
* Represents wind information.
*/
public class Wind {
private double speed;
private Double degrees;
private String unit;
/**
* Instantiates a new Wind.
*
* @param speed the speed
* @param unit the unitSystem
*/
private Wind(double speed, String unit) {
this.speed = speed;
this.unit = unit;
}
/**
* Creates {@link Wind} object with correctness check
* @param speed the wind
* @param unit the unitSystem
* @return created wind object
*/
public static Wind withValue(double speed, String unit) {
if (speed < 0) {
throw new IllegalArgumentException("Wind speed value must be in positive or zero.");
}
if (unit == null) {
throw new IllegalArgumentException("Unit must be set.");
}
return new Wind(speed, unit);
}
/**
* Gets speed.
*
* @return the speed
*/
public double getSpeed() {
return speed;
}
/**
* Sets speed.
*
* @param speed the speed
*/
public void setSpeed(double speed) {
if (speed < 0) {
throw new IllegalArgumentException("Wind speed value must be in positive or zero.");
}
this.speed = speed;
}
/**
* Gets degrees.
*
* @return the degrees
*/
public Double getDegrees() {
return degrees;
}
/**
* Sets degrees.
*
* @param degrees the degrees
*/
public void setDegrees(double degrees) {
if (degrees < 0 || degrees > 360) {
throw new IllegalArgumentException("Wind direction value must be in [0, 360] range.");
}
this.degrees = degrees;
}
/**
* Gets unitSystem.
*
* @return the unitSystem
*/
public String getUnit() {
return unit;
}
/**
* Sets unitSystem.
*
* @param unit the unitSystem
*/
public void setUnit(String unit) {
if (unit == null) {
throw new IllegalArgumentException("Unit must be set.");
}
this.unit = unit;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Wind)) return false;
Wind wind = (Wind) o;
return Double.compare(wind.speed, speed) == 0 &&
Objects.equals(degrees, wind.degrees) &&
Objects.equals(unit, wind.unit);
}
@Override
public int hashCode() {
return Objects.hash(speed, degrees, unit);
}
@Override
public String toString() {
return "Wind speed: " + speed + " " + unit +
", degrees: " + degrees;
}
}
@@ -0,0 +1,48 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model.forecast.climatic;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.github.prominence.openweathermap.api.model.generic.location.BaseLocation;
import java.util.List;
/**
* Root object for 30 days long daily forecasts.
*/
public interface ThirtyDaysDailyForecast {
/**
* The location where the forecast belongs to.
* @return location
*/
@JsonIgnore
BaseLocation getLocation();
/**
* The forecasts.
* @return days
*/
@JsonIgnore
List<WeatherForecastDay> getWeatherForecasts();
}
@@ -0,0 +1,62 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model.forecast.climatic;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.github.prominence.openweathermap.api.model.generic.location.BaseLocation;
import com.github.prominence.openweathermap.api.model.generic.location.BaseLocationModel;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;
/**
* Represents information about forecast for different timestamps.
*/
@Data
public class ThirtyDaysDailyForecastModel implements ThirtyDaysDailyForecast {
@JsonProperty("cod")
private long cod;
@JsonProperty("message")
private BigDecimal message;
@JsonProperty("city")
private BaseLocationModel locationModel;
@JsonProperty("list")
private List<WeatherForecast> forecasts;
@Override
@JsonIgnore
public BaseLocation getLocation() {
return locationModel;
}
@Override
@JsonIgnore
public List<WeatherForecastDay> getWeatherForecasts() {
return forecasts.stream().map(WeatherForecastDay.class::cast).collect(Collectors.toList());
}
}
@@ -0,0 +1,193 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model.forecast.climatic;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.github.prominence.openweathermap.api.deserializer.EpochSecondsDeserializer;
import com.github.prominence.openweathermap.api.deserializer.RequiredPercentageDeserializer;
import com.github.prominence.openweathermap.api.deserializer.WindSpeedDeserializer;
import com.github.prominence.openweathermap.api.enums.WeatherCondition;
import com.github.prominence.openweathermap.api.model.generic.clouds.CloudCoverage;
import com.github.prominence.openweathermap.api.model.generic.clouds.Clouds;
import com.github.prominence.openweathermap.api.model.generic.location.SunlightStages;
import com.github.prominence.openweathermap.api.model.generic.precipitation.Humidity;
import com.github.prominence.openweathermap.api.model.generic.precipitation.PrecipitationValues;
import com.github.prominence.openweathermap.api.model.generic.pressure.BaseAtmosphericPressure;
import com.github.prominence.openweathermap.api.model.generic.temperature.DailyTemperature;
import com.github.prominence.openweathermap.api.model.generic.temperature.TemperatureDailyBasic;
import com.github.prominence.openweathermap.api.model.generic.temperature.TemperatureDailyDetailed;
import com.github.prominence.openweathermap.api.model.generic.temperature.TemperatureValue;
import com.github.prominence.openweathermap.api.model.generic.wind.BasicWind;
import com.github.prominence.openweathermap.api.model.generic.wind.WindSpeed;
import lombok.Data;
import java.math.BigDecimal;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
/**
* Represents weather forecast information for a particular timestamp.
*/
@Data
public class WeatherForecast implements WeatherForecastDay, DailyTemperature, BaseAtmosphericPressure, BasicWind, Humidity,
PrecipitationValues, SunlightStages {
@JsonDeserialize(using = EpochSecondsDeserializer.class)
@JsonProperty("dt")
private OffsetDateTime forecastTime;
@JsonProperty("temp")
private TemperatureDailyDetailed temperature;
@JsonProperty("feels_like")
private TemperatureDailyBasic feelsLike;
@JsonProperty("weather")
private List<WeatherCondition> weatherStates = new ArrayList<>();
@JsonDeserialize(using = RequiredPercentageDeserializer.class)
@JsonProperty("humidity")
private int humidityPercentage;
@JsonProperty("pressure")
private BigDecimal pressure;
@JsonDeserialize(using = RequiredPercentageDeserializer.class)
@JsonProperty("clouds")
private int clouds;
@JsonDeserialize(using = WindSpeedDeserializer.class)
@JsonProperty("speed")
private WindSpeed speed;
@JsonProperty("deg")
private Integer directionDegrees;
@JsonProperty("rain")
private BigDecimal rain;
@JsonProperty("snow")
private BigDecimal snow;
@JsonDeserialize(using = EpochSecondsDeserializer.class)
@JsonProperty("sunrise")
private OffsetDateTime sunriseTime;
@JsonDeserialize(using = EpochSecondsDeserializer.class)
@JsonProperty("sunset")
private OffsetDateTime sunsetTime;
@Override
@JsonIgnore
public DailyTemperature getTemperature() {
return this;
}
@Override
@JsonIgnore
public BasicWind getWind() {
return this;
}
@Override
@JsonIgnore
public TemperatureValue getMorning() {
return Optional.ofNullable(temperature).map(TemperatureDailyBasic::getMorning).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getDay() {
return Optional.ofNullable(temperature).map(TemperatureDailyBasic::getDay).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getEve() {
return Optional.ofNullable(temperature).map(TemperatureDailyBasic::getEve).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getNight() {
return Optional.ofNullable(temperature).map(TemperatureDailyBasic::getNight).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getMin() {
return Optional.ofNullable(temperature).map(TemperatureDailyDetailed::getMin).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getMax() {
return Optional.ofNullable(temperature).map(TemperatureDailyDetailed::getMax).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getMorningFeelsLike() {
return Optional.ofNullable(feelsLike).map(TemperatureDailyBasic::getMorning).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getDayFeelsLike() {
return Optional.ofNullable(feelsLike).map(TemperatureDailyBasic::getDay).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getEveFeelsLike() {
return Optional.ofNullable(feelsLike).map(TemperatureDailyBasic::getEve).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getNightFeelsLike() {
return Optional.ofNullable(feelsLike).map(TemperatureDailyBasic::getNight).orElse(null);
}
@Override
@JsonIgnore
public Humidity getHumidity() {
return this;
}
@Override
@JsonIgnore
public BaseAtmosphericPressure getAtmosphericPressure() {
return this;
}
@Override
@JsonIgnore
public CloudCoverage getCloudCoverage() {
return new Clouds(this.clouds);
}
@Override
@JsonIgnore
public PrecipitationValues getPrecipitation() {
return this;
}
@Override
@JsonIgnore
public SunlightStages getSunlightStages() {
return this;
}
}
@@ -0,0 +1,104 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model.forecast.climatic;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.github.prominence.openweathermap.api.enums.WeatherCondition;
import com.github.prominence.openweathermap.api.model.generic.TimeAware;
import com.github.prominence.openweathermap.api.model.generic.clouds.CloudCoverage;
import com.github.prominence.openweathermap.api.model.generic.location.SunlightStages;
import com.github.prominence.openweathermap.api.model.generic.precipitation.Humidity;
import com.github.prominence.openweathermap.api.model.generic.precipitation.PrecipitationValues;
import com.github.prominence.openweathermap.api.model.generic.pressure.BaseAtmosphericPressure;
import com.github.prominence.openweathermap.api.model.generic.temperature.DailyTemperature;
import com.github.prominence.openweathermap.api.model.generic.wind.BasicWind;
import java.util.List;
/**
* Contains forecast information for one day of the 30 day long climatic forecasts.
*/
public interface WeatherForecastDay extends TimeAware {
/**
* The temperature forecast.
*
* @return temps
*/
@JsonIgnore
DailyTemperature getTemperature();
/**
* The humidity forecast.
*
* @return humidity
*/
@JsonIgnore
Humidity getHumidity();
/**
* The atmospheric pressure forecast.
*
* @return pressure
*/
@JsonIgnore
BaseAtmosphericPressure getAtmosphericPressure();
/**
* The forecasted wind conditions.
*
* @return wind
*/
@JsonIgnore
BasicWind getWind();
/**
* The expected weather states.
*
* @return weather states
*/
List<WeatherCondition> getWeatherStates();
/**
* The forecasted cloud coverage.
*
* @return clouds
*/
@JsonIgnore
CloudCoverage getCloudCoverage();
/**
* The forecasted precipitation.
*
* @return precipitation
*/
@JsonIgnore
PrecipitationValues getPrecipitation();
/**
* Information about sunlight stages.
*
* @return sunlight
*/
@JsonIgnore
SunlightStages getSunlightStages();
}
@@ -0,0 +1,105 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model.forecast.daily;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.github.prominence.openweathermap.api.enums.WeatherCondition;
import com.github.prominence.openweathermap.api.model.generic.TimeAware;
import com.github.prominence.openweathermap.api.model.generic.clouds.CloudCoverage;
import com.github.prominence.openweathermap.api.model.generic.location.SunlightStages;
import com.github.prominence.openweathermap.api.model.generic.precipitation.Humidity;
import com.github.prominence.openweathermap.api.model.generic.precipitation.PrecipitationForecast;
import com.github.prominence.openweathermap.api.model.generic.pressure.BaseAtmosphericPressure;
import com.github.prominence.openweathermap.api.model.generic.temperature.DailyTemperature;
import com.github.prominence.openweathermap.api.model.generic.wind.DetailedWindInfo;
import java.util.List;
/**
* Interface for weather forecast data used by the SixteenDaysDailyForecast.
*/
public interface DailyWeather extends TimeAware {
/**
* The temperature data,
*
* @return temp
*/
@JsonIgnore
DailyTemperature getTemperature();
/**
* The humidity.
*
* @return humidity
*/
@JsonIgnore
Humidity getHumidity();
/**
* The atmospheric pressure.
*
* @return pressure
*/
@JsonIgnore
BaseAtmosphericPressure getAtmosphericPressure();
/**
* The wind conditions.
*
* @return wind
*/
@JsonIgnore
DetailedWindInfo getWind();
/**
* The weather states.
*
* @return weather
*/
List<WeatherCondition> getWeatherStates();
/**
* The cloud coverage.
*
* @return louds
*/
@JsonIgnore
CloudCoverage getCloudCoverage();
/**
* The precipitation.
*
* @return precipitation
*/
@JsonIgnore
PrecipitationForecast getPrecipitation();
/**
* The sunlight stages.
*
* @return sunlight
*/
@JsonIgnore
SunlightStages getSunlightStages();
}
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model.forecast.daily;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.github.prominence.openweathermap.api.model.generic.location.DetailedLocationInfo;
import java.util.List;
/**
* Represents the daily forecast for the next sixteen days
*/
public interface SixteenDaysDailyForecast {
/**
* Information about the location.
*
* @return location
*/
@JsonIgnore
DetailedLocationInfo getLocation();
/**
* The daily forecasts.
*
* @return forecasts
*/
@JsonIgnore
List<DailyWeather> getWeatherForecasts();
}
@@ -0,0 +1,64 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model.forecast.daily;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.github.prominence.openweathermap.api.model.generic.location.DetailedLocationInfo;
import com.github.prominence.openweathermap.api.model.generic.location.DetailedLocationModel;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;
/**
* Represents information about forecast for different timestamps.
*/
@Data
@JsonIgnoreProperties(value = {"cnt"})
public class SixteenDaysDailyForecastModel implements SixteenDaysDailyForecast {
@JsonProperty("cod")
private long cod;
@JsonProperty("message")
private BigDecimal message;
@JsonProperty("city")
private DetailedLocationModel locationModel;
@JsonProperty("list")
private List<WeatherForecast> forecasts;
@Override
@JsonIgnore
public DetailedLocationInfo getLocation() {
return locationModel;
}
@Override
@JsonIgnore
public List<DailyWeather> getWeatherForecasts() {
return forecasts.stream().map(DailyWeather.class::cast).collect(Collectors.toList());
}
}
@@ -0,0 +1,200 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model.forecast.daily;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.github.prominence.openweathermap.api.deserializer.EpochSecondsDeserializer;
import com.github.prominence.openweathermap.api.deserializer.PercentageZeroToOneDeserializer;
import com.github.prominence.openweathermap.api.deserializer.RequiredPercentageDeserializer;
import com.github.prominence.openweathermap.api.deserializer.WindSpeedDeserializer;
import com.github.prominence.openweathermap.api.enums.WeatherCondition;
import com.github.prominence.openweathermap.api.model.generic.clouds.CloudCoverage;
import com.github.prominence.openweathermap.api.model.generic.clouds.Clouds;
import com.github.prominence.openweathermap.api.model.generic.location.SunlightStages;
import com.github.prominence.openweathermap.api.model.generic.precipitation.Humidity;
import com.github.prominence.openweathermap.api.model.generic.precipitation.PrecipitationForecast;
import com.github.prominence.openweathermap.api.model.generic.pressure.BaseAtmosphericPressure;
import com.github.prominence.openweathermap.api.model.generic.temperature.DailyTemperature;
import com.github.prominence.openweathermap.api.model.generic.temperature.TemperatureDailyBasic;
import com.github.prominence.openweathermap.api.model.generic.temperature.TemperatureDailyDetailed;
import com.github.prominence.openweathermap.api.model.generic.temperature.TemperatureValue;
import com.github.prominence.openweathermap.api.model.generic.wind.DetailedWindInfo;
import com.github.prominence.openweathermap.api.model.generic.wind.WindSpeed;
import lombok.Data;
import java.math.BigDecimal;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
/**
* Represents weather forecast information for a particular timestamp.
*/
@Data
public class WeatherForecast
implements DailyWeather, DailyTemperature, BaseAtmosphericPressure, DetailedWindInfo, Humidity, PrecipitationForecast, SunlightStages {
@JsonDeserialize(using = EpochSecondsDeserializer.class)
@JsonProperty("dt")
private OffsetDateTime forecastTime;
@JsonProperty("temp")
private TemperatureDailyDetailed temperature;
@JsonProperty("feels_like")
private TemperatureDailyBasic feelsLike;
@JsonProperty("weather")
private List<WeatherCondition> weatherStates = new ArrayList<>();
@JsonDeserialize(using = RequiredPercentageDeserializer.class)
@JsonProperty("humidity")
private int humidityPercentage;
@JsonProperty("pressure")
private BigDecimal pressure;
@JsonDeserialize(using = RequiredPercentageDeserializer.class)
@JsonProperty("clouds")
private int clouds;
@JsonDeserialize(using = WindSpeedDeserializer.class)
@JsonProperty("speed")
private WindSpeed speed;
@JsonProperty("deg")
private Integer directionDegrees;
@JsonDeserialize(using = WindSpeedDeserializer.class)
@JsonProperty("gust")
private WindSpeed gust;
@JsonProperty("rain")
private BigDecimal rain;
@JsonProperty("snow")
private BigDecimal snow;
@JsonDeserialize(using = PercentageZeroToOneDeserializer.class)
@JsonProperty("pop")
private Integer probabilityOfPrecipitation;
@JsonDeserialize(using = EpochSecondsDeserializer.class)
@JsonProperty("sunrise")
private OffsetDateTime sunriseTime;
@JsonDeserialize(using = EpochSecondsDeserializer.class)
@JsonProperty("sunset")
private OffsetDateTime sunsetTime;
@Override
@JsonIgnore
public DailyTemperature getTemperature() {
return this;
}
@Override
@JsonIgnore
public DetailedWindInfo getWind() {
return this;
}
@Override
@JsonIgnore
public TemperatureValue getMorning() {
return Optional.ofNullable(temperature).map(TemperatureDailyBasic::getMorning).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getDay() {
return Optional.ofNullable(temperature).map(TemperatureDailyBasic::getDay).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getEve() {
return Optional.ofNullable(temperature).map(TemperatureDailyBasic::getEve).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getNight() {
return Optional.ofNullable(temperature).map(TemperatureDailyBasic::getNight).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getMin() {
return Optional.ofNullable(temperature).map(TemperatureDailyDetailed::getMin).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getMax() {
return Optional.ofNullable(temperature).map(TemperatureDailyDetailed::getMax).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getMorningFeelsLike() {
return Optional.ofNullable(feelsLike).map(TemperatureDailyBasic::getMorning).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getDayFeelsLike() {
return Optional.ofNullable(feelsLike).map(TemperatureDailyBasic::getDay).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getEveFeelsLike() {
return Optional.ofNullable(feelsLike).map(TemperatureDailyBasic::getEve).orElse(null);
}
@Override
@JsonIgnore
public TemperatureValue getNightFeelsLike() {
return Optional.ofNullable(feelsLike).map(TemperatureDailyBasic::getNight).orElse(null);
}
@Override
@JsonIgnore
public Humidity getHumidity() {
return this;
}
@Override
@JsonIgnore
public BaseAtmosphericPressure getAtmosphericPressure() {
return this;
}
@Override
@JsonIgnore
public CloudCoverage getCloudCoverage() {
return new Clouds(this.clouds);
}
@Override
@JsonIgnore
public PrecipitationForecast getPrecipitation() {
return this;
}
@Override
@JsonIgnore
public SunlightStages getSunlightStages() {
return this;
}
}
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model.forecast.free;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.github.prominence.openweathermap.api.model.generic.location.DetailedLocationInfo;
import com.github.prominence.openweathermap.api.model.generic.location.SunlightStages;
import java.util.List;
/**
* Represents the 3 hours forecast for the next five days
*/
public interface FiveDaysThreeHoursForecast {
/**
* Information about the location.
*
* @return location
*/
@JsonIgnore
DetailedLocationInfo getLocation();
/**
* The expected sunlight stages.
*
* @return sunlight
*/
@JsonIgnore
SunlightStages getSunlightStages();
/**
* The 3-hourly forecasts.
*
* @return forecasts
*/
@JsonIgnore
List<ThreeHourWeather> getWeatherForecasts();
}
@@ -0,0 +1,69 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model.forecast.free;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.github.prominence.openweathermap.api.model.generic.location.DetailedLocationInfo;
import com.github.prominence.openweathermap.api.model.generic.location.SunlightStages;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;
/**
* Represents information about forecast for different timestamps.
*/
@Data
@JsonIgnoreProperties(value = {"cnt"})
public class FiveDaysThreeHoursForecastModel implements FiveDaysThreeHoursForecast {
@JsonProperty("cod")
private long cod;
@JsonProperty("message")
private BigDecimal message;
@JsonProperty("city")
private LocationModel locationModel;
@JsonProperty("list")
private List<WeatherForecast> forecasts;
@Override
@JsonIgnore
public DetailedLocationInfo getLocation() {
return locationModel;
}
@Override
@JsonIgnore
public SunlightStages getSunlightStages() {
return locationModel;
}
@Override
@JsonIgnore
public List<ThreeHourWeather> getWeatherForecasts() {
return forecasts.stream().map(ThreeHourWeather.class::cast).collect(Collectors.toList());
}
}
@@ -0,0 +1,51 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model.forecast.free;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.github.prominence.openweathermap.api.deserializer.EpochSecondsDeserializer;
import com.github.prominence.openweathermap.api.model.generic.location.DetailedLocationInfo;
import com.github.prominence.openweathermap.api.model.generic.location.DetailedLocationModel;
import com.github.prominence.openweathermap.api.model.generic.location.SunlightStages;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.time.OffsetDateTime;
/**
* Represents location information.
*/
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class LocationModel extends DetailedLocationModel implements DetailedLocationInfo, SunlightStages {
@JsonDeserialize(using = EpochSecondsDeserializer.class)
@JsonProperty("sunrise")
private OffsetDateTime sunriseTime;
@JsonDeserialize(using = EpochSecondsDeserializer.class)
@JsonProperty("sunset")
private OffsetDateTime sunsetTime;
}
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model.forecast.free;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
* Represents snow/rain information.
*/
@Data
public class Precipitation {
@JsonProperty("3h")
private BigDecimal threeHourLevel;
}
@@ -0,0 +1,111 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model.forecast.free;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.github.prominence.openweathermap.api.enums.DayTime;
import com.github.prominence.openweathermap.api.enums.WeatherCondition;
import com.github.prominence.openweathermap.api.model.generic.TimeAware;
import com.github.prominence.openweathermap.api.model.generic.clouds.CloudCoverage;
import com.github.prominence.openweathermap.api.model.generic.precipitation.Humidity;
import com.github.prominence.openweathermap.api.model.generic.precipitation.PrecipitationForecast;
import com.github.prominence.openweathermap.api.model.generic.pressure.DetailedAtmosphericPressure;
import com.github.prominence.openweathermap.api.model.generic.temperature.TemperatureWithRange;
import com.github.prominence.openweathermap.api.model.generic.visibility.Visibility;
import com.github.prominence.openweathermap.api.model.generic.wind.DetailedWindInfo;
import java.util.List;
/**
* Weather forecasts for 3 hours.
*/
public interface ThreeHourWeather extends TimeAware {
/**
* The temperature forecast.
*
* @return temperature
*/
@JsonIgnore
TemperatureWithRange getTemperature();
/**
* The humidity forecast.
*
* @return humidity
*/
@JsonIgnore
Humidity getHumidity();
/**
* The atmospheric pressure forecast.
*
* @return pressure
*/
@JsonIgnore
DetailedAtmosphericPressure getAtmosphericPressure();
/**
* The wind forecast.
*
* @return wind
*/
@JsonIgnore
DetailedWindInfo getWind();
/**
* The weather states.
*
* @return states
*/
List<WeatherCondition> getWeatherStates();
/**
* The forecasted cloud cover.
*
* @return clouds
*/
CloudCoverage getClouds();
/**
* The precipitation forecast.
*
* @return precipitation
*/
@JsonIgnore
PrecipitationForecast getThreeHoursPrecipitation();
/**
* The visibility forecast.
*
* @return visibility
*/
Visibility getVisibility();
/**
* The part of day.
*
* @return part of day
*/
@JsonIgnore
DayTime getPartOfDay();
}
@@ -0,0 +1,141 @@
/*
* Copyright (c) 2021-present Alexey Zinchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.prominence.openweathermap.api.model.forecast.free;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.github.prominence.openweathermap.api.deserializer.EpochSecondsDeserializer;
import com.github.prominence.openweathermap.api.deserializer.PercentageZeroToOneDeserializer;
import com.github.prominence.openweathermap.api.deserializer.VisibilityDeserializer;
import com.github.prominence.openweathermap.api.enums.DayTime;
import com.github.prominence.openweathermap.api.enums.WeatherCondition;
import com.github.prominence.openweathermap.api.model.forecast.MetaData;
import com.github.prominence.openweathermap.api.model.generic.MainMetrics;
import com.github.prominence.openweathermap.api.model.generic.TimeAware;
import com.github.prominence.openweathermap.api.model.generic.clouds.CloudCoverage;
import com.github.prominence.openweathermap.api.model.generic.clouds.Clouds;
import com.github.prominence.openweathermap.api.model.generic.precipitation.Humidity;
import com.github.prominence.openweathermap.api.model.generic.precipitation.PrecipitationForecast;
import com.github.prominence.openweathermap.api.model.generic.pressure.DetailedAtmosphericPressure;
import com.github.prominence.openweathermap.api.model.generic.temperature.TemperatureWithRange;
import com.github.prominence.openweathermap.api.model.generic.visibility.Visibility;
import com.github.prominence.openweathermap.api.model.generic.wind.DetailedWindInfo;
import com.github.prominence.openweathermap.api.model.generic.wind.WindModel;
import lombok.Data;
import java.math.BigDecimal;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
/**
* Represents weather forecast information for a particular timestamp.
*/
@Data
@JsonIgnoreProperties(value = {"dt_txt"})
public class WeatherForecast implements TimeAware, ThreeHourWeather, PrecipitationForecast {
@JsonDeserialize(using = EpochSecondsDeserializer.class)
@JsonProperty("dt")
private OffsetDateTime forecastTime;
@JsonProperty("main")
private MainMetrics mainMetrics;
@JsonProperty("weather")
private List<WeatherCondition> weatherStates = new ArrayList<>();
@JsonProperty("clouds")
private Clouds clouds;
@JsonProperty("wind")
private WindModel windModel;
@JsonProperty("rain")
private Precipitation rainModel;
@JsonProperty("snow")
private Precipitation snowModel;
@JsonDeserialize(using = VisibilityDeserializer.class)
@JsonProperty("visibility")
private Visibility visibility;
@JsonDeserialize(using = PercentageZeroToOneDeserializer.class)
@JsonProperty("pop")
private Integer probabilityOfPrecipitation;
@JsonProperty("sys")
private MetaData sysMeta;
@Override
@JsonIgnore
public TemperatureWithRange getTemperature() {
return mainMetrics;
}
@Override
@JsonIgnore
public Humidity getHumidity() {
return mainMetrics;
}
@Override
@JsonIgnore
public DetailedAtmosphericPressure getAtmosphericPressure() {
return mainMetrics;
}
@Override
@JsonIgnore
public DetailedWindInfo getWind() {
return windModel;
}
@Override
@JsonIgnore
public DayTime getPartOfDay() {
return Optional.ofNullable(sysMeta).map(MetaData::getPartOfDay).orElse(null);
}
@Override
@JsonIgnore
public PrecipitationForecast getThreeHoursPrecipitation() {
return this;
}
@Override
@JsonIgnore
public BigDecimal getRain() {
return Optional.ofNullable(rainModel)
.map(Precipitation::getThreeHourLevel)
.orElse(null);
}
@Override
@JsonIgnore
public BigDecimal getSnow() {
return Optional.ofNullable(snowModel)
.map(Precipitation::getThreeHourLevel)
.orElse(null);
}
@Override
public CloudCoverage getClouds() {
return clouds;
}
}

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