diff --git a/vol3/pom.xml b/vol3/pom.xml
index 219f333..67aa0d3 100644
--- a/vol3/pom.xml
+++ b/vol3/pom.xml
@@ -12,4 +12,17 @@
vol3
Модуль №3
+
+
+ com.squareup.okhttp3
+ okhttp
+ 4.12.0
+
+
+ com.google.code.gson
+ gson
+ 2.11.0
+
+
+
diff --git a/vol3/src/main/java/ru/mifi/practice/val3/cont/Deserializer.java b/vol3/src/main/java/ru/mifi/practice/val3/cont/Deserializer.java
new file mode 100644
index 0000000..aaadc82
--- /dev/null
+++ b/vol3/src/main/java/ru/mifi/practice/val3/cont/Deserializer.java
@@ -0,0 +1,15 @@
+package ru.mifi.practice.val3.cont;
+
+import com.google.gson.Gson;
+
+public interface Deserializer {
+ T deserialize(String text, Class clazz);
+
+ final class GsonDeserializer implements Deserializer {
+ private final Gson gson = new Gson();
+
+ public T deserialize(String text, Class clazz) {
+ return gson.fromJson(text, clazz);
+ }
+ }
+}
diff --git a/vol3/src/main/java/ru/mifi/practice/val3/cont/Http.java b/vol3/src/main/java/ru/mifi/practice/val3/cont/Http.java
new file mode 100644
index 0000000..14b20c0
--- /dev/null
+++ b/vol3/src/main/java/ru/mifi/practice/val3/cont/Http.java
@@ -0,0 +1,50 @@
+package ru.mifi.practice.val3.cont;
+
+import okhttp3.HttpUrl;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+import okhttp3.ResponseBody;
+
+import java.io.IOException;
+import java.util.Objects;
+import java.util.Optional;
+
+public interface Http {
+ Optional get(String url, Class clazz);
+
+ String urlencode(String url);
+
+ final class Ok implements Http {
+ private final OkHttpClient client = new OkHttpClient.Builder().build();
+ private final Deserializer deserializer;
+
+ public Ok(Deserializer deserializer) {
+ this.deserializer = deserializer;
+ }
+
+ @Override
+ public Optional get(String url, Class clazz) {
+ Request request = new Request.Builder().url(url).get().build();
+ try (Response response = client.newCall(request).execute()) {
+ ResponseBody responseBody = response.body();
+ if (response.isSuccessful() && responseBody != null) {
+ try (ResponseBody body = responseBody) {
+ String content = body.string();
+ return Optional.of(deserializer.deserialize(content, clazz));
+ }
+ } else {
+ System.err.println(response);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return Optional.empty();
+ }
+
+ @Override
+ public String urlencode(String url) {
+ return Objects.requireNonNull(HttpUrl.parse(url)).toString();
+ }
+ }
+}
diff --git a/vol3/src/main/java/ru/mifi/practice/val3/cont/Location.java b/vol3/src/main/java/ru/mifi/practice/val3/cont/Location.java
new file mode 100644
index 0000000..99631a5
--- /dev/null
+++ b/vol3/src/main/java/ru/mifi/practice/val3/cont/Location.java
@@ -0,0 +1,23 @@
+package ru.mifi.practice.val3.cont;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.util.Optional;
+
+@FunctionalInterface
+public interface Location {
+
+ static Location fixed(Place place) {
+ return () -> Optional.of(place);
+ }
+
+ static Location fixed(float latitude, float longitude) {
+ return fixed(new Place(latitude, longitude));
+ }
+
+ Optional get();
+
+ record Place(@SerializedName("latitude") float latitude,
+ @SerializedName("longitude") float longitude) {
+ }
+}
diff --git a/vol3/src/main/java/ru/mifi/practice/val3/cont/Main.java b/vol3/src/main/java/ru/mifi/practice/val3/cont/Main.java
new file mode 100644
index 0000000..3cb4260
--- /dev/null
+++ b/vol3/src/main/java/ru/mifi/practice/val3/cont/Main.java
@@ -0,0 +1,14 @@
+package ru.mifi.practice.val3.cont;
+
+import ru.mifi.practice.val3.cont.sevices.OpenMeteo;
+import ru.mifi.practice.val3.cont.sevices.WhoIs;
+
+public abstract class Main {
+ public static void main(String[] args) {
+ Http http = new Http.Ok(new Deserializer.GsonDeserializer());
+ Location location = new WhoIs(http);
+ Weather weather = new OpenMeteo(http);
+ location.get().flatMap(place -> weather.get(place.latitude(), place.longitude()))
+ .ifPresent(System.out::println);
+ }
+}
diff --git a/vol3/src/main/java/ru/mifi/practice/val3/cont/Weather.java b/vol3/src/main/java/ru/mifi/practice/val3/cont/Weather.java
new file mode 100644
index 0000000..61a7bba
--- /dev/null
+++ b/vol3/src/main/java/ru/mifi/practice/val3/cont/Weather.java
@@ -0,0 +1,13 @@
+package ru.mifi.practice.val3.cont;
+
+import java.util.Optional;
+
+@FunctionalInterface
+public interface Weather {
+
+ Optional get(float latitude, float longitude);
+
+ record Details(float temperature, float wind) {
+
+ }
+}
diff --git a/vol3/src/main/java/ru/mifi/practice/val3/cont/sevices/OpenMeteo.java b/vol3/src/main/java/ru/mifi/practice/val3/cont/sevices/OpenMeteo.java
new file mode 100644
index 0000000..f081373
--- /dev/null
+++ b/vol3/src/main/java/ru/mifi/practice/val3/cont/sevices/OpenMeteo.java
@@ -0,0 +1,41 @@
+package ru.mifi.practice.val3.cont.sevices;
+
+import com.google.gson.annotations.SerializedName;
+import okhttp3.HttpUrl;
+import ru.mifi.practice.val3.cont.Http;
+import ru.mifi.practice.val3.cont.Weather;
+
+import java.util.Objects;
+import java.util.Optional;
+
+public final class OpenMeteo implements Weather {
+ private static final String URL = "https://api.open-meteo.com/v1/forecast";
+ private final Http http;
+
+ public OpenMeteo(Http http) {
+ this.http = http;
+ }
+
+ @Override
+ public Optional get(float latitude, float longitude) {
+ HttpUrl url = Objects.requireNonNull(HttpUrl.parse(URL))
+ .newBuilder()
+ .addQueryParameter("latitude", String.valueOf(latitude))
+ .addQueryParameter("longitude", String.valueOf(longitude))
+ .addQueryParameter("current", "temperature_2m,wind_speed_10m")
+ .build();
+ return http.get(url.toString(), Result.class).map(result -> new Details(
+ Float.parseFloat(result.current.temperature),
+ Float.parseFloat(result.current.windSpeed)
+ ));
+ }
+
+ private record Result(@SerializedName("current") Current current) {
+
+ }
+
+ private record Current(@SerializedName("temperature_2m") String temperature,
+ @SerializedName("wind_speed_10m") String windSpeed) {
+
+ }
+}
diff --git a/vol3/src/main/java/ru/mifi/practice/val3/cont/sevices/WhoIs.java b/vol3/src/main/java/ru/mifi/practice/val3/cont/sevices/WhoIs.java
new file mode 100644
index 0000000..1cdabae
--- /dev/null
+++ b/vol3/src/main/java/ru/mifi/practice/val3/cont/sevices/WhoIs.java
@@ -0,0 +1,20 @@
+package ru.mifi.practice.val3.cont.sevices;
+
+import ru.mifi.practice.val3.cont.Http;
+import ru.mifi.practice.val3.cont.Location;
+
+import java.util.Optional;
+
+public final class WhoIs implements Location {
+ private static final String URL = "http://ipwho.is";
+ private final Http http;
+
+ public WhoIs(Http http) {
+ this.http = http;
+ }
+
+ @Override
+ public Optional get() {
+ return http.get(URL, Place.class);
+ }
+}