mirror of
https://github.com/Prominence/openweathermap-java-api.git
synced 2026-01-09 19:46:41 +03:00
Implemented climatic forecast for 30 days. Some refactoring.
This commit is contained in:
parent
4fdb48986e
commit
7f0866ffa2
15
README.md
15
README.md
@ -7,6 +7,12 @@ Free:
|
||||
* 5 day / 3-hour forecast
|
||||
* One Call API
|
||||
* Air pollution
|
||||
* Geocoding API
|
||||
|
||||
Paid:
|
||||
* Hourly Forecast 4 days
|
||||
* Daily Forecast 16 days
|
||||
* Climatic 30 days
|
||||
|
||||
Other:
|
||||
* Request timeout settings
|
||||
@ -14,14 +20,15 @@ Other:
|
||||
### Will be implemented later:
|
||||
|
||||
Free:
|
||||
* Geocoding API
|
||||
* Weather Stations
|
||||
* Weather Triggers
|
||||
|
||||
Paid:
|
||||
* Daily Forecast 16 days
|
||||
* Hourly Forecast 4 days
|
||||
* probably others...
|
||||
* Climatic Forecast 30 days
|
||||
* Bulk Downloading
|
||||
* Solar Radiation API
|
||||
* Global Weather Alerts / Push notifications
|
||||
* Road Risk API
|
||||
|
||||
### Maven coordinates:
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@ import com.github.prominence.openweathermap.api.annotation.SubscriptionAvailabil
|
||||
import com.github.prominence.openweathermap.api.conf.TimeoutSettings;
|
||||
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;
|
||||
@ -68,15 +69,6 @@ public class OpenWeatherMapClient {
|
||||
return new CurrentWeatherRequester(new RequestSettings(apiKey, timeoutSettings));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(new RequestSettings(apiKey, timeoutSettings));
|
||||
}
|
||||
|
||||
/**
|
||||
* Hourly forecast <a href="https://openweathermap.org/api/hourly-forecast">API</a>.
|
||||
* @return requester for retrieving hourly weather forecast information for 4 days.
|
||||
@ -86,6 +78,16 @@ public class OpenWeatherMapClient {
|
||||
return new FourDaysHourlyForecastRequester(new RequestSettings(apiKey, timeoutSettings));
|
||||
}
|
||||
|
||||
/**
|
||||
* One Call <a href="https://openweathermap.org/api/one-call-api">API</a>.
|
||||
* To get information about current weather, minute forecast for 1 hour, hourly forecast for 48 hours, daily forecast for 7 days and government weather alerts.
|
||||
* @return requester for retrieving one call weather information.
|
||||
*/
|
||||
@SubscriptionAvailability(plans = ALL)
|
||||
public OneCallWeatherRequester oneCall() {
|
||||
return new OneCallWeatherRequester(new RequestSettings(apiKey, timeoutSettings));
|
||||
}
|
||||
|
||||
/**
|
||||
* Daily forecast <a href="https://openweathermap.org/api/hourly-forecast">API</a>.
|
||||
* @return requester for retrieving daily weather forecast information for 16 days.
|
||||
@ -96,13 +98,21 @@ public class OpenWeatherMapClient {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* Climatic forecast <a href="https://openweathermap.org/api/forecast30">API</a>.
|
||||
* @return requester for retrieving climatic weather forecast information for 30 days.
|
||||
*/
|
||||
@SubscriptionAvailability(plans = { DEVELOPER, PROFESSIONAL, ENTERPRISE })
|
||||
public ClimaticForecastRequester climaticForecast30Days() {
|
||||
return new ClimaticForecastRequester(new RequestSettings(apiKey, timeoutSettings));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 OneCallWeatherRequester oneCall() {
|
||||
return new OneCallWeatherRequester(new RequestSettings(apiKey, timeoutSettings));
|
||||
public FiveDayThreeHourStepForecastRequester forecast5Day3HourStep() {
|
||||
return new FiveDayThreeHourStepForecastRequester(new RequestSettings(apiKey, timeoutSettings));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
package com.github.prominence.openweathermap.api.deserializer.forecast.climatic;
|
||||
|
||||
import com.fasterxml.jackson.core.JacksonException;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.github.prominence.openweathermap.api.model.forecast.climatic.AtmosphericPressure;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ClimaticForecastAtmosphericPressureDeserializer extends JsonDeserializer<AtmosphericPressure> {
|
||||
@Override
|
||||
public AtmosphericPressure deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
|
||||
final JsonNode jsonNode = jsonParser.getCodec().readTree(jsonParser);
|
||||
return (AtmosphericPressure) AtmosphericPressure.withValue(jsonNode.get("pressure").asDouble());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package com.github.prominence.openweathermap.api.deserializer.forecast.climatic;
|
||||
|
||||
import com.fasterxml.jackson.core.JacksonException;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.github.prominence.openweathermap.api.model.Clouds;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ClimaticForecastCloudsDeserializer extends JsonDeserializer<Clouds> {
|
||||
@Override
|
||||
public Clouds deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
|
||||
final JsonNode rootNode = jsonParser.getCodec().readTree(jsonParser);
|
||||
final JsonNode cloudsNode = rootNode.get("clouds");
|
||||
if (cloudsNode != null) {
|
||||
return Clouds.withValue((byte) cloudsNode.asInt());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
package com.github.prominence.openweathermap.api.deserializer.forecast.climatic;
|
||||
|
||||
import com.fasterxml.jackson.core.JacksonException;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.github.prominence.openweathermap.api.deserializer.CoordinatesDeserializer;
|
||||
import com.github.prominence.openweathermap.api.model.Coordinates;
|
||||
import com.github.prominence.openweathermap.api.model.forecast.climatic.Location;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static com.github.prominence.openweathermap.api.utils.JsonDeserializationUtils.parseZoneOffset;
|
||||
|
||||
public class ClimaticForecastLocationDeserializer extends JsonDeserializer<Location> {
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
public ClimaticForecastLocationDeserializer() {
|
||||
final SimpleModule module = new SimpleModule();
|
||||
module.addDeserializer(Coordinates.class, new CoordinatesDeserializer());
|
||||
objectMapper.registerModule(module);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
|
||||
final JsonNode rootNode = jsonParser.getCodec().readTree(jsonParser);
|
||||
final Location location = (Location) Location.withValues(rootNode.get("id").asInt(), rootNode.get("name").asText());
|
||||
|
||||
final JsonNode timezoneNode = rootNode.get("timezone");
|
||||
if (timezoneNode != null) {
|
||||
location.setZoneOffset(parseZoneOffset(timezoneNode));
|
||||
}
|
||||
|
||||
final JsonNode countryNode = rootNode.get("country");
|
||||
if (countryNode != null) {
|
||||
location.setCountryCode(countryNode.asText());
|
||||
}
|
||||
|
||||
final JsonNode coordNode = rootNode.get("coord");
|
||||
if (coordNode != null) {
|
||||
location.setCoordinate(objectMapper.readValue(objectMapper.treeAsTokens(coordNode), Coordinates.class));
|
||||
}
|
||||
|
||||
final JsonNode populationNode = rootNode.get("population");
|
||||
if (populationNode != null) {
|
||||
location.setPopulation(populationNode.asLong());
|
||||
}
|
||||
|
||||
return location;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package com.github.prominence.openweathermap.api.deserializer.forecast.climatic;
|
||||
|
||||
import com.fasterxml.jackson.core.JacksonException;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.github.prominence.openweathermap.api.model.forecast.climatic.Rain;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ClimaticForecastRainDeserializer extends JsonDeserializer<Rain> {
|
||||
@Override
|
||||
public Rain deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
|
||||
final JsonNode rootNode = jsonParser.getCodec().readTree(jsonParser);
|
||||
final JsonNode rainNode = rootNode.get("rain");
|
||||
if (rainNode != null) {
|
||||
return (Rain) Rain.withValue(rainNode.asDouble());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package com.github.prominence.openweathermap.api.deserializer.forecast.climatic;
|
||||
|
||||
import com.fasterxml.jackson.core.JacksonException;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.github.prominence.openweathermap.api.model.forecast.climatic.Snow;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ClimaticForecastSnowDeserializer extends JsonDeserializer<Snow> {
|
||||
@Override
|
||||
public Snow deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
|
||||
final JsonNode rootNode = jsonParser.getCodec().readTree(jsonParser);
|
||||
final JsonNode snowNode = rootNode.get("snow");
|
||||
if (snowNode != null) {
|
||||
return (Snow) Snow.withValue(snowNode.asDouble());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package com.github.prominence.openweathermap.api.deserializer.forecast.climatic;
|
||||
|
||||
import com.fasterxml.jackson.core.JacksonException;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.github.prominence.openweathermap.api.model.forecast.climatic.Temperature;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ClimaticForecastTemperatureDeserializer extends JsonDeserializer<Temperature> {
|
||||
@Override
|
||||
public Temperature deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
|
||||
final JsonNode rootNode = jsonParser.getCodec().readTree(jsonParser);
|
||||
|
||||
final Temperature temperature = new Temperature();
|
||||
final JsonNode tempNode = rootNode.get("temp");
|
||||
temperature.setMorning(tempNode.get("morn").asDouble());
|
||||
temperature.setDay(tempNode.get("day").asDouble());
|
||||
temperature.setEve(tempNode.get("eve").asDouble());
|
||||
temperature.setNight(tempNode.get("night").asDouble());
|
||||
temperature.setMin(tempNode.get("min").asDouble());
|
||||
temperature.setMax(tempNode.get("max").asDouble());
|
||||
|
||||
final JsonNode feelsLikeNode = rootNode.get("feels_like");
|
||||
temperature.setMorningFeelsLike(feelsLikeNode.get("morn").asDouble());
|
||||
temperature.setDayFeelsLike(feelsLikeNode.get("day").asDouble());
|
||||
temperature.setEveFeelsLike(feelsLikeNode.get("eve").asDouble());
|
||||
temperature.setNightFeelsLike(feelsLikeNode.get("night").asDouble());
|
||||
|
||||
return temperature;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Alexey Zinchenko
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.github.prominence.openweathermap.api.deserializer.forecast.climatic;
|
||||
|
||||
import com.fasterxml.jackson.core.JacksonException;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.github.prominence.openweathermap.api.enums.UnitSystem;
|
||||
import com.github.prominence.openweathermap.api.model.Wind;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ClimaticForecastWindDeserializer extends JsonDeserializer<Wind> {
|
||||
@Override
|
||||
public Wind deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
|
||||
final JsonNode windNode = p.getCodec().readTree(p);
|
||||
final UnitSystem unitSystem = (UnitSystem) ctxt.findInjectableValue("unitSystem", null, null);
|
||||
|
||||
JsonNode speedNode = windNode.get("speed");
|
||||
if (speedNode == null) {
|
||||
speedNode = windNode.get("wind_speed");
|
||||
}
|
||||
double speed = speedNode.asDouble();
|
||||
|
||||
final Wind wind = Wind.withValue(speed, unitSystem.getWindUnit());
|
||||
JsonNode degNode = windNode.get("deg");
|
||||
if (degNode == null) {
|
||||
degNode = windNode.get("wind_deg");
|
||||
}
|
||||
if (degNode != null) {
|
||||
wind.setDegrees(degNode.asDouble());
|
||||
}
|
||||
|
||||
return wind;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package com.github.prominence.openweathermap.api.deserializer.forecast.daily;
|
||||
|
||||
import com.fasterxml.jackson.core.JacksonException;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.github.prominence.openweathermap.api.model.forecast.daily.AtmosphericPressure;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class DailyForecastAtmosphericPressureDeserializer extends JsonDeserializer<AtmosphericPressure> {
|
||||
@Override
|
||||
public AtmosphericPressure deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
|
||||
final JsonNode jsonNode = jsonParser.getCodec().readTree(jsonParser);
|
||||
return (AtmosphericPressure) AtmosphericPressure.withValue(jsonNode.get("pressure").asDouble());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package com.github.prominence.openweathermap.api.deserializer.forecast.daily;
|
||||
|
||||
import com.fasterxml.jackson.core.JacksonException;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.github.prominence.openweathermap.api.model.Clouds;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class DailyForecastCloudsDeserializer extends JsonDeserializer<Clouds> {
|
||||
@Override
|
||||
public Clouds deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
|
||||
final JsonNode rootNode = jsonParser.getCodec().readTree(jsonParser);
|
||||
final JsonNode cloudsNode = rootNode.get("clouds");
|
||||
if (cloudsNode != null) {
|
||||
return Clouds.withValue((byte) cloudsNode.asInt());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
package com.github.prominence.openweathermap.api.deserializer.forecast.daily;
|
||||
|
||||
import com.fasterxml.jackson.core.JacksonException;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.github.prominence.openweathermap.api.deserializer.CoordinatesDeserializer;
|
||||
import com.github.prominence.openweathermap.api.model.Coordinates;
|
||||
import com.github.prominence.openweathermap.api.model.forecast.daily.Location;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static com.github.prominence.openweathermap.api.utils.JsonDeserializationUtils.parseZoneOffset;
|
||||
|
||||
public class DailyForecastLocationDeserializer extends JsonDeserializer<Location> {
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
public DailyForecastLocationDeserializer() {
|
||||
final SimpleModule module = new SimpleModule();
|
||||
module.addDeserializer(Coordinates.class, new CoordinatesDeserializer());
|
||||
objectMapper.registerModule(module);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
|
||||
final JsonNode rootNode = jsonParser.getCodec().readTree(jsonParser);
|
||||
final Location location = (Location) Location.withValues(rootNode.get("id").asInt(), rootNode.get("name").asText());
|
||||
|
||||
final JsonNode timezoneNode = rootNode.get("timezone");
|
||||
if (timezoneNode != null) {
|
||||
location.setZoneOffset(parseZoneOffset(timezoneNode));
|
||||
}
|
||||
|
||||
final JsonNode countryNode = rootNode.get("country");
|
||||
if (countryNode != null) {
|
||||
location.setCountryCode(countryNode.asText());
|
||||
}
|
||||
|
||||
final JsonNode coordNode = rootNode.get("coord");
|
||||
if (coordNode != null) {
|
||||
location.setCoordinate(objectMapper.readValue(objectMapper.treeAsTokens(coordNode), Coordinates.class));
|
||||
}
|
||||
|
||||
final JsonNode populationNode = rootNode.get("population");
|
||||
if (populationNode != null) {
|
||||
location.setPopulation(populationNode.asLong());
|
||||
}
|
||||
|
||||
return location;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package com.github.prominence.openweathermap.api.deserializer.forecast.daily;
|
||||
|
||||
import com.fasterxml.jackson.core.JacksonException;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.github.prominence.openweathermap.api.model.forecast.daily.Rain;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class DailyForecastRainDeserializer extends JsonDeserializer<Rain> {
|
||||
@Override
|
||||
public Rain deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
|
||||
final JsonNode rootNode = jsonParser.getCodec().readTree(jsonParser);
|
||||
final JsonNode rainNode = rootNode.get("rain");
|
||||
if (rainNode != null) {
|
||||
return (Rain) Rain.withValue(rainNode.asDouble());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package com.github.prominence.openweathermap.api.deserializer.forecast.daily;
|
||||
|
||||
import com.fasterxml.jackson.core.JacksonException;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.github.prominence.openweathermap.api.model.forecast.daily.Snow;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class DailyForecastSnowDeserializer extends JsonDeserializer<Snow> {
|
||||
@Override
|
||||
public Snow deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
|
||||
final JsonNode rootNode = jsonParser.getCodec().readTree(jsonParser);
|
||||
final JsonNode snowNode = rootNode.get("snow");
|
||||
if (snowNode != null) {
|
||||
return (Snow) Snow.withValue(snowNode.asDouble());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package com.github.prominence.openweathermap.api.deserializer.forecast.daily;
|
||||
|
||||
import com.fasterxml.jackson.core.JacksonException;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.github.prominence.openweathermap.api.model.forecast.daily.Temperature;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class DailyForecastTemperatureDeserializer extends JsonDeserializer<Temperature> {
|
||||
@Override
|
||||
public Temperature deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
|
||||
final JsonNode rootNode = jsonParser.getCodec().readTree(jsonParser);
|
||||
|
||||
final Temperature temperature = new Temperature();
|
||||
final JsonNode tempNode = rootNode.get("temp");
|
||||
temperature.setMorning(tempNode.get("morn").asDouble());
|
||||
temperature.setDay(tempNode.get("day").asDouble());
|
||||
temperature.setEve(tempNode.get("eve").asDouble());
|
||||
temperature.setNight(tempNode.get("night").asDouble());
|
||||
temperature.setMin(tempNode.get("min").asDouble());
|
||||
temperature.setMax(tempNode.get("max").asDouble());
|
||||
|
||||
final JsonNode feelsLikeNode = rootNode.get("feels_like");
|
||||
temperature.setMorningFeelsLike(feelsLikeNode.get("morn").asDouble());
|
||||
temperature.setDayFeelsLike(feelsLikeNode.get("day").asDouble());
|
||||
temperature.setEveFeelsLike(feelsLikeNode.get("eve").asDouble());
|
||||
temperature.setNightFeelsLike(feelsLikeNode.get("night").asDouble());
|
||||
|
||||
return temperature;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,84 @@
|
||||
package com.github.prominence.openweathermap.api.mapper;
|
||||
|
||||
import com.fasterxml.jackson.databind.InjectableValues;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.github.prominence.openweathermap.api.deserializer.HumidityDeserializer;
|
||||
import com.github.prominence.openweathermap.api.deserializer.WeatherStateDeserializer;
|
||||
import com.github.prominence.openweathermap.api.deserializer.forecast.climatic.*;
|
||||
import com.github.prominence.openweathermap.api.enums.UnitSystem;
|
||||
import com.github.prominence.openweathermap.api.model.Clouds;
|
||||
import com.github.prominence.openweathermap.api.model.Humidity;
|
||||
import com.github.prominence.openweathermap.api.model.WeatherState;
|
||||
import com.github.prominence.openweathermap.api.model.Wind;
|
||||
import com.github.prominence.openweathermap.api.model.forecast.climatic.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ClimaticForecastResponseMapper extends AbstractMapper {
|
||||
|
||||
public ClimaticForecastResponseMapper(UnitSystem unitSystem) {
|
||||
objectMapper.setInjectableValues(new InjectableValues.Std().addValue("unitSystem", unitSystem != null ? unitSystem : UnitSystem.STANDARD));
|
||||
final SimpleModule module = new SimpleModule();
|
||||
module.addDeserializer(WeatherState.class, new WeatherStateDeserializer());
|
||||
module.addDeserializer(Temperature.class, new ClimaticForecastTemperatureDeserializer());
|
||||
module.addDeserializer(AtmosphericPressure.class, new ClimaticForecastAtmosphericPressureDeserializer());
|
||||
module.addDeserializer(Humidity.class, new HumidityDeserializer());
|
||||
module.addDeserializer(Clouds.class, new ClimaticForecastCloudsDeserializer());
|
||||
module.addDeserializer(Rain.class, new ClimaticForecastRainDeserializer());
|
||||
module.addDeserializer(Snow.class, new ClimaticForecastSnowDeserializer());
|
||||
module.addDeserializer(Wind.class, new ClimaticForecastWindDeserializer());
|
||||
module.addDeserializer(Location.class, new ClimaticForecastLocationDeserializer());
|
||||
objectMapper.registerModule(module);
|
||||
}
|
||||
|
||||
public Forecast mapToForecast(String json) {
|
||||
Forecast forecast;
|
||||
try {
|
||||
final JsonNode root = objectMapper.readTree(json);
|
||||
forecast = mapToForecast(root);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Cannot parse Forecast response", e);
|
||||
}
|
||||
|
||||
return forecast;
|
||||
}
|
||||
|
||||
private Forecast mapToForecast(JsonNode root) throws IOException {
|
||||
final Forecast forecast = new Forecast();
|
||||
forecast.setLocation(objectMapper.readValue(objectMapper.treeAsTokens(root.get("city")), Location.class));
|
||||
|
||||
final List<WeatherForecast> forecasts = new ArrayList<>();
|
||||
|
||||
final JsonNode forecastListNode = root.get("list");
|
||||
for (JsonNode forecastNode : forecastListNode) {
|
||||
forecasts.add(parseWeatherForecast(forecastNode));
|
||||
}
|
||||
|
||||
forecast.setWeatherForecasts(forecasts);
|
||||
|
||||
return forecast;
|
||||
}
|
||||
|
||||
private WeatherForecast parseWeatherForecast(JsonNode rootNode) throws IOException {
|
||||
final WeatherForecast weatherForecast = new WeatherForecast();
|
||||
|
||||
weatherForecast.setForecastTime(parseDateTime(rootNode.get("dt")));
|
||||
weatherForecast.setSunriseTime(parseDateTime(rootNode.get("sunrise")));
|
||||
weatherForecast.setSunsetTime(parseDateTime(rootNode.get("sunset")));
|
||||
|
||||
weatherForecast.setWeatherStates(parseWeatherStates(rootNode.get("weather")));
|
||||
|
||||
weatherForecast.setTemperature(objectMapper.readValue(objectMapper.treeAsTokens(rootNode), Temperature.class));
|
||||
weatherForecast.setAtmosphericPressure(objectMapper.readValue(objectMapper.treeAsTokens(rootNode), AtmosphericPressure.class));
|
||||
weatherForecast.setHumidity(objectMapper.readValue(objectMapper.treeAsTokens(rootNode), Humidity.class));
|
||||
weatherForecast.setClouds(objectMapper.readValue(objectMapper.treeAsTokens(rootNode), Clouds.class));
|
||||
weatherForecast.setWind(objectMapper.readValue(objectMapper.treeAsTokens(rootNode), Wind.class));
|
||||
weatherForecast.setRain(objectMapper.readValue(objectMapper.treeAsTokens(rootNode), Rain.class));
|
||||
weatherForecast.setSnow(objectMapper.readValue(objectMapper.treeAsTokens(rootNode), Snow.class));
|
||||
|
||||
return weatherForecast;
|
||||
}
|
||||
}
|
||||
@ -22,22 +22,21 @@
|
||||
|
||||
package com.github.prominence.openweathermap.api.mapper;
|
||||
|
||||
import com.fasterxml.jackson.databind.*;
|
||||
import com.fasterxml.jackson.databind.InjectableValues;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.github.prominence.openweathermap.api.deserializer.*;
|
||||
import com.github.prominence.openweathermap.api.deserializer.weather.WeatherLocationDeserializer;
|
||||
import com.github.prominence.openweathermap.api.deserializer.weather.WeatherRainDeserializer;
|
||||
import com.github.prominence.openweathermap.api.deserializer.weather.WeatherSnowDeserializer;
|
||||
import com.github.prominence.openweathermap.api.model.weather.*;
|
||||
import com.github.prominence.openweathermap.api.enums.UnitSystem;
|
||||
import com.github.prominence.openweathermap.api.model.*;
|
||||
import com.github.prominence.openweathermap.api.model.weather.Location;
|
||||
import com.github.prominence.openweathermap.api.model.weather.Rain;
|
||||
import com.github.prominence.openweathermap.api.model.weather.Snow;
|
||||
import com.github.prominence.openweathermap.api.model.weather.Weather;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
* Official API response documentation: <a href="https://openweathermap.org/current#current_JSON">https://openweathermap.org/current#current_JSON</a>.
|
||||
@ -86,13 +85,7 @@ public class CurrentWeatherResponseMapper extends AbstractMapper {
|
||||
final JsonNode weatherArrayNode = rootNode.get("weather");
|
||||
final Weather weather = new Weather();
|
||||
|
||||
final List<WeatherState> weatherStateList = new ArrayList<>();
|
||||
if (weatherArrayNode != null && weatherArrayNode.isArray()) {
|
||||
for (JsonNode weatherNode : weatherArrayNode) {
|
||||
weatherStateList.add(objectMapper.readValue(objectMapper.treeAsTokens(weatherNode), WeatherState.class));
|
||||
}
|
||||
weather.setWeatherStates(weatherStateList);
|
||||
}
|
||||
weather.setWeatherStates(parseWeatherStates(weatherArrayNode));
|
||||
|
||||
weather.setTemperature(objectMapper.readValue(objectMapper.treeAsTokens(rootNode.get("main")), Temperature.class));
|
||||
weather.setAtmosphericPressure(objectMapper.readValue(objectMapper.treeAsTokens(rootNode.get("main")), AtmosphericPressure.class));
|
||||
|
||||
@ -22,33 +22,41 @@
|
||||
|
||||
package com.github.prominence.openweathermap.api.mapper;
|
||||
|
||||
import com.fasterxml.jackson.databind.InjectableValues;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.github.prominence.openweathermap.api.deserializer.HumidityDeserializer;
|
||||
import com.github.prominence.openweathermap.api.deserializer.WeatherStateDeserializer;
|
||||
import com.github.prominence.openweathermap.api.deserializer.WindDeserializer;
|
||||
import com.github.prominence.openweathermap.api.deserializer.forecast.daily.*;
|
||||
import com.github.prominence.openweathermap.api.enums.UnitSystem;
|
||||
import com.github.prominence.openweathermap.api.model.Clouds;
|
||||
import com.github.prominence.openweathermap.api.model.Coordinates;
|
||||
import com.github.prominence.openweathermap.api.model.Humidity;
|
||||
import com.github.prominence.openweathermap.api.model.WeatherState;
|
||||
import com.github.prominence.openweathermap.api.model.Wind;
|
||||
import com.github.prominence.openweathermap.api.model.forecast.daily.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.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: <a href="https://openweathermap.org/forecast16#JSON">https://openweathermap.org/forecast16#JSON</a>.
|
||||
*/
|
||||
public class DailyForecastResponseMapper {
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
private final UnitSystem unitSystem;
|
||||
|
||||
public class DailyForecastResponseMapper extends AbstractMapper {
|
||||
public DailyForecastResponseMapper(UnitSystem unitSystem) {
|
||||
this.unitSystem = unitSystem;
|
||||
objectMapper.setInjectableValues(new InjectableValues.Std().addValue("unitSystem", unitSystem != null ? unitSystem : UnitSystem.STANDARD));
|
||||
final SimpleModule module = new SimpleModule();
|
||||
module.addDeserializer(WeatherState.class, new WeatherStateDeserializer());
|
||||
module.addDeserializer(Temperature.class, new DailyForecastTemperatureDeserializer());
|
||||
module.addDeserializer(AtmosphericPressure.class, new DailyForecastAtmosphericPressureDeserializer());
|
||||
module.addDeserializer(Humidity.class, new HumidityDeserializer());
|
||||
module.addDeserializer(Clouds.class, new DailyForecastCloudsDeserializer());
|
||||
module.addDeserializer(Rain.class, new DailyForecastRainDeserializer());
|
||||
module.addDeserializer(Snow.class, new DailyForecastSnowDeserializer());
|
||||
module.addDeserializer(Wind.class, new WindDeserializer());
|
||||
module.addDeserializer(Location.class, new DailyForecastLocationDeserializer());
|
||||
objectMapper.registerModule(module);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -63,7 +71,7 @@ public class DailyForecastResponseMapper {
|
||||
final JsonNode root = objectMapper.readTree(json);
|
||||
forecast = mapToForecast(root);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Cannot parse Forecast response");
|
||||
throw new RuntimeException("Cannot parse Forecast response", e);
|
||||
}
|
||||
|
||||
return forecast;
|
||||
@ -71,7 +79,7 @@ public class DailyForecastResponseMapper {
|
||||
|
||||
private Forecast mapToForecast(JsonNode root) throws IOException {
|
||||
final Forecast forecast = new Forecast();
|
||||
forecast.setLocation(parseLocation(root.get("city")));
|
||||
forecast.setLocation(objectMapper.readValue(objectMapper.treeAsTokens(root.get("city")), Location.class));
|
||||
|
||||
final List<WeatherForecast> forecasts = new ArrayList<>(root.get("cnt").asInt());
|
||||
|
||||
@ -87,124 +95,25 @@ public class DailyForecastResponseMapper {
|
||||
|
||||
private WeatherForecast parseWeatherForecast(JsonNode rootNode) throws IOException {
|
||||
final WeatherForecast weatherForecast = new WeatherForecast();
|
||||
final JsonNode weatherArrayNode = rootNode.get("weather");
|
||||
if (weatherArrayNode != null) {
|
||||
final JsonNode weatherNode = weatherArrayNode.get(0);
|
||||
weatherForecast.setWeatherState(parseWeatherState(weatherNode));
|
||||
|
||||
weatherForecast.setForecastTime(parseDateTime(rootNode.get("dt")));
|
||||
weatherForecast.setSunriseTime(parseDateTime(rootNode.get("sunrise")));
|
||||
weatherForecast.setSunsetTime(parseDateTime(rootNode.get("sunset")));
|
||||
|
||||
weatherForecast.setWeatherStates(parseWeatherStates(rootNode.get("weather")));
|
||||
|
||||
weatherForecast.setTemperature(objectMapper.readValue(objectMapper.treeAsTokens(rootNode), Temperature.class));
|
||||
weatherForecast.setAtmosphericPressure(objectMapper.readValue(objectMapper.treeAsTokens(rootNode), AtmosphericPressure.class));
|
||||
weatherForecast.setHumidity(objectMapper.readValue(objectMapper.treeAsTokens(rootNode), Humidity.class));
|
||||
weatherForecast.setClouds(objectMapper.readValue(objectMapper.treeAsTokens(rootNode), Clouds.class));
|
||||
weatherForecast.setWind(objectMapper.readValue(objectMapper.treeAsTokens(rootNode), Wind.class));
|
||||
weatherForecast.setRain(objectMapper.readValue(objectMapper.treeAsTokens(rootNode), Rain.class));
|
||||
weatherForecast.setSnow(objectMapper.readValue(objectMapper.treeAsTokens(rootNode), Snow.class));
|
||||
|
||||
if (rootNode.has("pop")) {
|
||||
weatherForecast.setProbabilityOfPrecipitation(rootNode.get("pop").asDouble());
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
weatherForecast.setForecastTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(rootNode.get("dt").asLong()), TimeZone.getDefault().toZoneId()));
|
||||
|
||||
return weatherForecast;
|
||||
}
|
||||
|
||||
private WeatherState parseWeatherState(JsonNode weatherNode) throws IOException {
|
||||
if (weatherNode == null) {
|
||||
return null;
|
||||
}
|
||||
return objectMapper.readValue(objectMapper.treeAsTokens(weatherNode), WeatherState.class);
|
||||
}
|
||||
|
||||
private Temperature parseTemperature(JsonNode rootNode) {
|
||||
final Temperature temperature = new Temperature();
|
||||
final JsonNode tempNode = rootNode.get("temp");
|
||||
temperature.setMorning(tempNode.get("morn").asDouble());
|
||||
temperature.setDay(tempNode.get("day").asDouble());
|
||||
temperature.setEve(tempNode.get("eve").asDouble());
|
||||
temperature.setNight(tempNode.get("night").asDouble());
|
||||
temperature.setMin(tempNode.get("min").asDouble());
|
||||
temperature.setMax(tempNode.get("max").asDouble());
|
||||
|
||||
final JsonNode feelsLikeNode = rootNode.get("feels_like");
|
||||
temperature.setMorningFeelsLike(feelsLikeNode.get("morn").asDouble());
|
||||
temperature.setDayFeelsLike(feelsLikeNode.get("day").asDouble());
|
||||
temperature.setEveFeelsLike(feelsLikeNode.get("eve").asDouble());
|
||||
temperature.setNightFeelsLike(feelsLikeNode.get("night").asDouble());
|
||||
|
||||
return temperature;
|
||||
}
|
||||
|
||||
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 root) throws IOException {
|
||||
final JsonNode windNode = root.get("wind");
|
||||
return objectMapper.readValue(objectMapper.treeAsTokens(windNode), Wind.class);
|
||||
}
|
||||
|
||||
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 coordNode = rootNode.get("coord");
|
||||
if (coordNode != null) {
|
||||
location.setCoordinate(parseCoordinate(coordNode));
|
||||
}
|
||||
|
||||
return location;
|
||||
}
|
||||
|
||||
private Coordinates parseCoordinate(JsonNode rootNode) {
|
||||
final JsonNode latitudeNode = rootNode.get("lat");
|
||||
final JsonNode longitudeNode = rootNode.get("lon");
|
||||
if (latitudeNode != null && longitudeNode != null) {
|
||||
return Coordinates.of(latitudeNode.asDouble(), longitudeNode.asDouble());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,8 +28,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.github.prominence.openweathermap.api.deserializer.GeocodingRecordDeserializer;
|
||||
import com.github.prominence.openweathermap.api.deserializer.ZipCodeGeocodingDeserializer;
|
||||
import com.github.prominence.openweathermap.api.model.geocoding.ZipCodeGeocodingRecord;
|
||||
import com.github.prominence.openweathermap.api.model.geocoding.GeocodingRecord;
|
||||
import com.github.prominence.openweathermap.api.model.geocoding.ZipCodeGeocodingRecord;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Alexey Zinchenko
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.github.prominence.openweathermap.api.model.forecast.climatic;
|
||||
|
||||
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 seaLevelValue;
|
||||
|
||||
protected AtmosphericPressure() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method for {@link AtmosphericPressure} creation with value checking.
|
||||
* @param seaLevelValue atmospheric pressure value.
|
||||
* @return instantiated {@link AtmosphericPressure} object.
|
||||
*/
|
||||
public static AtmosphericPressure withValue(double seaLevelValue) {
|
||||
final AtmosphericPressure atmosphericPressure = new AtmosphericPressure();
|
||||
atmosphericPressure.setSeaLevelValue(seaLevelValue);
|
||||
return atmosphericPressure;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 == null || getClass() != o.getClass()) return false;
|
||||
AtmosphericPressure that = (AtmosphericPressure) o;
|
||||
return Double.compare(that.seaLevelValue, seaLevelValue) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(seaLevelValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Pressure: " + seaLevelValue + ' ' + getUnit();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Alexey Zinchenko
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.github.prominence.openweathermap.api.model.forecast.climatic;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Represents information about forecast for different timestamps.
|
||||
*/
|
||||
public class Forecast {
|
||||
private Location location;
|
||||
private List<? extends 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<? extends WeatherForecast> getWeatherForecasts() {
|
||||
return weatherForecasts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets list of weather forecasts for different timestamps.
|
||||
* @param weatherForecasts list of forecast information
|
||||
*/
|
||||
public void setWeatherForecasts(List<? extends 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.";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,198 @@
|
||||
/*
|
||||
* 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.model.forecast.climatic;
|
||||
|
||||
import com.github.prominence.openweathermap.api.model.Coordinates;
|
||||
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Represents location information.
|
||||
*/
|
||||
public class Location {
|
||||
private int id;
|
||||
private String name;
|
||||
private String countryCode;
|
||||
|
||||
private ZoneOffset zoneOffset;
|
||||
|
||||
private Coordinates coordinates;
|
||||
|
||||
private Long population;
|
||||
|
||||
protected 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 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 Coordinates getCoordinate() {
|
||||
return coordinates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets location coordinates.
|
||||
* @param coordinates location coordinates
|
||||
*/
|
||||
public void setCoordinate(Coordinates coordinates) {
|
||||
this.coordinates = coordinates;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(zoneOffset, location.zoneOffset) &&
|
||||
Objects.equals(coordinates, location.coordinates) &&
|
||||
Objects.equals(population, location.population);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, name, countryCode, zoneOffset, coordinates, population);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder stringBuilder = new StringBuilder();
|
||||
if (coordinates != null) {
|
||||
stringBuilder.append(coordinates);
|
||||
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,97 @@
|
||||
/*
|
||||
* 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.model.forecast.climatic;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Represents rain information.
|
||||
*/
|
||||
public class Rain {
|
||||
private static final String DEFAULT_UNIT = "mm";
|
||||
|
||||
private double level;
|
||||
|
||||
protected Rain(double level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates {@link Rain} object with correctness check.
|
||||
* @param level rain level value
|
||||
* @return rain object.
|
||||
*/
|
||||
public static Rain withValue(double level) {
|
||||
if (level < 0) {
|
||||
throw new IllegalArgumentException("Rain level value cannot be negative.");
|
||||
}
|
||||
return new Rain(level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns rain level value.
|
||||
* @return rain level value
|
||||
*/
|
||||
public double getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets rain level value with correctness check.
|
||||
* @param level rain level value
|
||||
*/
|
||||
public void setLevel(double level) {
|
||||
if (level < 0) {
|
||||
throw new IllegalArgumentException("Rain level value cannot be negative.");
|
||||
}
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.level, level) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Rain precipitation volume, mm: " +
|
||||
level + ' ' +
|
||||
getUnit();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* 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.model.forecast.climatic;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Represents snow information.
|
||||
*/
|
||||
public class Snow {
|
||||
private static final String DEFAULT_UNIT = "mm";
|
||||
|
||||
private double level;
|
||||
|
||||
protected Snow(double level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates {@link Snow} object with correctness check.
|
||||
* @param threeHourLevel snow level value
|
||||
* @return snow object.
|
||||
*/
|
||||
public static Snow withValue(double threeHourLevel) {
|
||||
if (threeHourLevel < 0) {
|
||||
throw new IllegalArgumentException("Snow level value cannot be negative.");
|
||||
}
|
||||
return new Snow(threeHourLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns snow level value.
|
||||
* @return snow level value
|
||||
*/
|
||||
public double getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets snow level value with correctness check.
|
||||
* @param level snow level value
|
||||
*/
|
||||
public void setLevel(double level) {
|
||||
if (level < 0) {
|
||||
throw new IllegalArgumentException("Snow level value cannot be negative.");
|
||||
}
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.level, level) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Snow volume, mm: " +
|
||||
level + ' ' +
|
||||
getUnit();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,263 @@
|
||||
/*
|
||||
* 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.climatic;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* The type Daily temperature.
|
||||
*/
|
||||
public class Temperature {
|
||||
private Double morning;
|
||||
private Double morningFeelsLike;
|
||||
private Double day;
|
||||
private Double dayFeelsLike;
|
||||
private Double eve;
|
||||
private Double eveFeelsLike;
|
||||
private Double night;
|
||||
private Double nightFeelsLike;
|
||||
private Double min;
|
||||
private Double max;
|
||||
private String unit;
|
||||
|
||||
/**
|
||||
* Gets morning temperature.
|
||||
*
|
||||
* @return the morning
|
||||
*/
|
||||
public Double getMorning() {
|
||||
return morning;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets morning temperature.
|
||||
*
|
||||
* @param morning the morning
|
||||
*/
|
||||
public void setMorning(Double morning) {
|
||||
this.morning = morning;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets morning feels like temperature.
|
||||
*
|
||||
* @return the morning feels like temperature
|
||||
*/
|
||||
public Double getMorningFeelsLike() {
|
||||
return morningFeelsLike;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets morning feels like temperature.
|
||||
*
|
||||
* @param morningFeelsLike the morning feels like temperature
|
||||
*/
|
||||
public void setMorningFeelsLike(Double morningFeelsLike) {
|
||||
this.morningFeelsLike = morningFeelsLike;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets day temperature.
|
||||
*
|
||||
* @return the day temperature
|
||||
*/
|
||||
public Double getDay() {
|
||||
return day;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets day temperature.
|
||||
*
|
||||
* @param day the day temperature
|
||||
*/
|
||||
public void setDay(Double day) {
|
||||
this.day = day;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets day feels like temperature.
|
||||
*
|
||||
* @return the day feels like temperature
|
||||
*/
|
||||
public Double getDayFeelsLike() {
|
||||
return dayFeelsLike;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets day feels like temperature.
|
||||
*
|
||||
* @param dayFeelsLike the day feels like temperature
|
||||
*/
|
||||
public void setDayFeelsLike(Double dayFeelsLike) {
|
||||
this.dayFeelsLike = dayFeelsLike;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets eve temperature.
|
||||
*
|
||||
* @return the eve temperature
|
||||
*/
|
||||
public Double getEve() {
|
||||
return eve;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets eve temperature.
|
||||
*
|
||||
* @param eve the eve temperature
|
||||
*/
|
||||
public void setEve(Double eve) {
|
||||
this.eve = eve;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets eve feels like temperature.
|
||||
*
|
||||
* @return the eve feels like temperature
|
||||
*/
|
||||
public Double getEveFeelsLike() {
|
||||
return eveFeelsLike;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets eve feels like temperature.
|
||||
*
|
||||
* @param eveFeelsLike the eve feels like temperature
|
||||
*/
|
||||
public void setEveFeelsLike(Double eveFeelsLike) {
|
||||
this.eveFeelsLike = eveFeelsLike;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets night temperature.
|
||||
*
|
||||
* @return the night temperature
|
||||
*/
|
||||
public Double getNight() {
|
||||
return night;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets night temperature.
|
||||
*
|
||||
* @param night the night temperature
|
||||
*/
|
||||
public void setNight(Double night) {
|
||||
this.night = night;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets night feels like temperature.
|
||||
*
|
||||
* @return the night feels like temperature
|
||||
*/
|
||||
public Double getNightFeelsLike() {
|
||||
return nightFeelsLike;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets night feels like temperature.
|
||||
*
|
||||
* @param nightFeelsLike the night feels like temperature
|
||||
*/
|
||||
public void setNightFeelsLike(Double nightFeelsLike) {
|
||||
this.nightFeelsLike = nightFeelsLike;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets min temperature.
|
||||
*
|
||||
* @return the min temperature
|
||||
*/
|
||||
public Double getMin() {
|
||||
return min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets min temperature.
|
||||
*
|
||||
* @param min the min temperature
|
||||
*/
|
||||
public void setMin(Double min) {
|
||||
this.min = min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets max temperature.
|
||||
*
|
||||
* @return the max temperature
|
||||
*/
|
||||
public Double getMax() {
|
||||
return max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets max temperature.
|
||||
*
|
||||
* @param max the max temperature
|
||||
*/
|
||||
public void setMax(Double max) {
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets unit temperature.
|
||||
*
|
||||
* @return the unit temperature
|
||||
*/
|
||||
public String getUnit() {
|
||||
return unit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets unit temperature.
|
||||
*
|
||||
* @param unit the unit temperature
|
||||
*/
|
||||
public void setUnit(String unit) {
|
||||
this.unit = unit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Temperature that = (Temperature) o;
|
||||
return Objects.equals(morning, that.morning) &&
|
||||
Objects.equals(morningFeelsLike, that.morningFeelsLike) &&
|
||||
Objects.equals(day, that.day) &&
|
||||
Objects.equals(dayFeelsLike, that.dayFeelsLike) &&
|
||||
Objects.equals(eve, that.eve) &&
|
||||
Objects.equals(eveFeelsLike, that.eveFeelsLike) &&
|
||||
Objects.equals(night, that.night) &&
|
||||
Objects.equals(nightFeelsLike, that.nightFeelsLike) &&
|
||||
Objects.equals(min, that.min) &&
|
||||
Objects.equals(max, that.max) &&
|
||||
Objects.equals(unit, that.unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(morning, morningFeelsLike, day, dayFeelsLike, eve, eveFeelsLike, night, nightFeelsLike, min, max, unit);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,295 @@
|
||||
/*
|
||||
* 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.model.forecast.climatic;
|
||||
|
||||
|
||||
import com.github.prominence.openweathermap.api.model.Clouds;
|
||||
import com.github.prominence.openweathermap.api.model.Humidity;
|
||||
import com.github.prominence.openweathermap.api.model.WeatherState;
|
||||
import com.github.prominence.openweathermap.api.model.Wind;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Represents weather forecast information for a particular timestamp.
|
||||
*/
|
||||
public class WeatherForecast {
|
||||
private LocalDateTime forecastTime;
|
||||
private LocalDateTime sunriseTime;
|
||||
private LocalDateTime sunsetTime;
|
||||
|
||||
private List<WeatherState> weatherStates;
|
||||
private Temperature temperature;
|
||||
private AtmosphericPressure atmosphericPressure;
|
||||
private Humidity humidity;
|
||||
|
||||
private Wind wind;
|
||||
private Rain rain;
|
||||
private Snow snow;
|
||||
private Clouds clouds;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
public LocalDateTime getSunriseTime() {
|
||||
return sunriseTime;
|
||||
}
|
||||
|
||||
public void setSunriseTime(LocalDateTime sunriseTime) {
|
||||
this.sunriseTime = sunriseTime;
|
||||
}
|
||||
|
||||
public LocalDateTime getSunsetTime() {
|
||||
return sunsetTime;
|
||||
}
|
||||
|
||||
public void setSunsetTime(LocalDateTime sunsetTime) {
|
||||
this.sunsetTime = sunsetTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets weather state.
|
||||
*
|
||||
* @return the weather state
|
||||
*/
|
||||
public List<WeatherState> getWeatherStates() {
|
||||
return weatherStates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets weather state.
|
||||
*
|
||||
* @param weatherStates the weather state
|
||||
*/
|
||||
public void setWeatherStates(List<WeatherState> weatherStates) {
|
||||
this.weatherStates = weatherStates;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
@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(sunriseTime, that.sunriseTime) &&
|
||||
Objects.equals(sunsetTime, that.sunsetTime) &&
|
||||
Objects.equals(weatherStates, that.weatherStates) &&
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(forecastTime, sunriseTime, sunsetTime, weatherStates, temperature, atmosphericPressure, humidity, wind, rain, snow, clouds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.append("Timestamp: ");
|
||||
stringBuilder.append(forecastTime);
|
||||
if (weatherStates != null && weatherStates.size() > 0) {
|
||||
stringBuilder.append(", Weather: ");
|
||||
stringBuilder.append(weatherStates.get(0).getDescription());
|
||||
}
|
||||
if (temperature != null) {
|
||||
stringBuilder.append(", Min temperature: ");
|
||||
stringBuilder.append(temperature.getMin());
|
||||
stringBuilder.append(temperature.getUnit());
|
||||
stringBuilder.append(", Max temperature: ");
|
||||
stringBuilder.append(temperature.getMax());
|
||||
stringBuilder.append(temperature.getUnit());
|
||||
}
|
||||
if (atmosphericPressure != null) {
|
||||
stringBuilder.append(", ");
|
||||
stringBuilder.append(atmosphericPressure.getSeaLevelValue());
|
||||
stringBuilder.append(' ');
|
||||
stringBuilder.append(atmosphericPressure.getUnit());
|
||||
}
|
||||
if (clouds != null) {
|
||||
stringBuilder.append(", ");
|
||||
stringBuilder.append(clouds);
|
||||
}
|
||||
if (rain != null) {
|
||||
stringBuilder.append(", Rain: ");
|
||||
stringBuilder.append(rain.getLevel());
|
||||
stringBuilder.append(' ');
|
||||
stringBuilder.append(rain.getUnit());
|
||||
}
|
||||
if (snow != null) {
|
||||
stringBuilder.append(", Snow: ");
|
||||
stringBuilder.append(snow.getLevel());
|
||||
stringBuilder.append(' ');
|
||||
stringBuilder.append(snow.getUnit());
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* 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.model.forecast.climatic;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* The type Wind.
|
||||
*/
|
||||
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 speed
|
||||
* @param unit the unitSystem
|
||||
* @return wind object
|
||||
*/
|
||||
public static Wind withValue(double speed, String unit) {
|
||||
if (speed < 0) {
|
||||
throw new IllegalArgumentException("Wind speed value must be in positive or zero.");
|
||||
}
|
||||
if (unit == null) {
|
||||
throw new IllegalArgumentException("Unit must be set.");
|
||||
}
|
||||
return new Wind(speed, unit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets speed.
|
||||
*
|
||||
* @return the speed
|
||||
*/
|
||||
public double getSpeed() {
|
||||
return speed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets speed.
|
||||
*
|
||||
* @param speed the speed
|
||||
*/
|
||||
public void setSpeed(double speed) {
|
||||
if (speed < 0) {
|
||||
throw new IllegalArgumentException("Wind speed value must be in positive or zero.");
|
||||
}
|
||||
this.speed = speed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets 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;
|
||||
}
|
||||
}
|
||||
@ -33,7 +33,7 @@ public class AtmosphericPressure {
|
||||
|
||||
private double seaLevelValue;
|
||||
|
||||
private AtmosphericPressure() {
|
||||
protected AtmosphericPressure() {
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -31,7 +31,7 @@ import java.util.Objects;
|
||||
*/
|
||||
public class Forecast {
|
||||
private Location location;
|
||||
private List<WeatherForecast> weatherForecasts;
|
||||
private List<? extends WeatherForecast> weatherForecasts;
|
||||
|
||||
/**
|
||||
* Returns location information.
|
||||
@ -53,7 +53,7 @@ public class Forecast {
|
||||
* Returns list of weather forecasts for different timestamps.
|
||||
* @return list of forecast-per-timestamp information.
|
||||
*/
|
||||
public List<WeatherForecast> getWeatherForecasts() {
|
||||
public List<? extends WeatherForecast> getWeatherForecasts() {
|
||||
return weatherForecasts;
|
||||
}
|
||||
|
||||
@ -61,7 +61,7 @@ public class Forecast {
|
||||
* Sets list of weather forecasts for different timestamps.
|
||||
* @param weatherForecasts list of forecast information
|
||||
*/
|
||||
public void setWeatherForecasts(List<WeatherForecast> weatherForecasts) {
|
||||
public void setWeatherForecasts(List<? extends WeatherForecast> weatherForecasts) {
|
||||
this.weatherForecasts = weatherForecasts;
|
||||
}
|
||||
|
||||
|
||||
@ -41,7 +41,7 @@ public class Location {
|
||||
|
||||
private Long population;
|
||||
|
||||
private Location(int id, String name) {
|
||||
protected Location(int id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@ -32,33 +32,33 @@ public class Rain {
|
||||
|
||||
private double level;
|
||||
|
||||
private Rain(double level) {
|
||||
protected Rain(double level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates {@link Rain} object with correctness check.
|
||||
* @param threeHourLevel 3-hour rain level value
|
||||
* @param level rain level value
|
||||
* @return rain object.
|
||||
*/
|
||||
public static Rain withThreeHourLevelValue(double threeHourLevel) {
|
||||
if (threeHourLevel < 0) {
|
||||
public static Rain withValue(double level) {
|
||||
if (level < 0) {
|
||||
throw new IllegalArgumentException("Rain level value cannot be negative.");
|
||||
}
|
||||
return new Rain(threeHourLevel);
|
||||
return new Rain(level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 3-hour rain level value.
|
||||
* @return 3-hour rain level value
|
||||
* Returns rain level value.
|
||||
* @return rain level value
|
||||
*/
|
||||
public double getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets 3-hour rain level value with correctness check.
|
||||
* @param level 3-hour rain level value
|
||||
* Sets rain level value with correctness check.
|
||||
* @param level rain level value
|
||||
*/
|
||||
public void setLevel(double level) {
|
||||
if (level < 0) {
|
||||
@ -68,7 +68,7 @@ public class Rain {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns rain level unit of measure. Currently is constant.
|
||||
* Returns rain level unit of measure. Currently, is constant.
|
||||
* @return rain level unit of measure
|
||||
*/
|
||||
public String getUnit() {
|
||||
@ -90,7 +90,7 @@ public class Rain {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "3-hour rain level: " +
|
||||
return "Rain precipitation volume, mm: " +
|
||||
level + ' ' +
|
||||
getUnit();
|
||||
}
|
||||
|
||||
@ -32,16 +32,16 @@ public class Snow {
|
||||
|
||||
private double level;
|
||||
|
||||
private Snow(double level) {
|
||||
protected Snow(double level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates {@link Snow} object with correctness check.
|
||||
* @param threeHourLevel 3-hour snow level value
|
||||
* @param threeHourLevel snow level value
|
||||
* @return snow object.
|
||||
*/
|
||||
public static Snow withThreeHourLevelValue(double threeHourLevel) {
|
||||
public static Snow withValue(double threeHourLevel) {
|
||||
if (threeHourLevel < 0) {
|
||||
throw new IllegalArgumentException("Snow level value cannot be negative.");
|
||||
}
|
||||
@ -49,16 +49,16 @@ public class Snow {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 3-hour snow level value.
|
||||
* @return 3-hour snow level value
|
||||
* Returns snow level value.
|
||||
* @return snow level value
|
||||
*/
|
||||
public double getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets 3-hour snow level value with correctness check.
|
||||
* @param level 3-hour snow level value
|
||||
* Sets snow level value with correctness check.
|
||||
* @param level snow level value
|
||||
*/
|
||||
public void setLevel(double level) {
|
||||
if (level < 0) {
|
||||
@ -68,7 +68,7 @@ public class Snow {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns snow level unit of measure. Currently is constant.
|
||||
* Returns snow level unit of measure. Currently, is constant.
|
||||
* @return snow level unit of measure
|
||||
*/
|
||||
public String getUnit() {
|
||||
@ -90,7 +90,7 @@ public class Snow {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "3-hour snow level: " +
|
||||
return "Snow volume, mm: " +
|
||||
level + ' ' +
|
||||
getUnit();
|
||||
}
|
||||
|
||||
@ -29,6 +29,7 @@ import com.github.prominence.openweathermap.api.model.WeatherState;
|
||||
import com.github.prominence.openweathermap.api.model.Wind;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
@ -36,12 +37,10 @@ import java.util.Objects;
|
||||
*/
|
||||
public class WeatherForecast {
|
||||
private LocalDateTime forecastTime;
|
||||
|
||||
private LocalDateTime sunriseTime;
|
||||
|
||||
private LocalDateTime sunsetTime;
|
||||
|
||||
private WeatherState weatherState;
|
||||
private List<WeatherState> weatherStates;
|
||||
private Temperature temperature;
|
||||
private AtmosphericPressure atmosphericPressure;
|
||||
private Humidity humidity;
|
||||
@ -51,6 +50,8 @@ public class WeatherForecast {
|
||||
private Snow snow;
|
||||
private Clouds clouds;
|
||||
|
||||
private Double probabilityOfPrecipitation;
|
||||
|
||||
/**
|
||||
* Gets forecast time.
|
||||
*
|
||||
@ -69,22 +70,38 @@ public class WeatherForecast {
|
||||
this.forecastTime = forecastTime;
|
||||
}
|
||||
|
||||
public LocalDateTime getSunriseTime() {
|
||||
return sunriseTime;
|
||||
}
|
||||
|
||||
public void setSunriseTime(LocalDateTime sunriseTime) {
|
||||
this.sunriseTime = sunriseTime;
|
||||
}
|
||||
|
||||
public LocalDateTime getSunsetTime() {
|
||||
return sunsetTime;
|
||||
}
|
||||
|
||||
public void setSunsetTime(LocalDateTime sunsetTime) {
|
||||
this.sunsetTime = sunsetTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets weather state.
|
||||
*
|
||||
* @return the weather state
|
||||
*/
|
||||
public WeatherState getWeatherState() {
|
||||
return weatherState;
|
||||
public List<WeatherState> getWeatherStates() {
|
||||
return weatherStates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets weather state.
|
||||
*
|
||||
* @param weatherState the weather state
|
||||
* @param weatherStates the weather state
|
||||
*/
|
||||
public void setWeatherState(WeatherState weatherState) {
|
||||
this.weatherState = weatherState;
|
||||
public void setWeatherStates(List<WeatherState> weatherStates) {
|
||||
this.weatherStates = weatherStates;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -213,25 +230,36 @@ public class WeatherForecast {
|
||||
this.clouds = clouds;
|
||||
}
|
||||
|
||||
public Double getProbabilityOfPrecipitation() {
|
||||
return probabilityOfPrecipitation;
|
||||
}
|
||||
|
||||
public void setProbabilityOfPrecipitation(Double probabilityOfPrecipitation) {
|
||||
this.probabilityOfPrecipitation = probabilityOfPrecipitation;
|
||||
}
|
||||
|
||||
@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(sunriseTime, that.sunriseTime) &&
|
||||
Objects.equals(sunsetTime, that.sunsetTime) &&
|
||||
Objects.equals(weatherStates, that.weatherStates) &&
|
||||
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(clouds, that.clouds) &&
|
||||
Objects.equals(probabilityOfPrecipitation, that.probabilityOfPrecipitation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(forecastTime, weatherState, temperature, atmosphericPressure, humidity, wind, rain, snow, clouds);
|
||||
return Objects.hash(forecastTime, sunriseTime, sunsetTime, weatherStates, temperature, atmosphericPressure, humidity, wind, rain, snow, clouds, probabilityOfPrecipitation);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -239,9 +267,9 @@ public class WeatherForecast {
|
||||
final StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.append("Timestamp: ");
|
||||
stringBuilder.append(forecastTime);
|
||||
if (weatherState != null) {
|
||||
if (weatherStates != null && weatherStates.size() > 0) {
|
||||
stringBuilder.append(", Weather: ");
|
||||
stringBuilder.append(weatherState.getDescription());
|
||||
stringBuilder.append(weatherStates.get(0).getDescription());
|
||||
}
|
||||
if (temperature != null) {
|
||||
stringBuilder.append(", Min temperature: ");
|
||||
@ -259,7 +287,7 @@ public class WeatherForecast {
|
||||
}
|
||||
if (clouds != null) {
|
||||
stringBuilder.append(", ");
|
||||
stringBuilder.append(clouds.toString());
|
||||
stringBuilder.append(clouds);
|
||||
}
|
||||
if (rain != null) {
|
||||
stringBuilder.append(", Rain: ");
|
||||
|
||||
@ -23,7 +23,6 @@
|
||||
package com.github.prominence.openweathermap.api.model.forecast.free;
|
||||
|
||||
import com.github.prominence.openweathermap.api.model.*;
|
||||
import com.github.prominence.openweathermap.api.model.Wind;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Objects;
|
||||
|
||||
@ -23,7 +23,6 @@
|
||||
package com.github.prominence.openweathermap.api.model.forecast.hourly;
|
||||
|
||||
import com.github.prominence.openweathermap.api.model.*;
|
||||
import com.github.prominence.openweathermap.api.model.Wind;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@ -25,8 +25,8 @@ package com.github.prominence.openweathermap.api.model.onecall.current;
|
||||
import com.github.prominence.openweathermap.api.model.Clouds;
|
||||
import com.github.prominence.openweathermap.api.model.Humidity;
|
||||
import com.github.prominence.openweathermap.api.model.WeatherState;
|
||||
import com.github.prominence.openweathermap.api.model.onecall.AtmosphericPressure;
|
||||
import com.github.prominence.openweathermap.api.model.Wind;
|
||||
import com.github.prominence.openweathermap.api.model.onecall.AtmosphericPressure;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@ -26,7 +26,10 @@ import com.github.prominence.openweathermap.api.model.Clouds;
|
||||
import com.github.prominence.openweathermap.api.model.Humidity;
|
||||
import com.github.prominence.openweathermap.api.model.WeatherState;
|
||||
import com.github.prominence.openweathermap.api.model.Wind;
|
||||
import com.github.prominence.openweathermap.api.model.onecall.*;
|
||||
import com.github.prominence.openweathermap.api.model.onecall.AtmosphericPressure;
|
||||
import com.github.prominence.openweathermap.api.model.onecall.Rain;
|
||||
import com.github.prominence.openweathermap.api.model.onecall.Snow;
|
||||
import com.github.prominence.openweathermap.api.model.onecall.Temperature;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
|
||||
package com.github.prominence.openweathermap.api.model.onecall.historical;
|
||||
|
||||
import com.github.prominence.openweathermap.api.model.onecall.*;
|
||||
import com.github.prominence.openweathermap.api.model.onecall.Current;
|
||||
|
||||
/**
|
||||
* The type Historical weather.
|
||||
|
||||
@ -26,7 +26,10 @@ import com.github.prominence.openweathermap.api.model.Clouds;
|
||||
import com.github.prominence.openweathermap.api.model.Humidity;
|
||||
import com.github.prominence.openweathermap.api.model.WeatherState;
|
||||
import com.github.prominence.openweathermap.api.model.Wind;
|
||||
import com.github.prominence.openweathermap.api.model.onecall.*;
|
||||
import com.github.prominence.openweathermap.api.model.onecall.AtmosphericPressure;
|
||||
import com.github.prominence.openweathermap.api.model.onecall.Rain;
|
||||
import com.github.prominence.openweathermap.api.model.onecall.Snow;
|
||||
import com.github.prominence.openweathermap.api.model.onecall.Temperature;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Alexey Zinchenko
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.github.prominence.openweathermap.api.request.forecast.climatic;
|
||||
|
||||
import com.github.prominence.openweathermap.api.enums.ResponseType;
|
||||
import com.github.prominence.openweathermap.api.mapper.ClimaticForecastResponseMapper;
|
||||
import com.github.prominence.openweathermap.api.model.forecast.climatic.Forecast;
|
||||
import com.github.prominence.openweathermap.api.request.RequestSettings;
|
||||
import com.github.prominence.openweathermap.api.utils.RequestUtils;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
class ClimaticForecastAsyncRequestTerminator {
|
||||
private final RequestSettings requestSettings;
|
||||
|
||||
ClimaticForecastAsyncRequestTerminator(RequestSettings requestSettings) {
|
||||
this.requestSettings = requestSettings;
|
||||
}
|
||||
|
||||
public CompletableFuture<Forecast> asJava() {
|
||||
return CompletableFuture.supplyAsync(() -> new ClimaticForecastResponseMapper(requestSettings.getUnitSystem()).mapToForecast(getRawResponse()));
|
||||
}
|
||||
|
||||
public CompletableFuture<String> asJSON() {
|
||||
return CompletableFuture.supplyAsync(this::getRawResponse);
|
||||
}
|
||||
|
||||
public CompletableFuture<String> asXML() {
|
||||
requestSettings.setResponseType(ResponseType.XML);
|
||||
return CompletableFuture.supplyAsync(this::getRawResponse);
|
||||
}
|
||||
|
||||
private String getRawResponse() {
|
||||
return RequestUtils.getResponse(requestSettings);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
package com.github.prominence.openweathermap.api.request.forecast.climatic;
|
||||
|
||||
import com.github.prominence.openweathermap.api.enums.Language;
|
||||
import com.github.prominence.openweathermap.api.enums.UnitSystem;
|
||||
import com.github.prominence.openweathermap.api.request.RequestSettings;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class ClimaticForecastRequestCustomizer {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ClimaticForecastRequestCustomizer.class);
|
||||
|
||||
private final RequestSettings requestSettings;
|
||||
|
||||
public ClimaticForecastRequestCustomizer(RequestSettings requestSettings) {
|
||||
this.requestSettings = requestSettings;
|
||||
}
|
||||
|
||||
public ClimaticForecastRequestCustomizer language(Language language) {
|
||||
requestSettings.setLanguage(language);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClimaticForecastRequestCustomizer unitSystem(UnitSystem unitSystem) {
|
||||
requestSettings.setUnitSystem(unitSystem);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClimaticForecastRequestCustomizer numberOfDays(int numberOfDays) {
|
||||
int days = numberOfDays;
|
||||
if (days > 30) {
|
||||
logger.warn("Cannot use more than 30 days for this API request. Please, specify 30 or less days. !!! Requesting information for 30 days...");
|
||||
days = 30;
|
||||
}
|
||||
requestSettings.putRequestParameter("cnt", Integer.toString(days));
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClimaticForecastRequestTerminator retrieve() {
|
||||
return new ClimaticForecastRequestTerminator(requestSettings);
|
||||
}
|
||||
|
||||
public ClimaticForecastAsyncRequestTerminator retrieveAsync() {
|
||||
return new ClimaticForecastAsyncRequestTerminator(requestSettings);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Alexey Zinchenko
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.github.prominence.openweathermap.api.request.forecast.climatic;
|
||||
|
||||
import com.github.prominence.openweathermap.api.enums.ResponseType;
|
||||
import com.github.prominence.openweathermap.api.mapper.ClimaticForecastResponseMapper;
|
||||
import com.github.prominence.openweathermap.api.model.forecast.climatic.Forecast;
|
||||
import com.github.prominence.openweathermap.api.request.RequestSettings;
|
||||
import com.github.prominence.openweathermap.api.utils.RequestUtils;
|
||||
|
||||
class ClimaticForecastRequestTerminator {
|
||||
private final RequestSettings requestSettings;
|
||||
|
||||
ClimaticForecastRequestTerminator(RequestSettings requestSettings) {
|
||||
this.requestSettings = requestSettings;
|
||||
}
|
||||
|
||||
public Forecast asJava() {
|
||||
return new ClimaticForecastResponseMapper(requestSettings.getUnitSystem()).mapToForecast(getRawResponse());
|
||||
}
|
||||
|
||||
public String asJSON() {
|
||||
return getRawResponse();
|
||||
}
|
||||
|
||||
public String asXML() {
|
||||
requestSettings.setResponseType(ResponseType.XML);
|
||||
return getRawResponse();
|
||||
}
|
||||
|
||||
private String getRawResponse() {
|
||||
return RequestUtils.getResponse(requestSettings);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
package com.github.prominence.openweathermap.api.request.forecast.climatic;
|
||||
|
||||
import com.github.prominence.openweathermap.api.model.Coordinates;
|
||||
import com.github.prominence.openweathermap.api.request.RequestSettings;
|
||||
|
||||
public class ClimaticForecastRequester {
|
||||
private final RequestSettings requestSettings;
|
||||
|
||||
public ClimaticForecastRequester(RequestSettings requestSettings) {
|
||||
this.requestSettings = requestSettings;
|
||||
this.requestSettings.setSubdomain("pro");
|
||||
this.requestSettings.appendToURL("data/2.5/forecast/climate");
|
||||
}
|
||||
|
||||
public ClimaticForecastRequestCustomizer byCoordinates(Coordinates coordinates) {
|
||||
requestSettings.putRequestParameter("lat", String.valueOf(coordinates.getLatitude()));
|
||||
requestSettings.putRequestParameter("lon", String.valueOf(coordinates.getLongitude()));
|
||||
return new ClimaticForecastRequestCustomizer(requestSettings);
|
||||
}
|
||||
}
|
||||
@ -50,7 +50,7 @@ class DailyForecastRequestCustomizer {
|
||||
public DailyForecastRequestCustomizer numberOfDays(int numberOfDays) {
|
||||
int days = numberOfDays;
|
||||
if (days > 16) {
|
||||
logger.warn("Cannot use more than 16 days for this api request. Please, specify 16 or less days. !!! Requesting information for 16 days...");
|
||||
logger.warn("Cannot use more than 16 days for this API request. Please, specify 16 or less days. !!! Requesting information for 16 days...");
|
||||
days = 16;
|
||||
}
|
||||
requestSettings.putRequestParameter("cnt", Integer.toString(days));
|
||||
|
||||
@ -30,7 +30,7 @@ public class DailyForecastRequester {
|
||||
|
||||
public DailyForecastRequester(RequestSettings requestSettings) {
|
||||
this.requestSettings = requestSettings;
|
||||
this.requestSettings.appendToURL("data/2.5/forecast/hourly");
|
||||
this.requestSettings.appendToURL("data/2.5/forecast/daily");
|
||||
}
|
||||
|
||||
public DailyForecastRequestCustomizer byCoordinates(Coordinates coordinates) {
|
||||
|
||||
@ -23,8 +23,6 @@
|
||||
package com.github.prominence.openweathermap.api.request.geocoding.direct;
|
||||
|
||||
import com.github.prominence.openweathermap.api.request.RequestSettings;
|
||||
import com.github.prominence.openweathermap.api.request.geocoding.reverse.ReverseGeocodingRequestAsyncTerminator;
|
||||
import com.github.prominence.openweathermap.api.request.geocoding.reverse.ReverseGeocodingRequestTerminator;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
|
||||
@ -23,9 +23,9 @@
|
||||
package com.github.prominence.openweathermap.api.request.weather;
|
||||
|
||||
import com.github.prominence.openweathermap.api.enums.ResponseType;
|
||||
import com.github.prominence.openweathermap.api.request.RequestSettings;
|
||||
import com.github.prominence.openweathermap.api.mapper.CurrentWeatherResponseMapper;
|
||||
import com.github.prominence.openweathermap.api.model.weather.Weather;
|
||||
import com.github.prominence.openweathermap.api.request.RequestSettings;
|
||||
import com.github.prominence.openweathermap.api.utils.RequestUtils;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@ -23,9 +23,9 @@
|
||||
package com.github.prominence.openweathermap.api.request.weather;
|
||||
|
||||
import com.github.prominence.openweathermap.api.enums.ResponseType;
|
||||
import com.github.prominence.openweathermap.api.mapper.CurrentWeatherResponseMapper;
|
||||
import com.github.prominence.openweathermap.api.model.weather.Weather;
|
||||
import com.github.prominence.openweathermap.api.request.RequestSettings;
|
||||
import com.github.prominence.openweathermap.api.mapper.CurrentWeatherResponseMapper;
|
||||
import com.github.prominence.openweathermap.api.utils.RequestUtils;
|
||||
|
||||
/**
|
||||
|
||||
@ -23,8 +23,8 @@
|
||||
package com.github.prominence.openweathermap.api.utils;
|
||||
|
||||
import com.github.prominence.openweathermap.api.conf.TimeoutSettings;
|
||||
import com.github.prominence.openweathermap.api.exception.NoDataFoundException;
|
||||
import com.github.prominence.openweathermap.api.exception.InvalidAuthTokenException;
|
||||
import com.github.prominence.openweathermap.api.exception.NoDataFoundException;
|
||||
import com.github.prominence.openweathermap.api.request.RequestSettings;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -0,0 +1,126 @@
|
||||
package com.github.prominence.openweathermap.api.mapper;
|
||||
|
||||
import com.github.prominence.openweathermap.api.enums.UnitSystem;
|
||||
import com.github.prominence.openweathermap.api.model.Wind;
|
||||
import com.github.prominence.openweathermap.api.model.*;
|
||||
import com.github.prominence.openweathermap.api.model.forecast.climatic.AtmosphericPressure;
|
||||
import com.github.prominence.openweathermap.api.model.forecast.climatic.Temperature;
|
||||
import com.github.prominence.openweathermap.api.model.forecast.climatic.*;
|
||||
import com.github.prominence.openweathermap.api.utils.TestMappingUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class ClimaticForecastResponseMapperTest {
|
||||
|
||||
@Test
|
||||
public void mapToForecast() {
|
||||
final String jsonResponse = """
|
||||
{
|
||||
"cod": "200",
|
||||
"city": {
|
||||
"id": 2643743,
|
||||
"name": "London",
|
||||
"coord": {
|
||||
"lon": -0.1277,
|
||||
"lat": 51.5073
|
||||
},
|
||||
"country": "GB"
|
||||
},
|
||||
"message": 0.353472054,
|
||||
"list": [
|
||||
{
|
||||
"dt": 1594382400,
|
||||
"sunrise": 1594353335,
|
||||
"sunset": 1594412149,
|
||||
"temp": {
|
||||
"day": 286.98,
|
||||
"min": 285.22,
|
||||
"max": 287.97,
|
||||
"night": 285.22,
|
||||
"eve": 287.97,
|
||||
"morn": 287.29
|
||||
},
|
||||
"feels_like": {
|
||||
"day": 282.61,
|
||||
"night": 283.19,
|
||||
"eve": 284.98,
|
||||
"morn": 282.68
|
||||
},
|
||||
"pressure": 1016,
|
||||
"humidity": 84,
|
||||
"weather": [
|
||||
{
|
||||
"id": 500,
|
||||
"main": "Rain",
|
||||
"description": "light rain",
|
||||
"icon": "10d"
|
||||
}
|
||||
],
|
||||
"speed": 6.78,
|
||||
"deg": 320,
|
||||
"clouds": 81,
|
||||
"rain": 1.96,
|
||||
"snow": 2.21
|
||||
}
|
||||
]
|
||||
}
|
||||
""";
|
||||
|
||||
final Forecast forecast = new ClimaticForecastResponseMapper(UnitSystem.METRIC).mapToForecast(jsonResponse);
|
||||
assertNotNull(forecast);
|
||||
|
||||
final Location location = forecast.getLocation();
|
||||
assertNotNull(location);
|
||||
assertEquals(Coordinates.of(51.5073, -0.1277), location.getCoordinate());
|
||||
assertEquals(2643743, location.getId());
|
||||
assertEquals("London", location.getName());
|
||||
assertEquals("GB", location.getCountryCode());
|
||||
assertNull(location.getPopulation());
|
||||
assertNull(location.getZoneOffset());
|
||||
|
||||
assertEquals(1, forecast.getWeatherForecasts().size());
|
||||
final WeatherForecast weatherForecast = forecast.getWeatherForecasts().get(0);
|
||||
assertEquals(TestMappingUtils.parseDateTime(1594382400), weatherForecast.getForecastTime());
|
||||
assertEquals(TestMappingUtils.parseDateTime(1594353335), weatherForecast.getSunriseTime());
|
||||
assertEquals(TestMappingUtils.parseDateTime(1594412149), weatherForecast.getSunsetTime());
|
||||
|
||||
final Temperature temperature = weatherForecast.getTemperature();
|
||||
assertEquals(286.98, temperature.getDay());
|
||||
assertEquals(285.22, temperature.getMin());
|
||||
assertEquals(287.97, temperature.getMax());
|
||||
assertEquals(285.22, temperature.getNight());
|
||||
assertEquals(287.97, temperature.getEve());
|
||||
assertEquals(287.29, temperature.getMorning());
|
||||
assertEquals(282.61, temperature.getDayFeelsLike());
|
||||
assertEquals(283.19, temperature.getNightFeelsLike());
|
||||
assertEquals(284.98, temperature.getEveFeelsLike());
|
||||
assertEquals(282.68, temperature.getMorningFeelsLike());
|
||||
|
||||
final AtmosphericPressure pressure = weatherForecast.getAtmosphericPressure();
|
||||
assertEquals(1016, pressure.getSeaLevelValue());
|
||||
|
||||
final Humidity humidity = weatherForecast.getHumidity();
|
||||
assertEquals(84, humidity.getValue());
|
||||
|
||||
final Wind wind = weatherForecast.getWind();
|
||||
assertEquals(6.78, wind.getSpeed());
|
||||
assertEquals(320, wind.getDegrees());
|
||||
|
||||
final Clouds clouds = weatherForecast.getClouds();
|
||||
assertEquals(81, clouds.getValue());
|
||||
|
||||
assertEquals(1, weatherForecast.getWeatherStates().size());
|
||||
final WeatherState weatherState = weatherForecast.getWeatherStates().get(0);
|
||||
assertEquals(500, weatherState.getId());
|
||||
assertEquals("Rain", weatherState.getName());
|
||||
assertEquals("light rain", weatherState.getDescription());
|
||||
assertEquals("10d", weatherState.getIconId());
|
||||
|
||||
final Rain rain = weatherForecast.getRain();
|
||||
assertEquals(1.96, rain.getLevel());
|
||||
|
||||
final Snow snow = weatherForecast.getSnow();
|
||||
assertEquals(2.21, snow.getLevel());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,137 @@
|
||||
package com.github.prominence.openweathermap.api.mapper;
|
||||
|
||||
import com.github.prominence.openweathermap.api.enums.UnitSystem;
|
||||
import com.github.prominence.openweathermap.api.model.*;
|
||||
import com.github.prominence.openweathermap.api.model.forecast.daily.AtmosphericPressure;
|
||||
import com.github.prominence.openweathermap.api.model.forecast.daily.Temperature;
|
||||
import com.github.prominence.openweathermap.api.model.forecast.daily.*;
|
||||
import com.github.prominence.openweathermap.api.utils.TestMappingUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.ZoneOffset;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
class DailyForecastResponseMapperTest {
|
||||
|
||||
@Test
|
||||
public void mapToForecast() {
|
||||
final String jsonResponse = """
|
||||
{
|
||||
"city": {
|
||||
"id": 2643743,
|
||||
"name": "London",
|
||||
"coord": {
|
||||
"lon": -0.1258,
|
||||
"lat": 51.5085
|
||||
},
|
||||
"country": "GB",
|
||||
"population": 0,
|
||||
"timezone": 3600
|
||||
},
|
||||
"cod": "200",
|
||||
"message": 0.7809187,
|
||||
"cnt": 1,
|
||||
"list": [
|
||||
{
|
||||
"dt": 1568977200,
|
||||
"sunrise": 1568958164,
|
||||
"sunset": 1569002733,
|
||||
"temp": {
|
||||
"day": 293.79,
|
||||
"min": 288.85,
|
||||
"max": 294.47,
|
||||
"night": 288.85,
|
||||
"eve": 290.44,
|
||||
"morn": 293.79
|
||||
},
|
||||
"feels_like": {
|
||||
"day": 278.87,
|
||||
"night": 282.73,
|
||||
"eve": 281.92,
|
||||
"morn": 278.87
|
||||
},
|
||||
"pressure": 1025.04,
|
||||
"humidity": 42,
|
||||
"weather": [
|
||||
{
|
||||
"id": 800,
|
||||
"main": "Clear",
|
||||
"description": "sky is clear",
|
||||
"icon": "01d"
|
||||
}
|
||||
],
|
||||
"speed": 4.66,
|
||||
"deg": 102,
|
||||
"gust": 5.3,
|
||||
"clouds": 0,
|
||||
"pop": 0.24,
|
||||
"rain": 22.2,
|
||||
"snow": 24.2
|
||||
}
|
||||
]
|
||||
}
|
||||
""";
|
||||
|
||||
final Forecast forecast = new DailyForecastResponseMapper(UnitSystem.METRIC).mapToForecast(jsonResponse);
|
||||
assertNotNull(forecast);
|
||||
|
||||
final Location location = forecast.getLocation();
|
||||
assertNotNull(location);
|
||||
assertEquals(Coordinates.of(51.5085, -0.1258), location.getCoordinate());
|
||||
assertEquals(2643743, location.getId());
|
||||
assertEquals("London", location.getName());
|
||||
assertEquals("GB", location.getCountryCode());
|
||||
assertEquals(0, location.getPopulation());
|
||||
assertEquals(ZoneOffset.ofTotalSeconds(3600), location.getZoneOffset());
|
||||
|
||||
assertEquals(1, forecast.getWeatherForecasts().size());
|
||||
final WeatherForecast weatherForecast = forecast.getWeatherForecasts().get(0);
|
||||
assertEquals(TestMappingUtils.parseDateTime(1568977200), weatherForecast.getForecastTime());
|
||||
// TODO: Does the API provide the sunrise and sunset info??? It is not officially described in the API but present in the example.
|
||||
assertEquals(TestMappingUtils.parseDateTime(1568958164), weatherForecast.getSunriseTime());
|
||||
assertEquals(TestMappingUtils.parseDateTime(1569002733), weatherForecast.getSunsetTime());
|
||||
|
||||
final Temperature temperature = weatherForecast.getTemperature();
|
||||
assertEquals(293.79, temperature.getDay());
|
||||
assertEquals(288.85, temperature.getMin());
|
||||
assertEquals(294.47, temperature.getMax());
|
||||
assertEquals(288.85, temperature.getNight());
|
||||
assertEquals(290.44, temperature.getEve());
|
||||
assertEquals(293.79, temperature.getMorning());
|
||||
assertEquals(278.87, temperature.getDayFeelsLike());
|
||||
assertEquals(282.73, temperature.getNightFeelsLike());
|
||||
assertEquals(281.92, temperature.getEveFeelsLike());
|
||||
assertEquals(278.87, temperature.getMorningFeelsLike());
|
||||
|
||||
final AtmosphericPressure pressure = weatherForecast.getAtmosphericPressure();
|
||||
assertEquals(1025.04, pressure.getSeaLevelValue());
|
||||
|
||||
final Humidity humidity = weatherForecast.getHumidity();
|
||||
assertEquals(42, humidity.getValue());
|
||||
|
||||
final Wind wind = weatherForecast.getWind();
|
||||
assertEquals(4.66, wind.getSpeed());
|
||||
assertEquals(102, wind.getDegrees());
|
||||
assertEquals(5.3, wind.getGust());
|
||||
|
||||
final Clouds clouds = weatherForecast.getClouds();
|
||||
assertEquals(0, clouds.getValue());
|
||||
|
||||
assertEquals(1, weatherForecast.getWeatherStates().size());
|
||||
final WeatherState weatherState = weatherForecast.getWeatherStates().get(0);
|
||||
assertEquals(800, weatherState.getId());
|
||||
assertEquals("Clear", weatherState.getName());
|
||||
assertEquals("sky is clear", weatherState.getDescription());
|
||||
assertEquals("01d", weatherState.getIconId());
|
||||
|
||||
final Rain rain = weatherForecast.getRain();
|
||||
assertEquals(22.2, rain.getLevel());
|
||||
|
||||
final Snow snow = weatherForecast.getSnow();
|
||||
assertEquals(24.2, snow.getLevel());
|
||||
|
||||
assertEquals(0.24, weatherForecast.getProbabilityOfPrecipitation());
|
||||
}
|
||||
}
|
||||
@ -29,7 +29,8 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
class GeocodingResponseMapperTest {
|
||||
|
||||
|
||||
@ -32,7 +32,8 @@ import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
class HourlyForecastResponseMapperTest {
|
||||
|
||||
|
||||
@ -30,7 +30,8 @@ import org.junit.jupiter.api.Test;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
|
||||
public class AirPollutionDetailsUnitTest {
|
||||
@Test
|
||||
|
||||
@ -22,8 +22,8 @@
|
||||
|
||||
package com.github.prominence.openweathermap.api.model.onecall;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import com.github.prominence.openweathermap.api.model.Wind;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
|
||||
@ -24,7 +24,8 @@ package com.github.prominence.openweathermap.api.model.onecall.current;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
|
||||
public class DailyTemperatureUnitTest {
|
||||
|
||||
|
||||
@ -25,8 +25,8 @@ package com.github.prominence.openweathermap.api.model.onecall.current;
|
||||
import com.github.prominence.openweathermap.api.model.Clouds;
|
||||
import com.github.prominence.openweathermap.api.model.Humidity;
|
||||
import com.github.prominence.openweathermap.api.model.WeatherState;
|
||||
import com.github.prominence.openweathermap.api.model.onecall.AtmosphericPressure;
|
||||
import com.github.prominence.openweathermap.api.model.Wind;
|
||||
import com.github.prominence.openweathermap.api.model.onecall.AtmosphericPressure;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@ -26,7 +26,10 @@ import com.github.prominence.openweathermap.api.model.Clouds;
|
||||
import com.github.prominence.openweathermap.api.model.Humidity;
|
||||
import com.github.prominence.openweathermap.api.model.WeatherState;
|
||||
import com.github.prominence.openweathermap.api.model.Wind;
|
||||
import com.github.prominence.openweathermap.api.model.onecall.*;
|
||||
import com.github.prominence.openweathermap.api.model.onecall.AtmosphericPressure;
|
||||
import com.github.prominence.openweathermap.api.model.onecall.Rain;
|
||||
import com.github.prominence.openweathermap.api.model.onecall.Snow;
|
||||
import com.github.prominence.openweathermap.api.model.onecall.Temperature;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@ -26,7 +26,10 @@ import com.github.prominence.openweathermap.api.model.Clouds;
|
||||
import com.github.prominence.openweathermap.api.model.Humidity;
|
||||
import com.github.prominence.openweathermap.api.model.WeatherState;
|
||||
import com.github.prominence.openweathermap.api.model.Wind;
|
||||
import com.github.prominence.openweathermap.api.model.onecall.*;
|
||||
import com.github.prominence.openweathermap.api.model.onecall.AtmosphericPressure;
|
||||
import com.github.prominence.openweathermap.api.model.onecall.Rain;
|
||||
import com.github.prominence.openweathermap.api.model.onecall.Snow;
|
||||
import com.github.prominence.openweathermap.api.model.onecall.Temperature;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@ -26,7 +26,10 @@ import com.github.prominence.openweathermap.api.model.Clouds;
|
||||
import com.github.prominence.openweathermap.api.model.Humidity;
|
||||
import com.github.prominence.openweathermap.api.model.WeatherState;
|
||||
import com.github.prominence.openweathermap.api.model.Wind;
|
||||
import com.github.prominence.openweathermap.api.model.onecall.*;
|
||||
import com.github.prominence.openweathermap.api.model.onecall.AtmosphericPressure;
|
||||
import com.github.prominence.openweathermap.api.model.onecall.Rain;
|
||||
import com.github.prominence.openweathermap.api.model.onecall.Snow;
|
||||
import com.github.prominence.openweathermap.api.model.onecall.Temperature;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@ -27,7 +27,6 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
package com.github.prominence.openweathermap.api.utils;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public class TestMappingUtils {
|
||||
|
||||
public static LocalDateTime parseDateTime(int seconds) {
|
||||
return LocalDateTime.ofInstant(Instant.ofEpochSecond(seconds), TimeZone.getDefault().toZoneId());
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user