diff --git a/README.md b/README.md
index 0f3e268..af20955 100644
--- a/README.md
+++ b/README.md
@@ -30,6 +30,31 @@ Works on Java 8 (and higher)
## Examples
+### Agriculture
+```java
+import io.openepi.common.ApiException;
+import io.openepi.agriculture.api.Agriculture;
+import io.openepi.agriculture.model.ModelsSummmary;
+
+import java.math.BigDecimal;
+
+
+public class Main {
+ public static void main(String[] args) {
+ Agriculture api = new AgricultureApi();
+ try {
+ BigDecimal lon = new BigDecimal("30.06");
+ BigDecimal lat = BigDecimal.valueOf(-1.94);
+ ModelsSummary response = api.getSummary(lon, lat);
+ System.out.println(response);
+ } catch (ApiException e) {
+ System.err.println("Exception when calling AgricultureApi#getSummary");
+ e.printStackTrace();
+ }
+ }
+}
+```
+
### Crop Health
```java
import io.openepi.client.CropHealthApi;
@@ -188,11 +213,12 @@ The generator generates a lot of the same code for each API. This library theref
Generation should be done in a separate folder, and files that are relevant should be copied into this project:
```bash
-openapi-generator generate -i https://api.openepi.io/crop-health/openapi.json -g java -o ./crop-health
-openapi-generator generate -i https://api.openepi.io/deforestation/openapi.json -g java -o ./deforestation
-openapi-generator generate -i https://api.openepi.io/flood/openapi.json -g java -o ./flood
-openapi-generator generate -i https://api.openepi.io/soil/openapi.json -g java -o ./soil
-openapi-generator generate -i https://api.openepi.io/weather/openapi.json -g java -o ./weather
+openapi-generator generate -i https://api-test.openepi.io/agriculture/openapi.json -g java -o ./agriculture
+openapi-generator generate -i https://api-test.openepi.io/crop-health/openapi.json -g java -o ./crop-health
+openapi-generator generate -i https://api-test.openepi.io/deforestation/openapi.json -g java -o ./deforestation
+openapi-generator generate -i https://api-test.openepi.io/flood/openapi.json -g java -o ./flood
+openapi-generator generate -i https://api-test.openepi.io/soil/openapi.json -g java -o ./soil
+openapi-generator generate -i https://api-test.openepi.io/weather/openapi.json -g java -o ./weather
```
There is a special case for the geocoding api. When the api generates its openapi spec, it generates with `anyOf` and
diff --git a/src/main/java/io/openepi/agriculture/ApiClient.java b/src/main/java/io/openepi/agriculture/ApiClient.java
new file mode 100644
index 0000000..9e85318
--- /dev/null
+++ b/src/main/java/io/openepi/agriculture/ApiClient.java
@@ -0,0 +1,1584 @@
+/*
+ * Agriculture API
+ * This API is used to get aggregated data from Deforestation, Flood, Weather and Soil APIs.
+ *
+ * The version of the OpenAPI document: 1.0.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+
+package io.openepi.agriculture;
+
+import io.openepi.common.*;
+import okhttp3.*;
+import okhttp3.internal.http.HttpMethod;
+import okhttp3.internal.tls.OkHostnameVerifier;
+import okhttp3.logging.HttpLoggingInterceptor;
+import okhttp3.logging.HttpLoggingInterceptor.Level;
+import okio.Buffer;
+import okio.BufferedSink;
+import okio.Okio;
+
+import javax.net.ssl.*;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Type;
+import java.net.URI;
+import java.net.URLConnection;
+import java.net.URLEncoder;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.SecureRandom;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.text.DateFormat;
+import java.time.LocalDate;
+import java.time.OffsetDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import io.openepi.common.auth.Authentication;
+import io.openepi.common.auth.HttpBasicAuth;
+import io.openepi.common.auth.ApiKeyAuth;
+
+/**
+ *
ApiClient class.
+ */
+public class ApiClient {
+
+ private String basePath = "https://api.openepi.io/agriculture";
+ protected List servers = new ArrayList(Arrays.asList(
+ new ServerConfiguration(
+ "",
+ "No description provided",
+ new HashMap()
+ )
+ ));
+ protected Integer serverIndex = 0;
+ protected Map serverVariables = null;
+ private boolean debugging = false;
+ private Map defaultHeaderMap = new HashMap();
+ private Map defaultCookieMap = new HashMap();
+ private String tempFolderPath = null;
+
+ private Map authentications;
+
+ private DateFormat dateFormat;
+ private DateFormat datetimeFormat;
+ private boolean lenientDatetimeFormat;
+ private int dateLength;
+
+ private InputStream sslCaCert;
+ private boolean verifyingSsl;
+ private KeyManager[] keyManagers;
+
+ private OkHttpClient httpClient;
+ private JSON json;
+
+ private HttpLoggingInterceptor loggingInterceptor;
+
+ /**
+ * Basic constructor for ApiClient
+ */
+ public ApiClient() {
+ init();
+ initHttpClient();
+
+ // Setup authentications (key: authentication name, value: authentication).
+ // Prevent the authentications from being modified.
+ authentications = Collections.unmodifiableMap(authentications);
+ }
+
+ /**
+ * Basic constructor with custom OkHttpClient
+ *
+ * @param client a {@link okhttp3.OkHttpClient} object
+ */
+ public ApiClient(OkHttpClient client) {
+ init();
+
+ httpClient = client;
+
+ // Setup authentications (key: authentication name, value: authentication).
+ // Prevent the authentications from being modified.
+ authentications = Collections.unmodifiableMap(authentications);
+ }
+
+ private void initHttpClient() {
+ initHttpClient(Collections.emptyList());
+ }
+
+ private void initHttpClient(List interceptors) {
+ OkHttpClient.Builder builder = new OkHttpClient.Builder();
+ builder.addNetworkInterceptor(getProgressInterceptor());
+ for (Interceptor interceptor: interceptors) {
+ builder.addInterceptor(interceptor);
+ }
+
+ httpClient = builder.build();
+ }
+
+ private void init() {
+ verifyingSsl = true;
+
+ json = new JSON();
+
+ // Set default User-Agent.
+ setUserAgent("OpenAPI-Generator/1.0.0/java");
+
+ authentications = new HashMap();
+ }
+
+ /**
+ * Get base path
+ *
+ * @return Base path
+ */
+ public String getBasePath() {
+ return basePath;
+ }
+
+ /**
+ * Set base path
+ *
+ * @param basePath Base path of the URL (e.g http://localhost
+ * @return An instance of OkHttpClient
+ */
+ public ApiClient setBasePath(String basePath) {
+ this.basePath = basePath;
+ this.serverIndex = null;
+ return this;
+ }
+
+ public List getServers() {
+ return servers;
+ }
+
+ public ApiClient setServers(List servers) {
+ this.servers = servers;
+ return this;
+ }
+
+ public Integer getServerIndex() {
+ return serverIndex;
+ }
+
+ public ApiClient setServerIndex(Integer serverIndex) {
+ this.serverIndex = serverIndex;
+ return this;
+ }
+
+ public Map getServerVariables() {
+ return serverVariables;
+ }
+
+ public ApiClient setServerVariables(Map serverVariables) {
+ this.serverVariables = serverVariables;
+ return this;
+ }
+
+ /**
+ * Get HTTP client
+ *
+ * @return An instance of OkHttpClient
+ */
+ public OkHttpClient getHttpClient() {
+ return httpClient;
+ }
+
+ /**
+ * Set HTTP client, which must never be null.
+ *
+ * @param newHttpClient An instance of OkHttpClient
+ * @return Api Client
+ * @throws java.lang.NullPointerException when newHttpClient is null
+ */
+ public ApiClient setHttpClient(OkHttpClient newHttpClient) {
+ this.httpClient = Objects.requireNonNull(newHttpClient, "HttpClient must not be null!");
+ return this;
+ }
+
+ /**
+ * Get JSON
+ *
+ * @return JSON object
+ */
+ public JSON getJSON() {
+ return json;
+ }
+
+ /**
+ * Set JSON
+ *
+ * @param json JSON object
+ * @return Api client
+ */
+ public ApiClient setJSON(JSON json) {
+ this.json = json;
+ return this;
+ }
+
+ /**
+ * True if isVerifyingSsl flag is on
+ *
+ * @return True if isVerifySsl flag is on
+ */
+ public boolean isVerifyingSsl() {
+ return verifyingSsl;
+ }
+
+ /**
+ * Configure whether to verify certificate and hostname when making https requests.
+ * Default to true.
+ * NOTE: Do NOT set to false in production code, otherwise you would face multiple types of cryptographic attacks.
+ *
+ * @param verifyingSsl True to verify TLS/SSL connection
+ * @return ApiClient
+ */
+ public ApiClient setVerifyingSsl(boolean verifyingSsl) {
+ this.verifyingSsl = verifyingSsl;
+ applySslSettings();
+ return this;
+ }
+
+ /**
+ * Get SSL CA cert.
+ *
+ * @return Input stream to the SSL CA cert
+ */
+ public InputStream getSslCaCert() {
+ return sslCaCert;
+ }
+
+ /**
+ * Configure the CA certificate to be trusted when making https requests.
+ * Use null to reset to default.
+ *
+ * @param sslCaCert input stream for SSL CA cert
+ * @return ApiClient
+ */
+ public ApiClient setSslCaCert(InputStream sslCaCert) {
+ this.sslCaCert = sslCaCert;
+ applySslSettings();
+ return this;
+ }
+
+ /**
+ * Getter for the field keyManagers.
+ *
+ * @return an array of {@link javax.net.ssl.KeyManager} objects
+ */
+ public KeyManager[] getKeyManagers() {
+ return keyManagers;
+ }
+
+ /**
+ * Configure client keys to use for authorization in an SSL session.
+ * Use null to reset to default.
+ *
+ * @param managers The KeyManagers to use
+ * @return ApiClient
+ */
+ public ApiClient setKeyManagers(KeyManager[] managers) {
+ this.keyManagers = managers;
+ applySslSettings();
+ return this;
+ }
+
+ /**
+ * Getter for the field dateFormat.
+ *
+ * @return a {@link java.text.DateFormat} object
+ */
+ public DateFormat getDateFormat() {
+ return dateFormat;
+ }
+
+ /**
+ * Setter for the field dateFormat.
+ *
+ * @param dateFormat a {@link java.text.DateFormat} object
+ * @return a {@link io.openepi.agriculture.ApiClient} object
+ */
+ public ApiClient setDateFormat(DateFormat dateFormat) {
+ JSON.setDateFormat(dateFormat);
+ return this;
+ }
+
+ /**
+ * Set SqlDateFormat.
+ *
+ * @param dateFormat a {@link java.text.DateFormat} object
+ * @return a {@link io.openepi.agriculture.ApiClient} object
+ */
+ public ApiClient setSqlDateFormat(DateFormat dateFormat) {
+ JSON.setSqlDateFormat(dateFormat);
+ return this;
+ }
+
+ /**
+ * Set OffsetDateTimeFormat.
+ *
+ * @param dateFormat a {@link java.time.format.DateTimeFormatter} object
+ * @return a {@link io.openepi.agriculture.ApiClient} object
+ */
+ public ApiClient setOffsetDateTimeFormat(DateTimeFormatter dateFormat) {
+ JSON.setOffsetDateTimeFormat(dateFormat);
+ return this;
+ }
+
+ /**
+ * Set LocalDateFormat.
+ *
+ * @param dateFormat a {@link java.time.format.DateTimeFormatter} object
+ * @return a {@link io.openepi.agriculture.ApiClient} object
+ */
+ public ApiClient setLocalDateFormat(DateTimeFormatter dateFormat) {
+ JSON.setLocalDateFormat(dateFormat);
+ return this;
+ }
+
+ /**
+ * Set LenientOnJson.
+ *
+ * @param lenientOnJson a boolean
+ * @return a {@link io.openepi.agriculture.ApiClient} object
+ */
+ public ApiClient setLenientOnJson(boolean lenientOnJson) {
+ JSON.setLenientOnJson(lenientOnJson);
+ return this;
+ }
+
+ /**
+ * Get authentications (key: authentication name, value: authentication).
+ *
+ * @return Map of authentication objects
+ */
+ public Map getAuthentications() {
+ return authentications;
+ }
+
+ /**
+ * Get authentication for the given name.
+ *
+ * @param authName The authentication name
+ * @return The authentication, null if not found
+ */
+ public Authentication getAuthentication(String authName) {
+ return authentications.get(authName);
+ }
+
+
+ /**
+ * Helper method to set username for the first HTTP basic authentication.
+ *
+ * @param username Username
+ */
+ public void setUsername(String username) {
+ for (Authentication auth : authentications.values()) {
+ if (auth instanceof HttpBasicAuth) {
+ ((HttpBasicAuth) auth).setUsername(username);
+ return;
+ }
+ }
+ throw new RuntimeException("No HTTP basic authentication configured!");
+ }
+
+ /**
+ * Helper method to set password for the first HTTP basic authentication.
+ *
+ * @param password Password
+ */
+ public void setPassword(String password) {
+ for (Authentication auth : authentications.values()) {
+ if (auth instanceof HttpBasicAuth) {
+ ((HttpBasicAuth) auth).setPassword(password);
+ return;
+ }
+ }
+ throw new RuntimeException("No HTTP basic authentication configured!");
+ }
+
+ /**
+ * Helper method to set API key value for the first API key authentication.
+ *
+ * @param apiKey API key
+ */
+ public void setApiKey(String apiKey) {
+ for (Authentication auth : authentications.values()) {
+ if (auth instanceof ApiKeyAuth) {
+ ((ApiKeyAuth) auth).setApiKey(apiKey);
+ return;
+ }
+ }
+ throw new RuntimeException("No API key authentication configured!");
+ }
+
+ /**
+ * Helper method to set API key prefix for the first API key authentication.
+ *
+ * @param apiKeyPrefix API key prefix
+ */
+ public void setApiKeyPrefix(String apiKeyPrefix) {
+ for (Authentication auth : authentications.values()) {
+ if (auth instanceof ApiKeyAuth) {
+ ((ApiKeyAuth) auth).setApiKeyPrefix(apiKeyPrefix);
+ return;
+ }
+ }
+ throw new RuntimeException("No API key authentication configured!");
+ }
+
+ /**
+ * Helper method to set access token for the first OAuth2 authentication.
+ *
+ * @param accessToken Access token
+ */
+ public void setAccessToken(String accessToken) {
+ throw new RuntimeException("No OAuth2 authentication configured!");
+ }
+
+ /**
+ * Helper method to set credentials for AWSV4 Signature
+ *
+ * @param accessKey Access Key
+ * @param secretKey Secret Key
+ * @param region Region
+ * @param service Service to access to
+ */
+ public void setAWS4Configuration(String accessKey, String secretKey, String region, String service) {
+ throw new RuntimeException("No AWS4 authentication configured!");
+ }
+
+ /**
+ * Helper method to set credentials for AWSV4 Signature
+ *
+ * @param accessKey Access Key
+ * @param secretKey Secret Key
+ * @param sessionToken Session Token
+ * @param region Region
+ * @param service Service to access to
+ */
+ public void setAWS4Configuration(String accessKey, String secretKey, String sessionToken, String region, String service) {
+ throw new RuntimeException("No AWS4 authentication configured!");
+ }
+
+ /**
+ * Set the User-Agent header's value (by adding to the default header map).
+ *
+ * @param userAgent HTTP request's user agent
+ * @return ApiClient
+ */
+ public ApiClient setUserAgent(String userAgent) {
+ addDefaultHeader("User-Agent", userAgent);
+ return this;
+ }
+
+ /**
+ * Add a default header.
+ *
+ * @param key The header's key
+ * @param value The header's value
+ * @return ApiClient
+ */
+ public ApiClient addDefaultHeader(String key, String value) {
+ defaultHeaderMap.put(key, value);
+ return this;
+ }
+
+ /**
+ * Add a default cookie.
+ *
+ * @param key The cookie's key
+ * @param value The cookie's value
+ * @return ApiClient
+ */
+ public ApiClient addDefaultCookie(String key, String value) {
+ defaultCookieMap.put(key, value);
+ return this;
+ }
+
+ /**
+ * Check that whether debugging is enabled for this API client.
+ *
+ * @return True if debugging is enabled, false otherwise.
+ */
+ public boolean isDebugging() {
+ return debugging;
+ }
+
+ /**
+ * Enable/disable debugging for this API client.
+ *
+ * @param debugging To enable (true) or disable (false) debugging
+ * @return ApiClient
+ */
+ public ApiClient setDebugging(boolean debugging) {
+ if (debugging != this.debugging) {
+ if (debugging) {
+ loggingInterceptor = new HttpLoggingInterceptor();
+ loggingInterceptor.setLevel(Level.BODY);
+ httpClient = httpClient.newBuilder().addInterceptor(loggingInterceptor).build();
+ } else {
+ final OkHttpClient.Builder builder = httpClient.newBuilder();
+ builder.interceptors().remove(loggingInterceptor);
+ httpClient = builder.build();
+ loggingInterceptor = null;
+ }
+ }
+ this.debugging = debugging;
+ return this;
+ }
+
+ /**
+ * The path of temporary folder used to store downloaded files from endpoints
+ * with file response. The default value is null, i.e. using
+ * the system's default temporary folder.
+ *
+ * @see createTempFile
+ * @return Temporary folder path
+ */
+ public String getTempFolderPath() {
+ return tempFolderPath;
+ }
+
+ /**
+ * Set the temporary folder path (for downloading files)
+ *
+ * @param tempFolderPath Temporary folder path
+ * @return ApiClient
+ */
+ public ApiClient setTempFolderPath(String tempFolderPath) {
+ this.tempFolderPath = tempFolderPath;
+ return this;
+ }
+
+ /**
+ * Get connection timeout (in milliseconds).
+ *
+ * @return Timeout in milliseconds
+ */
+ public int getConnectTimeout() {
+ return httpClient.connectTimeoutMillis();
+ }
+
+ /**
+ * Sets the connect timeout (in milliseconds).
+ * A value of 0 means no timeout, otherwise values must be between 1 and
+ * {@link java.lang.Integer#MAX_VALUE}.
+ *
+ * @param connectionTimeout connection timeout in milliseconds
+ * @return Api client
+ */
+ public ApiClient setConnectTimeout(int connectionTimeout) {
+ httpClient = httpClient.newBuilder().connectTimeout(connectionTimeout, TimeUnit.MILLISECONDS).build();
+ return this;
+ }
+
+ /**
+ * Get read timeout (in milliseconds).
+ *
+ * @return Timeout in milliseconds
+ */
+ public int getReadTimeout() {
+ return httpClient.readTimeoutMillis();
+ }
+
+ /**
+ * Sets the read timeout (in milliseconds).
+ * A value of 0 means no timeout, otherwise values must be between 1 and
+ * {@link java.lang.Integer#MAX_VALUE}.
+ *
+ * @param readTimeout read timeout in milliseconds
+ * @return Api client
+ */
+ public ApiClient setReadTimeout(int readTimeout) {
+ httpClient = httpClient.newBuilder().readTimeout(readTimeout, TimeUnit.MILLISECONDS).build();
+ return this;
+ }
+
+ /**
+ * Get write timeout (in milliseconds).
+ *
+ * @return Timeout in milliseconds
+ */
+ public int getWriteTimeout() {
+ return httpClient.writeTimeoutMillis();
+ }
+
+ /**
+ * Sets the write timeout (in milliseconds).
+ * A value of 0 means no timeout, otherwise values must be between 1 and
+ * {@link java.lang.Integer#MAX_VALUE}.
+ *
+ * @param writeTimeout connection timeout in milliseconds
+ * @return Api client
+ */
+ public ApiClient setWriteTimeout(int writeTimeout) {
+ httpClient = httpClient.newBuilder().writeTimeout(writeTimeout, TimeUnit.MILLISECONDS).build();
+ return this;
+ }
+
+
+ /**
+ * Format the given parameter object into string.
+ *
+ * @param param Parameter
+ * @return String representation of the parameter
+ */
+ public String parameterToString(Object param) {
+ if (param == null) {
+ return "";
+ } else if (param instanceof Date || param instanceof OffsetDateTime || param instanceof LocalDate) {
+ //Serialize to json string and remove the " enclosing characters
+ String jsonStr = JSON.serialize(param);
+ return jsonStr.substring(1, jsonStr.length() - 1);
+ } else if (param instanceof Collection) {
+ StringBuilder b = new StringBuilder();
+ for (Object o : (Collection) param) {
+ if (b.length() > 0) {
+ b.append(",");
+ }
+ b.append(o);
+ }
+ return b.toString();
+ } else {
+ return String.valueOf(param);
+ }
+ }
+
+ /**
+ * Formats the specified query parameter to a list containing a single {@code Pair} object.
+ *
+ * Note that {@code value} must not be a collection.
+ *
+ * @param name The name of the parameter.
+ * @param value The value of the parameter.
+ * @return A list containing a single {@code Pair} object.
+ */
+ public List parameterToPair(String name, Object value) {
+ List params = new ArrayList();
+
+ // preconditions
+ if (name == null || name.isEmpty() || value == null || value instanceof Collection) {
+ return params;
+ }
+
+ params.add(new Pair(name, parameterToString(value)));
+ return params;
+ }
+
+ /**
+ * Formats the specified collection query parameters to a list of {@code Pair} objects.
+ *
+ * Note that the values of each of the returned Pair objects are percent-encoded.
+ *
+ * @param collectionFormat The collection format of the parameter.
+ * @param name The name of the parameter.
+ * @param value The value of the parameter.
+ * @return A list of {@code Pair} objects.
+ */
+ public List parameterToPairs(String collectionFormat, String name, Collection value) {
+ List params = new ArrayList();
+
+ // preconditions
+ if (name == null || name.isEmpty() || value == null || value.isEmpty()) {
+ return params;
+ }
+
+ // create the params based on the collection format
+ if ("multi".equals(collectionFormat)) {
+ for (Object item : value) {
+ params.add(new Pair(name, escapeString(parameterToString(item))));
+ }
+ return params;
+ }
+
+ // collectionFormat is assumed to be "csv" by default
+ String delimiter = ",";
+
+ // escape all delimiters except commas, which are URI reserved
+ // characters
+ if ("ssv".equals(collectionFormat)) {
+ delimiter = escapeString(" ");
+ } else if ("tsv".equals(collectionFormat)) {
+ delimiter = escapeString("\t");
+ } else if ("pipes".equals(collectionFormat)) {
+ delimiter = escapeString("|");
+ }
+
+ StringBuilder sb = new StringBuilder();
+ for (Object item : value) {
+ sb.append(delimiter);
+ sb.append(escapeString(parameterToString(item)));
+ }
+
+ params.add(new Pair(name, sb.substring(delimiter.length())));
+
+ return params;
+ }
+
+ /**
+ * Formats the specified free-form query parameters to a list of {@code Pair} objects.
+ *
+ * @param value The free-form query parameters.
+ * @return A list of {@code Pair} objects.
+ */
+ public List freeFormParameterToPairs(Object value) {
+ List params = new ArrayList<>();
+
+ // preconditions
+ if (value == null || !(value instanceof Map )) {
+ return params;
+ }
+
+ final Map valuesMap = (Map) value;
+
+ for (Map.Entry entry : valuesMap.entrySet()) {
+ params.add(new Pair(entry.getKey(), parameterToString(entry.getValue())));
+ }
+
+ return params;
+ }
+
+
+ /**
+ * Formats the specified collection path parameter to a string value.
+ *
+ * @param collectionFormat The collection format of the parameter.
+ * @param value The value of the parameter.
+ * @return String representation of the parameter
+ */
+ public String collectionPathParameterToString(String collectionFormat, Collection value) {
+ // create the value based on the collection format
+ if ("multi".equals(collectionFormat)) {
+ // not valid for path params
+ return parameterToString(value);
+ }
+
+ // collectionFormat is assumed to be "csv" by default
+ String delimiter = ",";
+
+ if ("ssv".equals(collectionFormat)) {
+ delimiter = " ";
+ } else if ("tsv".equals(collectionFormat)) {
+ delimiter = "\t";
+ } else if ("pipes".equals(collectionFormat)) {
+ delimiter = "|";
+ }
+
+ StringBuilder sb = new StringBuilder() ;
+ for (Object item : value) {
+ sb.append(delimiter);
+ sb.append(parameterToString(item));
+ }
+
+ return sb.substring(delimiter.length());
+ }
+
+ /**
+ * Sanitize filename by removing path.
+ * e.g. ../../sun.gif becomes sun.gif
+ *
+ * @param filename The filename to be sanitized
+ * @return The sanitized filename
+ */
+ public String sanitizeFilename(String filename) {
+ return filename.replaceAll(".*[/\\\\]", "");
+ }
+
+ /**
+ * Check if the given MIME is a JSON MIME.
+ * JSON MIME examples:
+ * application/json
+ * application/json; charset=UTF8
+ * APPLICATION/JSON
+ * application/vnd.company+json
+ * "* / *" is also default to JSON
+ * @param mime MIME (Multipurpose Internet Mail Extensions)
+ * @return True if the given MIME is JSON, false otherwise.
+ */
+ public boolean isJsonMime(String mime) {
+ String jsonMime = "(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$";
+ return mime != null && (mime.matches(jsonMime) || mime.equals("*/*"));
+ }
+
+ /**
+ * Select the Accept header's value from the given accepts array:
+ * if JSON exists in the given array, use it;
+ * otherwise use all of them (joining into a string)
+ *
+ * @param accepts The accepts array to select from
+ * @return The Accept header to use. If the given array is empty,
+ * null will be returned (not to set the Accept header explicitly).
+ */
+ public String selectHeaderAccept(String[] accepts) {
+ if (accepts.length == 0) {
+ return null;
+ }
+ for (String accept : accepts) {
+ if (isJsonMime(accept)) {
+ return accept;
+ }
+ }
+ return StringUtil.join(accepts, ",");
+ }
+
+ /**
+ * Select the Content-Type header's value from the given array:
+ * if JSON exists in the given array, use it;
+ * otherwise use the first one of the array.
+ *
+ * @param contentTypes The Content-Type array to select from
+ * @return The Content-Type header to use. If the given array is empty,
+ * returns null. If it matches "any", JSON will be used.
+ */
+ public String selectHeaderContentType(String[] contentTypes) {
+ if (contentTypes.length == 0) {
+ return null;
+ }
+
+ if (contentTypes[0].equals("*/*")) {
+ return "application/json";
+ }
+
+ for (String contentType : contentTypes) {
+ if (isJsonMime(contentType)) {
+ return contentType;
+ }
+ }
+
+ return contentTypes[0];
+ }
+
+ /**
+ * Escape the given string to be used as URL query value.
+ *
+ * @param str String to be escaped
+ * @return Escaped string
+ */
+ public String escapeString(String str) {
+ try {
+ return URLEncoder.encode(str, "utf8").replaceAll("\\+", "%20");
+ } catch (UnsupportedEncodingException e) {
+ return str;
+ }
+ }
+
+ /**
+ * Deserialize response body to Java object, according to the return type and
+ * the Content-Type response header.
+ *
+ * @param Type
+ * @param response HTTP response
+ * @param returnType The type of the Java object
+ * @return The deserialized Java object
+ * @throws io.openepi.common.ApiException If fail to deserialize response body, i.e. cannot read response body
+ * or the Content-Type of the response is not supported.
+ */
+ @SuppressWarnings("unchecked")
+ public T deserialize(Response response, Type returnType) throws ApiException {
+ if (response == null || returnType == null) {
+ return null;
+ }
+
+ if ("byte[]".equals(returnType.toString())) {
+ // Handle binary response (byte array).
+ try {
+ return (T) response.body().bytes();
+ } catch (IOException e) {
+ throw new ApiException(e);
+ }
+ } else if (returnType.equals(File.class)) {
+ // Handle file downloading.
+ return (T) downloadFileFromResponse(response);
+ }
+
+ String respBody;
+ try {
+ if (response.body() != null)
+ respBody = response.body().string();
+ else
+ respBody = null;
+ } catch (IOException e) {
+ throw new ApiException(e);
+ }
+
+ if (respBody == null || "".equals(respBody)) {
+ return null;
+ }
+
+ String contentType = response.headers().get("Content-Type");
+ if (contentType == null) {
+ // ensuring a default content type
+ contentType = "application/json";
+ }
+ if (isJsonMime(contentType)) {
+ return JSON.deserialize(respBody, returnType);
+ } else if (returnType.equals(String.class)) {
+ // Expecting string, return the raw response body.
+ return (T) respBody;
+ } else {
+ throw new ApiException(
+ "Content type \"" + contentType + "\" is not supported for type: " + returnType,
+ response.code(),
+ response.headers().toMultimap(),
+ respBody);
+ }
+ }
+
+ /**
+ * Serialize the given Java object into request body according to the object's
+ * class and the request Content-Type.
+ *
+ * @param obj The Java object
+ * @param contentType The request Content-Type
+ * @return The serialized request body
+ * @throws io.openepi.common.ApiException If fail to serialize the given object
+ */
+ public RequestBody serialize(Object obj, String contentType) throws ApiException {
+ if (obj instanceof byte[]) {
+ // Binary (byte array) body parameter support.
+ return RequestBody.create((byte[]) obj, MediaType.parse(contentType));
+ } else if (obj instanceof File) {
+ // File body parameter support.
+ return RequestBody.create((File) obj, MediaType.parse(contentType));
+ } else if ("text/plain".equals(contentType) && obj instanceof String) {
+ return RequestBody.create((String) obj, MediaType.parse(contentType));
+ } else if (isJsonMime(contentType)) {
+ String content;
+ if (obj != null) {
+ content = JSON.serialize(obj);
+ } else {
+ content = null;
+ }
+ return RequestBody.create(content, MediaType.parse(contentType));
+ } else if (obj instanceof String) {
+ return RequestBody.create((String) obj, MediaType.parse(contentType));
+ } else {
+ throw new ApiException("Content type \"" + contentType + "\" is not supported");
+ }
+ }
+
+ /**
+ * Download file from the given response.
+ *
+ * @param response An instance of the Response object
+ * @throws io.openepi.common.ApiException If fail to read file content from response and write to disk
+ * @return Downloaded file
+ */
+ public File downloadFileFromResponse(Response response) throws ApiException {
+ try {
+ File file = prepareDownloadFile(response);
+ BufferedSink sink = Okio.buffer(Okio.sink(file));
+ sink.writeAll(response.body().source());
+ sink.close();
+ return file;
+ } catch (IOException e) {
+ throw new ApiException(e);
+ }
+ }
+
+ /**
+ * Prepare file for download
+ *
+ * @param response An instance of the Response object
+ * @return Prepared file for the download
+ * @throws java.io.IOException If fail to prepare file for download
+ */
+ public File prepareDownloadFile(Response response) throws IOException {
+ String filename = null;
+ String contentDisposition = response.header("Content-Disposition");
+ if (contentDisposition != null && !"".equals(contentDisposition)) {
+ // Get filename from the Content-Disposition header.
+ Pattern pattern = Pattern.compile("filename=['\"]?([^'\"\\s]+)['\"]?");
+ Matcher matcher = pattern.matcher(contentDisposition);
+ if (matcher.find()) {
+ filename = sanitizeFilename(matcher.group(1));
+ }
+ }
+
+ String prefix = null;
+ String suffix = null;
+ if (filename == null) {
+ prefix = "download-";
+ suffix = "";
+ } else {
+ int pos = filename.lastIndexOf(".");
+ if (pos == -1) {
+ prefix = filename + "-";
+ } else {
+ prefix = filename.substring(0, pos) + "-";
+ suffix = filename.substring(pos);
+ }
+ // Files.createTempFile requires the prefix to be at least three characters long
+ if (prefix.length() < 3)
+ prefix = "download-";
+ }
+
+ if (tempFolderPath == null)
+ return Files.createTempFile(prefix, suffix).toFile();
+ else
+ return Files.createTempFile(Paths.get(tempFolderPath), prefix, suffix).toFile();
+ }
+
+ /**
+ * {@link #execute(Call, Type)}
+ *
+ * @param Type
+ * @param call An instance of the Call object
+ * @return ApiResponse<T>
+ * @throws io.openepi.common.ApiException If fail to execute the call
+ */
+ public ApiResponse execute(Call call) throws ApiException {
+ return execute(call, null);
+ }
+
+ /**
+ * Execute HTTP call and deserialize the HTTP response body into the given return type.
+ *
+ * @param returnType The return type used to deserialize HTTP response body
+ * @param The return type corresponding to (same with) returnType
+ * @param call Call
+ * @return ApiResponse object containing response status, headers and
+ * data, which is a Java object deserialized from response body and would be null
+ * when returnType is null.
+ * @throws io.openepi.common.ApiException If fail to execute the call
+ */
+ public ApiResponse execute(Call call, Type returnType) throws ApiException {
+ try {
+ Response response = call.execute();
+ T data = handleResponse(response, returnType);
+ return new ApiResponse(response.code(), response.headers().toMultimap(), data);
+ } catch (IOException e) {
+ throw new ApiException(e);
+ }
+ }
+
+ /**
+ * {@link #executeAsync(Call, Type, ApiCallback)}
+ *
+ * @param Type
+ * @param call An instance of the Call object
+ * @param callback ApiCallback<T>
+ */
+ public void executeAsync(Call call, ApiCallback callback) {
+ executeAsync(call, null, callback);
+ }
+
+ /**
+ * Execute HTTP call asynchronously.
+ *
+ * @param Type
+ * @param call The callback to be executed when the API call finishes
+ * @param returnType Return type
+ * @param callback ApiCallback
+ * @see #execute(Call, Type)
+ */
+ @SuppressWarnings("unchecked")
+ public void executeAsync(Call call, final Type returnType, final ApiCallback callback) {
+ call.enqueue(new Callback() {
+ @Override
+ public void onFailure(Call call, IOException e) {
+ callback.onFailure(new ApiException(e), 0, null);
+ }
+
+ @Override
+ public void onResponse(Call call, Response response) throws IOException {
+ T result;
+ try {
+ result = (T) handleResponse(response, returnType);
+ } catch (ApiException e) {
+ callback.onFailure(e, response.code(), response.headers().toMultimap());
+ return;
+ } catch (Exception e) {
+ callback.onFailure(new ApiException(e), response.code(), response.headers().toMultimap());
+ return;
+ }
+ callback.onSuccess(result, response.code(), response.headers().toMultimap());
+ }
+ });
+ }
+
+ /**
+ * Handle the given response, return the deserialized object when the response is successful.
+ *
+ * @param Type
+ * @param response Response
+ * @param returnType Return type
+ * @return Type
+ * @throws io.openepi.common.ApiException If the response has an unsuccessful status code or
+ * fail to deserialize the response body
+ */
+ public T handleResponse(Response response, Type returnType) throws ApiException {
+ if (response.isSuccessful()) {
+ if (returnType == null || response.code() == 204) {
+ // returning null if the returnType is not defined,
+ // or the status code is 204 (No Content)
+ if (response.body() != null) {
+ try {
+ response.body().close();
+ } catch (Exception e) {
+ throw new ApiException(response.message(), e, response.code(), response.headers().toMultimap());
+ }
+ }
+ return null;
+ } else {
+ return deserialize(response, returnType);
+ }
+ } else {
+ String respBody = null;
+ if (response.body() != null) {
+ try {
+ respBody = response.body().string();
+ } catch (IOException e) {
+ throw new ApiException(response.message(), e, response.code(), response.headers().toMultimap());
+ }
+ }
+ throw new ApiException(response.message(), response.code(), response.headers().toMultimap(), respBody);
+ }
+ }
+
+ /**
+ * Build HTTP call with the given options.
+ *
+ * @param baseUrl The base URL
+ * @param path The sub-path of the HTTP URL
+ * @param method The request method, one of "GET", "HEAD", "OPTIONS", "POST", "PUT", "PATCH" and "DELETE"
+ * @param queryParams The query parameters
+ * @param collectionQueryParams The collection query parameters
+ * @param body The request body object
+ * @param headerParams The header parameters
+ * @param cookieParams The cookie parameters
+ * @param formParams The form parameters
+ * @param authNames The authentications to apply
+ * @param callback Callback for upload/download progress
+ * @return The HTTP call
+ * @throws io.openepi.common.ApiException If fail to serialize the request body object
+ */
+ public Call buildCall(String baseUrl, String path, String method, List queryParams, List collectionQueryParams, Object body, Map headerParams, Map cookieParams, Map formParams, String[] authNames, ApiCallback callback) throws ApiException {
+ Request request = buildRequest(baseUrl, path, method, queryParams, collectionQueryParams, body, headerParams, cookieParams, formParams, authNames, callback);
+
+ return httpClient.newCall(request);
+ }
+
+ /**
+ * Build an HTTP request with the given options.
+ *
+ * @param baseUrl The base URL
+ * @param path The sub-path of the HTTP URL
+ * @param method The request method, one of "GET", "HEAD", "OPTIONS", "POST", "PUT", "PATCH" and "DELETE"
+ * @param queryParams The query parameters
+ * @param collectionQueryParams The collection query parameters
+ * @param body The request body object
+ * @param headerParams The header parameters
+ * @param cookieParams The cookie parameters
+ * @param formParams The form parameters
+ * @param authNames The authentications to apply
+ * @param callback Callback for upload/download progress
+ * @return The HTTP request
+ * @throws io.openepi.common.ApiException If fail to serialize the request body object
+ */
+ public Request buildRequest(String baseUrl, String path, String method, List queryParams, List collectionQueryParams, Object body, Map headerParams, Map cookieParams, Map formParams, String[] authNames, ApiCallback callback) throws ApiException {
+ final String url = buildUrl(baseUrl, path, queryParams, collectionQueryParams);
+
+ // prepare HTTP request body
+ RequestBody reqBody;
+ String contentType = headerParams.get("Content-Type");
+ String contentTypePure = contentType;
+ if (contentTypePure != null && contentTypePure.contains(";")) {
+ contentTypePure = contentType.substring(0, contentType.indexOf(";"));
+ }
+ if (!HttpMethod.permitsRequestBody(method)) {
+ reqBody = null;
+ } else if ("application/x-www-form-urlencoded".equals(contentTypePure)) {
+ reqBody = buildRequestBodyFormEncoding(formParams);
+ } else if ("multipart/form-data".equals(contentTypePure)) {
+ reqBody = buildRequestBodyMultipart(formParams);
+ } else if (body == null) {
+ if ("DELETE".equals(method)) {
+ // allow calling DELETE without sending a request body
+ reqBody = null;
+ } else {
+ // use an empty request body (for POST, PUT and PATCH)
+ reqBody = RequestBody.create("", contentType == null ? null : MediaType.parse(contentType));
+ }
+ } else {
+ reqBody = serialize(body, contentType);
+ }
+
+ List updatedQueryParams = new ArrayList<>(queryParams);
+
+ // update parameters with authentication settings
+ updateParamsForAuth(authNames, updatedQueryParams, headerParams, cookieParams, requestBodyToString(reqBody), method, URI.create(url));
+
+ final Request.Builder reqBuilder = new Request.Builder().url(buildUrl(baseUrl, path, updatedQueryParams, collectionQueryParams));
+ processHeaderParams(headerParams, reqBuilder);
+ processCookieParams(cookieParams, reqBuilder);
+
+ // Associate callback with request (if not null) so interceptor can
+ // access it when creating ProgressResponseBody
+ reqBuilder.tag(callback);
+
+ Request request = null;
+
+ if (callback != null && reqBody != null) {
+ ProgressRequestBody progressRequestBody = new ProgressRequestBody(reqBody, callback);
+ request = reqBuilder.method(method, progressRequestBody).build();
+ } else {
+ request = reqBuilder.method(method, reqBody).build();
+ }
+
+ return request;
+ }
+
+ /**
+ * Build full URL by concatenating base path, the given sub path and query parameters.
+ *
+ * @param baseUrl The base URL
+ * @param path The sub path
+ * @param queryParams The query parameters
+ * @param collectionQueryParams The collection query parameters
+ * @return The full URL
+ */
+ public String buildUrl(String baseUrl, String path, List queryParams, List collectionQueryParams) {
+ final StringBuilder url = new StringBuilder();
+ if (baseUrl != null) {
+ url.append(baseUrl).append(path);
+ } else {
+ String baseURL;
+ if (serverIndex != null) {
+ if (serverIndex < 0 || serverIndex >= servers.size()) {
+ throw new ArrayIndexOutOfBoundsException(String.format(
+ "Invalid index %d when selecting the host settings. Must be less than %d", serverIndex, servers.size()
+ ));
+ }
+ baseURL = servers.get(serverIndex).URL(serverVariables);
+ } else {
+ baseURL = basePath;
+ }
+ url.append(baseURL).append(path);
+ }
+
+ if (queryParams != null && !queryParams.isEmpty()) {
+ // support (constant) query string in `path`, e.g. "/posts?draft=1"
+ String prefix = path.contains("?") ? "&" : "?";
+ for (Pair param : queryParams) {
+ if (param.getValue() != null) {
+ if (prefix != null) {
+ url.append(prefix);
+ prefix = null;
+ } else {
+ url.append("&");
+ }
+ String value = parameterToString(param.getValue());
+ url.append(escapeString(param.getName())).append("=").append(escapeString(value));
+ }
+ }
+ }
+
+ if (collectionQueryParams != null && !collectionQueryParams.isEmpty()) {
+ String prefix = url.toString().contains("?") ? "&" : "?";
+ for (Pair param : collectionQueryParams) {
+ if (param.getValue() != null) {
+ if (prefix != null) {
+ url.append(prefix);
+ prefix = null;
+ } else {
+ url.append("&");
+ }
+ String value = parameterToString(param.getValue());
+ // collection query parameter value already escaped as part of parameterToPairs
+ url.append(escapeString(param.getName())).append("=").append(value);
+ }
+ }
+ }
+
+ return url.toString();
+ }
+
+ /**
+ * Set header parameters to the request builder, including default headers.
+ *
+ * @param headerParams Header parameters in the form of Map
+ * @param reqBuilder Request.Builder
+ */
+ public void processHeaderParams(Map headerParams, Request.Builder reqBuilder) {
+ for (Entry param : headerParams.entrySet()) {
+ reqBuilder.header(param.getKey(), parameterToString(param.getValue()));
+ }
+ for (Entry header : defaultHeaderMap.entrySet()) {
+ if (!headerParams.containsKey(header.getKey())) {
+ reqBuilder.header(header.getKey(), parameterToString(header.getValue()));
+ }
+ }
+ }
+
+ /**
+ * Set cookie parameters to the request builder, including default cookies.
+ *
+ * @param cookieParams Cookie parameters in the form of Map
+ * @param reqBuilder Request.Builder
+ */
+ public void processCookieParams(Map cookieParams, Request.Builder reqBuilder) {
+ for (Entry param : cookieParams.entrySet()) {
+ reqBuilder.addHeader("Cookie", String.format("%s=%s", param.getKey(), param.getValue()));
+ }
+ for (Entry param : defaultCookieMap.entrySet()) {
+ if (!cookieParams.containsKey(param.getKey())) {
+ reqBuilder.addHeader("Cookie", String.format("%s=%s", param.getKey(), param.getValue()));
+ }
+ }
+ }
+
+ /**
+ * Update query and header parameters based on authentication settings.
+ *
+ * @param authNames The authentications to apply
+ * @param queryParams List of query parameters
+ * @param headerParams Map of header parameters
+ * @param cookieParams Map of cookie parameters
+ * @param payload HTTP request body
+ * @param method HTTP method
+ * @param uri URI
+ * @throws io.openepi.common.ApiException If fails to update the parameters
+ */
+ public void updateParamsForAuth(String[] authNames, List queryParams, Map headerParams,
+ Map cookieParams, String payload, String method, URI uri) throws ApiException {
+ for (String authName : authNames) {
+ Authentication auth = authentications.get(authName);
+ if (auth == null) {
+ throw new RuntimeException("Authentication undefined: " + authName);
+ }
+ auth.applyToParams(queryParams, headerParams, cookieParams, payload, method, uri);
+ }
+ }
+
+ /**
+ * Build a form-encoding request body with the given form parameters.
+ *
+ * @param formParams Form parameters in the form of Map
+ * @return RequestBody
+ */
+ public RequestBody buildRequestBodyFormEncoding(Map formParams) {
+ okhttp3.FormBody.Builder formBuilder = new okhttp3.FormBody.Builder();
+ for (Entry param : formParams.entrySet()) {
+ formBuilder.add(param.getKey(), parameterToString(param.getValue()));
+ }
+ return formBuilder.build();
+ }
+
+ /**
+ * Build a multipart (file uploading) request body with the given form parameters,
+ * which could contain text fields and file fields.
+ *
+ * @param formParams Form parameters in the form of Map
+ * @return RequestBody
+ */
+ public RequestBody buildRequestBodyMultipart(Map formParams) {
+ MultipartBody.Builder mpBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
+ for (Entry param : formParams.entrySet()) {
+ if (param.getValue() instanceof File) {
+ File file = (File) param.getValue();
+ addPartToMultiPartBuilder(mpBuilder, param.getKey(), file);
+ } else if (param.getValue() instanceof List) {
+ List list = (List) param.getValue();
+ for (Object item: list) {
+ if (item instanceof File) {
+ addPartToMultiPartBuilder(mpBuilder, param.getKey(), (File) item);
+ } else {
+ addPartToMultiPartBuilder(mpBuilder, param.getKey(), param.getValue());
+ }
+ }
+ } else {
+ addPartToMultiPartBuilder(mpBuilder, param.getKey(), param.getValue());
+ }
+ }
+ return mpBuilder.build();
+ }
+
+ /**
+ * Guess Content-Type header from the given file (defaults to "application/octet-stream").
+ *
+ * @param file The given file
+ * @return The guessed Content-Type
+ */
+ public String guessContentTypeFromFile(File file) {
+ String contentType = URLConnection.guessContentTypeFromName(file.getName());
+ if (contentType == null) {
+ return "application/octet-stream";
+ } else {
+ return contentType;
+ }
+ }
+
+ /**
+ * Add a Content-Disposition Header for the given key and file to the MultipartBody Builder.
+ *
+ * @param mpBuilder MultipartBody.Builder
+ * @param key The key of the Header element
+ * @param file The file to add to the Header
+ */
+ private void addPartToMultiPartBuilder(MultipartBody.Builder mpBuilder, String key, File file) {
+ Headers partHeaders = Headers.of("Content-Disposition", "form-data; name=\"" + key + "\"; filename=\"" + file.getName() + "\"");
+ MediaType mediaType = MediaType.parse(guessContentTypeFromFile(file));
+ mpBuilder.addPart(partHeaders, RequestBody.create(file, mediaType));
+ }
+
+ /**
+ * Add a Content-Disposition Header for the given key and complex object to the MultipartBody Builder.
+ *
+ * @param mpBuilder MultipartBody.Builder
+ * @param key The key of the Header element
+ * @param obj The complex object to add to the Header
+ */
+ private void addPartToMultiPartBuilder(MultipartBody.Builder mpBuilder, String key, Object obj) {
+ RequestBody requestBody;
+ if (obj instanceof String) {
+ requestBody = RequestBody.create((String) obj, MediaType.parse("text/plain"));
+ } else {
+ String content;
+ if (obj != null) {
+ content = JSON.serialize(obj);
+ } else {
+ content = null;
+ }
+ requestBody = RequestBody.create(content, MediaType.parse("application/json"));
+ }
+
+ Headers partHeaders = Headers.of("Content-Disposition", "form-data; name=\"" + key + "\"");
+ mpBuilder.addPart(partHeaders, requestBody);
+ }
+
+ /**
+ * Get network interceptor to add it to the httpClient to track download progress for
+ * async requests.
+ */
+ private Interceptor getProgressInterceptor() {
+ return new Interceptor() {
+ @Override
+ public Response intercept(Interceptor.Chain chain) throws IOException {
+ final Request request = chain.request();
+ final Response originalResponse = chain.proceed(request);
+ if (request.tag() instanceof ApiCallback) {
+ final ApiCallback callback = (ApiCallback) request.tag();
+ return originalResponse.newBuilder()
+ .body(new ProgressResponseBody(originalResponse.body(), callback))
+ .build();
+ }
+ return originalResponse;
+ }
+ };
+ }
+
+ /**
+ * Apply SSL related settings to httpClient according to the current values of
+ * verifyingSsl and sslCaCert.
+ */
+ private void applySslSettings() {
+ try {
+ TrustManager[] trustManagers;
+ HostnameVerifier hostnameVerifier;
+ if (!verifyingSsl) {
+ trustManagers = new TrustManager[]{
+ new X509TrustManager() {
+ @Override
+ public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
+ }
+
+ @Override
+ public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
+ }
+
+ @Override
+ public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+ return new java.security.cert.X509Certificate[]{};
+ }
+ }
+ };
+ hostnameVerifier = new HostnameVerifier() {
+ @Override
+ public boolean verify(String hostname, SSLSession session) {
+ return true;
+ }
+ };
+ } else {
+ TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+
+ if (sslCaCert == null) {
+ trustManagerFactory.init((KeyStore) null);
+ } else {
+ char[] password = null; // Any password will work.
+ CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
+ Collection extends Certificate> certificates = certificateFactory.generateCertificates(sslCaCert);
+ if (certificates.isEmpty()) {
+ throw new IllegalArgumentException("expected non-empty set of trusted certificates");
+ }
+ KeyStore caKeyStore = newEmptyKeyStore(password);
+ int index = 0;
+ for (Certificate certificate : certificates) {
+ String certificateAlias = "ca" + (index++);
+ caKeyStore.setCertificateEntry(certificateAlias, certificate);
+ }
+ trustManagerFactory.init(caKeyStore);
+ }
+ trustManagers = trustManagerFactory.getTrustManagers();
+ hostnameVerifier = OkHostnameVerifier.INSTANCE;
+ }
+
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(keyManagers, trustManagers, new SecureRandom());
+ httpClient = httpClient.newBuilder()
+ .sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustManagers[0])
+ .hostnameVerifier(hostnameVerifier)
+ .build();
+ } catch (GeneralSecurityException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityException {
+ try {
+ KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
+ keyStore.load(null, password);
+ return keyStore;
+ } catch (IOException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ /**
+ * Convert the HTTP request body to a string.
+ *
+ * @param requestBody The HTTP request object
+ * @return The string representation of the HTTP request body
+ * @throws io.openepi.common.ApiException If fail to serialize the request body object into a string
+ */
+ private String requestBodyToString(RequestBody requestBody) throws ApiException {
+ if (requestBody != null) {
+ try {
+ final Buffer buffer = new Buffer();
+ requestBody.writeTo(buffer);
+ return buffer.readUtf8();
+ } catch (final IOException e) {
+ throw new ApiException(e);
+ }
+ }
+
+ // empty http request body
+ return "";
+ }
+}
diff --git a/src/main/java/io/openepi/agriculture/Configuration.java b/src/main/java/io/openepi/agriculture/Configuration.java
new file mode 100644
index 0000000..9188996
--- /dev/null
+++ b/src/main/java/io/openepi/agriculture/Configuration.java
@@ -0,0 +1,41 @@
+/*
+ * Agriculture API
+ * This API is used to get aggregated data from Deforestation, Flood, Weather and Soil APIs.
+ *
+ * The version of the OpenAPI document: 1.0.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+
+package io.openepi.agriculture;
+
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2024-12-02T12:55:09.550932+01:00[Europe/Oslo]", comments = "Generator version: 7.8.0")
+public class Configuration {
+ public static final String VERSION = "1.0.0";
+
+ private static ApiClient defaultApiClient = new ApiClient();
+
+ /**
+ * Get the default API client, which would be used when creating API
+ * instances without providing an API client.
+ *
+ * @return Default API client
+ */
+ public static ApiClient getDefaultApiClient() {
+ return defaultApiClient;
+ }
+
+ /**
+ * Set the default API client, which would be used when creating API
+ * instances without providing an API client.
+ *
+ * @param apiClient API client
+ */
+ public static void setDefaultApiClient(ApiClient apiClient) {
+ defaultApiClient = apiClient;
+ }
+}
diff --git a/src/main/java/io/openepi/agriculture/JSON.java b/src/main/java/io/openepi/agriculture/JSON.java
new file mode 100644
index 0000000..f09e0a7
--- /dev/null
+++ b/src/main/java/io/openepi/agriculture/JSON.java
@@ -0,0 +1,405 @@
+/*
+ * Agriculture API
+ * This API is used to get aggregated data from Deforestation, Flood, Weather and Soil APIs.
+ *
+ * The version of the OpenAPI document: 1.0.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+
+package io.openepi.agriculture;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonParseException;
+import com.google.gson.TypeAdapter;
+import com.google.gson.internal.bind.util.ISO8601Utils;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+import com.google.gson.JsonElement;
+import io.gsonfire.GsonFireBuilder;
+import io.gsonfire.TypeSelector;
+
+import okio.ByteString;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.lang.reflect.Type;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.ParsePosition;
+import java.time.LocalDate;
+import java.time.OffsetDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Map;
+import java.util.HashMap;
+
+/*
+ * A JSON utility class
+ *
+ * NOTE: in the future, this class may be converted to static, which may break
+ * backward-compatibility
+ */
+public class JSON {
+ private static Gson gson;
+ private static boolean isLenientOnJson = false;
+ private static DateTypeAdapter dateTypeAdapter = new DateTypeAdapter();
+ private static SqlDateTypeAdapter sqlDateTypeAdapter = new SqlDateTypeAdapter();
+ private static OffsetDateTimeTypeAdapter offsetDateTimeTypeAdapter = new OffsetDateTimeTypeAdapter();
+ private static LocalDateTypeAdapter localDateTypeAdapter = new LocalDateTypeAdapter();
+ private static ByteArrayAdapter byteArrayAdapter = new ByteArrayAdapter();
+
+ @SuppressWarnings("unchecked")
+ public static GsonBuilder createGson() {
+ GsonFireBuilder fireBuilder = new GsonFireBuilder()
+ ;
+ GsonBuilder builder = fireBuilder.createGsonBuilder();
+ return builder;
+ }
+
+ private static String getDiscriminatorValue(JsonElement readElement, String discriminatorField) {
+ JsonElement element = readElement.getAsJsonObject().get(discriminatorField);
+ if (null == element) {
+ throw new IllegalArgumentException("missing discriminator field: <" + discriminatorField + ">");
+ }
+ return element.getAsString();
+ }
+
+ /**
+ * Returns the Java class that implements the OpenAPI schema for the specified discriminator value.
+ *
+ * @param classByDiscriminatorValue The map of discriminator values to Java classes.
+ * @param discriminatorValue The value of the OpenAPI discriminator in the input data.
+ * @return The Java class that implements the OpenAPI schema
+ */
+ private static Class getClassByDiscriminator(Map classByDiscriminatorValue, String discriminatorValue) {
+ Class clazz = (Class) classByDiscriminatorValue.get(discriminatorValue);
+ if (null == clazz) {
+ throw new IllegalArgumentException("cannot determine model class of name: <" + discriminatorValue + ">");
+ }
+ return clazz;
+ }
+
+ static {
+ GsonBuilder gsonBuilder = createGson();
+ gsonBuilder.registerTypeAdapter(Date.class, dateTypeAdapter);
+ gsonBuilder.registerTypeAdapter(java.sql.Date.class, sqlDateTypeAdapter);
+ gsonBuilder.registerTypeAdapter(OffsetDateTime.class, offsetDateTimeTypeAdapter);
+ gsonBuilder.registerTypeAdapter(LocalDate.class, localDateTypeAdapter);
+ gsonBuilder.registerTypeAdapter(byte[].class, byteArrayAdapter);
+ gsonBuilder.registerTypeAdapterFactory(new io.openepi.agriculture.model.ModelsDeforestation.CustomTypeAdapterFactory());
+ gsonBuilder.registerTypeAdapterFactory(new io.openepi.agriculture.model.ModelsFlood.CustomTypeAdapterFactory());
+ gsonBuilder.registerTypeAdapterFactory(new io.openepi.agriculture.model.ModelsSoilType.CustomTypeAdapterFactory());
+ gsonBuilder.registerTypeAdapterFactory(new io.openepi.agriculture.model.ModelsSummary.CustomTypeAdapterFactory());
+ gsonBuilder.registerTypeAdapterFactory(new io.openepi.agriculture.model.ModelsWeather.CustomTypeAdapterFactory());
+ gson = gsonBuilder.create();
+ }
+
+ /**
+ * Get Gson.
+ *
+ * @return Gson
+ */
+ public static Gson getGson() {
+ return gson;
+ }
+
+ /**
+ * Set Gson.
+ *
+ * @param gson Gson
+ */
+ public static void setGson(Gson gson) {
+ JSON.gson = gson;
+ }
+
+ public static void setLenientOnJson(boolean lenientOnJson) {
+ isLenientOnJson = lenientOnJson;
+ }
+
+ /**
+ * Serialize the given Java object into JSON string.
+ *
+ * @param obj Object
+ * @return String representation of the JSON
+ */
+ public static String serialize(Object obj) {
+ return gson.toJson(obj);
+ }
+
+ /**
+ * Deserialize the given JSON string to Java object.
+ *
+ * @param Type
+ * @param body The JSON string
+ * @param returnType The type to deserialize into
+ * @return The deserialized Java object
+ */
+ @SuppressWarnings("unchecked")
+ public static T deserialize(String body, Type returnType) {
+ try {
+ if (isLenientOnJson) {
+ JsonReader jsonReader = new JsonReader(new StringReader(body));
+ // see https://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/stream/JsonReader.html#setLenient(boolean)
+ jsonReader.setLenient(true);
+ return gson.fromJson(jsonReader, returnType);
+ } else {
+ return gson.fromJson(body, returnType);
+ }
+ } catch (JsonParseException e) {
+ // Fallback processing when failed to parse JSON form response body:
+ // return the response body string directly for the String return type;
+ if (returnType.equals(String.class)) {
+ return (T) body;
+ } else {
+ throw (e);
+ }
+ }
+ }
+
+ /**
+ * Gson TypeAdapter for Byte Array type
+ */
+ public static class ByteArrayAdapter extends TypeAdapter {
+
+ @Override
+ public void write(JsonWriter out, byte[] value) throws IOException {
+ if (value == null) {
+ out.nullValue();
+ } else {
+ out.value(ByteString.of(value).base64());
+ }
+ }
+
+ @Override
+ public byte[] read(JsonReader in) throws IOException {
+ switch (in.peek()) {
+ case NULL:
+ in.nextNull();
+ return null;
+ default:
+ String bytesAsBase64 = in.nextString();
+ ByteString byteString = ByteString.decodeBase64(bytesAsBase64);
+ return byteString.toByteArray();
+ }
+ }
+ }
+
+ /**
+ * Gson TypeAdapter for JSR310 OffsetDateTime type
+ */
+ public static class OffsetDateTimeTypeAdapter extends TypeAdapter {
+
+ private DateTimeFormatter formatter;
+
+ public OffsetDateTimeTypeAdapter() {
+ this(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
+ }
+
+ public OffsetDateTimeTypeAdapter(DateTimeFormatter formatter) {
+ this.formatter = formatter;
+ }
+
+ public void setFormat(DateTimeFormatter dateFormat) {
+ this.formatter = dateFormat;
+ }
+
+ @Override
+ public void write(JsonWriter out, OffsetDateTime date) throws IOException {
+ if (date == null) {
+ out.nullValue();
+ } else {
+ out.value(formatter.format(date));
+ }
+ }
+
+ @Override
+ public OffsetDateTime read(JsonReader in) throws IOException {
+ switch (in.peek()) {
+ case NULL:
+ in.nextNull();
+ return null;
+ default:
+ String date = in.nextString();
+ if (date.endsWith("+0000")) {
+ date = date.substring(0, date.length()-5) + "Z";
+ }
+ return OffsetDateTime.parse(date, formatter);
+ }
+ }
+ }
+
+ /**
+ * Gson TypeAdapter for JSR310 LocalDate type
+ */
+ public static class LocalDateTypeAdapter extends TypeAdapter {
+
+ private DateTimeFormatter formatter;
+
+ public LocalDateTypeAdapter() {
+ this(DateTimeFormatter.ISO_LOCAL_DATE);
+ }
+
+ public LocalDateTypeAdapter(DateTimeFormatter formatter) {
+ this.formatter = formatter;
+ }
+
+ public void setFormat(DateTimeFormatter dateFormat) {
+ this.formatter = dateFormat;
+ }
+
+ @Override
+ public void write(JsonWriter out, LocalDate date) throws IOException {
+ if (date == null) {
+ out.nullValue();
+ } else {
+ out.value(formatter.format(date));
+ }
+ }
+
+ @Override
+ public LocalDate read(JsonReader in) throws IOException {
+ switch (in.peek()) {
+ case NULL:
+ in.nextNull();
+ return null;
+ default:
+ String date = in.nextString();
+ return LocalDate.parse(date, formatter);
+ }
+ }
+ }
+
+ public static void setOffsetDateTimeFormat(DateTimeFormatter dateFormat) {
+ offsetDateTimeTypeAdapter.setFormat(dateFormat);
+ }
+
+ public static void setLocalDateFormat(DateTimeFormatter dateFormat) {
+ localDateTypeAdapter.setFormat(dateFormat);
+ }
+
+ /**
+ * Gson TypeAdapter for java.sql.Date type
+ * If the dateFormat is null, a simple "yyyy-MM-dd" format will be used
+ * (more efficient than SimpleDateFormat).
+ */
+ public static class SqlDateTypeAdapter extends TypeAdapter {
+
+ private DateFormat dateFormat;
+
+ public SqlDateTypeAdapter() {}
+
+ public SqlDateTypeAdapter(DateFormat dateFormat) {
+ this.dateFormat = dateFormat;
+ }
+
+ public void setFormat(DateFormat dateFormat) {
+ this.dateFormat = dateFormat;
+ }
+
+ @Override
+ public void write(JsonWriter out, java.sql.Date date) throws IOException {
+ if (date == null) {
+ out.nullValue();
+ } else {
+ String value;
+ if (dateFormat != null) {
+ value = dateFormat.format(date);
+ } else {
+ value = date.toString();
+ }
+ out.value(value);
+ }
+ }
+
+ @Override
+ public java.sql.Date read(JsonReader in) throws IOException {
+ switch (in.peek()) {
+ case NULL:
+ in.nextNull();
+ return null;
+ default:
+ String date = in.nextString();
+ try {
+ if (dateFormat != null) {
+ return new java.sql.Date(dateFormat.parse(date).getTime());
+ }
+ return new java.sql.Date(ISO8601Utils.parse(date, new ParsePosition(0)).getTime());
+ } catch (ParseException e) {
+ throw new JsonParseException(e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Gson TypeAdapter for java.util.Date type
+ * If the dateFormat is null, ISO8601Utils will be used.
+ */
+ public static class DateTypeAdapter extends TypeAdapter {
+
+ private DateFormat dateFormat;
+
+ public DateTypeAdapter() {}
+
+ public DateTypeAdapter(DateFormat dateFormat) {
+ this.dateFormat = dateFormat;
+ }
+
+ public void setFormat(DateFormat dateFormat) {
+ this.dateFormat = dateFormat;
+ }
+
+ @Override
+ public void write(JsonWriter out, Date date) throws IOException {
+ if (date == null) {
+ out.nullValue();
+ } else {
+ String value;
+ if (dateFormat != null) {
+ value = dateFormat.format(date);
+ } else {
+ value = ISO8601Utils.format(date, true);
+ }
+ out.value(value);
+ }
+ }
+
+ @Override
+ public Date read(JsonReader in) throws IOException {
+ try {
+ switch (in.peek()) {
+ case NULL:
+ in.nextNull();
+ return null;
+ default:
+ String date = in.nextString();
+ try {
+ if (dateFormat != null) {
+ return dateFormat.parse(date);
+ }
+ return ISO8601Utils.parse(date, new ParsePosition(0));
+ } catch (ParseException e) {
+ throw new JsonParseException(e);
+ }
+ }
+ } catch (IllegalArgumentException e) {
+ throw new JsonParseException(e);
+ }
+ }
+ }
+
+ public static void setDateFormat(DateFormat dateFormat) {
+ dateTypeAdapter.setFormat(dateFormat);
+ }
+
+ public static void setSqlDateFormat(DateFormat dateFormat) {
+ sqlDateTypeAdapter.setFormat(dateFormat);
+ }
+}
diff --git a/src/main/java/io/openepi/agriculture/api/AgricultureApi.java b/src/main/java/io/openepi/agriculture/api/AgricultureApi.java
new file mode 100644
index 0000000..0fc2380
--- /dev/null
+++ b/src/main/java/io/openepi/agriculture/api/AgricultureApi.java
@@ -0,0 +1,211 @@
+/*
+ * Agriculture API
+ * This API is used to get aggregated data from Deforestation, Flood, Weather and Soil APIs.
+ *
+ * The version of the OpenAPI document: 1.0.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+
+package io.openepi.agriculture.api;
+
+import io.openepi.agriculture.ApiClient;
+import io.openepi.agriculture.Configuration;
+import io.openepi.common.ApiCallback;
+import io.openepi.common.ApiException;
+import io.openepi.common.ApiResponse;
+import io.openepi.common.Pair;
+
+import com.google.gson.reflect.TypeToken;
+
+
+import java.math.BigDecimal;
+import io.openepi.agriculture.model.ModelsSummary;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class AgricultureApi {
+ private ApiClient localVarApiClient;
+ private int localHostIndex;
+ private String localCustomBaseUrl;
+
+ public AgricultureApi() {
+ this(Configuration.getDefaultApiClient());
+ }
+
+ public AgricultureApi(ApiClient apiClient) {
+ this.localVarApiClient = apiClient;
+ }
+
+ public ApiClient getApiClient() {
+ return localVarApiClient;
+ }
+
+ public void setApiClient(ApiClient apiClient) {
+ this.localVarApiClient = apiClient;
+ }
+
+ public int getHostIndex() {
+ return localHostIndex;
+ }
+
+ public void setHostIndex(int hostIndex) {
+ this.localHostIndex = hostIndex;
+ }
+
+ public String getCustomBaseUrl() {
+ return localCustomBaseUrl;
+ }
+
+ public void setCustomBaseUrl(String customBaseUrl) {
+ this.localCustomBaseUrl = customBaseUrl;
+ }
+
+ /**
+ * Build call for summaryGet
+ * @param lat Latitude (required)
+ * @param lon Longitude (required)
+ * @param _callback Callback for upload/download progress
+ * @return Call to execute
+ * @throws ApiException If fail to serialize the request body object
+ * @http.response.details
+
+ | Status Code | Description | Response Headers |
+ | 200 | OK | - |
+
+ */
+ public okhttp3.Call getSummaryCall(BigDecimal lat, BigDecimal lon, final ApiCallback _callback) throws ApiException {
+ String basePath = null;
+ // Operation Servers
+ String[] localBasePaths = new String[] { };
+
+ // Determine Base Path to Use
+ if (localCustomBaseUrl != null){
+ basePath = localCustomBaseUrl;
+ } else if ( localBasePaths.length > 0 ) {
+ basePath = localBasePaths[localHostIndex];
+ } else {
+ basePath = null;
+ }
+
+ Object localVarPostBody = null;
+
+ // create path and map variables
+ String localVarPath = "/summary";
+
+ List localVarQueryParams = new ArrayList();
+ List localVarCollectionQueryParams = new ArrayList();
+ Map localVarHeaderParams = new HashMap();
+ Map localVarCookieParams = new HashMap();
+ Map localVarFormParams = new HashMap();
+
+ if (lat != null) {
+ localVarQueryParams.addAll(localVarApiClient.parameterToPair("lat", lat));
+ }
+
+ if (lon != null) {
+ localVarQueryParams.addAll(localVarApiClient.parameterToPair("lon", lon));
+ }
+
+ final String[] localVarAccepts = {
+ "application/json"
+ };
+ final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts);
+ if (localVarAccept != null) {
+ localVarHeaderParams.put("Accept", localVarAccept);
+ }
+
+ final String[] localVarContentTypes = {
+ };
+ final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes);
+ if (localVarContentType != null) {
+ localVarHeaderParams.put("Content-Type", localVarContentType);
+ }
+
+ String[] localVarAuthNames = new String[] { };
+ return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback);
+ }
+
+ @SuppressWarnings("rawtypes")
+ private okhttp3.Call summaryGetValidateBeforeCall(BigDecimal lat, BigDecimal lon, final ApiCallback _callback) throws ApiException {
+ // verify the required parameter 'lat' is set
+ if (lat == null) {
+ throw new ApiException("Missing the required parameter 'lat' when calling summaryGet(Async)");
+ }
+
+ // verify the required parameter 'lon' is set
+ if (lon == null) {
+ throw new ApiException("Missing the required parameter 'lon' when calling summaryGet(Async)");
+ }
+
+ return getSummaryCall(lat, lon, _callback);
+
+ }
+
+ /**
+ * Get summary of agriculture data
+ * Gets aggregated data from Deforestation, Flood, Weather and Soil APIs. See the [API documentation](https://developer.openepi.io) for more information. There is an error field for each of the APIs. If a certain API does not respond, it will instead return with an error message in the field that belong to that API.
+ * @param lat Latitude (required)
+ * @param lon Longitude (required)
+ * @return ModelsSummary
+ * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
+ * @http.response.details
+
+ | Status Code | Description | Response Headers |
+ | 200 | OK | - |
+
+ */
+ public ModelsSummary getSummary(BigDecimal lat, BigDecimal lon) throws ApiException {
+ ApiResponse localVarResp = getSummaryWithHttpInfo(lat, lon);
+ return localVarResp.getData();
+ }
+
+ /**
+ * Get summary of agriculture data
+ * Gets aggregated data from Deforestation, Flood, Weather and Soil APIs. See the [API documentation](https://developer.openepi.io) for more information. There is an error field for each of the APIs. If a certain API does not respond, it will instead return with an error message in the field that belong to that API.
+ * @param lat Latitude (required)
+ * @param lon Longitude (required)
+ * @return ApiResponse<ModelsSummary>
+ * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
+ * @http.response.details
+
+ | Status Code | Description | Response Headers |
+ | 200 | OK | - |
+
+ */
+ public ApiResponse getSummaryWithHttpInfo(BigDecimal lat, BigDecimal lon) throws ApiException {
+ okhttp3.Call localVarCall = summaryGetValidateBeforeCall(lat, lon, null);
+ Type localVarReturnType = new TypeToken(){}.getType();
+ return localVarApiClient.execute(localVarCall, localVarReturnType);
+ }
+
+ /**
+ * Get summary of agriculture data (asynchronously)
+ * Gets aggregated data from Deforestation, Flood, Weather and Soil APIs. See the [API documentation](https://developer.openepi.io) for more information. There is an error field for each of the APIs. If a certain API does not respond, it will instead return with an error message in the field that belong to that API.
+ * @param lat Latitude (required)
+ * @param lon Longitude (required)
+ * @param _callback The callback to be executed when the API call finishes
+ * @return The request call
+ * @throws ApiException If fail to process the API call, e.g. serializing the request body object
+ * @http.response.details
+
+ | Status Code | Description | Response Headers |
+ | 200 | OK | - |
+
+ */
+ public okhttp3.Call getSummaryAsync(BigDecimal lat, BigDecimal lon, final ApiCallback _callback) throws ApiException {
+
+ okhttp3.Call localVarCall = summaryGetValidateBeforeCall(lat, lon, _callback);
+ Type localVarReturnType = new TypeToken(){}.getType();
+ localVarApiClient.executeAsync(localVarCall, localVarReturnType, _callback);
+ return localVarCall;
+ }
+}
diff --git a/src/main/java/io/openepi/agriculture/model/AbstractOpenApiSchema.java b/src/main/java/io/openepi/agriculture/model/AbstractOpenApiSchema.java
new file mode 100644
index 0000000..a3f8788
--- /dev/null
+++ b/src/main/java/io/openepi/agriculture/model/AbstractOpenApiSchema.java
@@ -0,0 +1,146 @@
+/*
+ * Agriculture API
+ * This API is used to get aggregated data from Deforestation, Flood, Weather and Soil APIs.
+ *
+ * The version of the OpenAPI document: 1.0.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+
+package io.openepi.agriculture.model;
+
+import io.openepi.common.ApiException;
+import java.util.Objects;
+import java.lang.reflect.Type;
+import java.util.Map;
+
+/**
+ * Abstract class for oneOf,anyOf schemas defined in OpenAPI spec
+ */
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2024-12-02T12:55:09.550932+01:00[Europe/Oslo]", comments = "Generator version: 7.8.0")
+public abstract class AbstractOpenApiSchema {
+
+ // store the actual instance of the schema/object
+ private Object instance;
+
+ // is nullable
+ private Boolean isNullable;
+
+ // schema type (e.g. oneOf, anyOf)
+ private final String schemaType;
+
+ public AbstractOpenApiSchema(String schemaType, Boolean isNullable) {
+ this.schemaType = schemaType;
+ this.isNullable = isNullable;
+ }
+
+ /**
+ * Get the list of oneOf/anyOf composed schemas allowed to be stored in this object
+ *
+ * @return an instance of the actual schema/object
+ */
+ public abstract Map> getSchemas();
+
+ /**
+ * Get the actual instance
+ *
+ * @return an instance of the actual schema/object
+ */
+ //@JsonValue
+ public Object getActualInstance() {return instance;}
+
+ /**
+ * Set the actual instance
+ *
+ * @param instance the actual instance of the schema/object
+ */
+ public void setActualInstance(Object instance) {this.instance = instance;}
+
+ /**
+ * Get the instant recursively when the schemas defined in oneOf/anyof happen to be oneOf/anyOf schema as well
+ *
+ * @return an instance of the actual schema/object
+ */
+ public Object getActualInstanceRecursively() {
+ return getActualInstanceRecursively(this);
+ }
+
+ private Object getActualInstanceRecursively(AbstractOpenApiSchema object) {
+ if (object.getActualInstance() == null) {
+ return null;
+ } else if (object.getActualInstance() instanceof AbstractOpenApiSchema) {
+ return getActualInstanceRecursively((AbstractOpenApiSchema)object.getActualInstance());
+ } else {
+ return object.getActualInstance();
+ }
+ }
+
+ /**
+ * Get the schema type (e.g. anyOf, oneOf)
+ *
+ * @return the schema type
+ */
+ public String getSchemaType() {
+ return schemaType;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("class ").append(getClass()).append(" {\n");
+ sb.append(" instance: ").append(toIndentedString(instance)).append("\n");
+ sb.append(" isNullable: ").append(toIndentedString(isNullable)).append("\n");
+ sb.append(" schemaType: ").append(toIndentedString(schemaType)).append("\n");
+ sb.append("}");
+ return sb.toString();
+ }
+
+ /**
+ * Convert the given object to string with each line indented by 4 spaces
+ * (except the first line).
+ */
+ private String toIndentedString(Object o) {
+ if (o == null) {
+ return "null";
+ }
+ return o.toString().replace("\n", "\n ");
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ AbstractOpenApiSchema a = (AbstractOpenApiSchema) o;
+ return Objects.equals(this.instance, a.instance) &&
+ Objects.equals(this.isNullable, a.isNullable) &&
+ Objects.equals(this.schemaType, a.schemaType);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(instance, isNullable, schemaType);
+ }
+
+ /**
+ * Is nullable
+ *
+ * @return true if it's nullable
+ */
+ public Boolean isNullable() {
+ if (Boolean.TRUE.equals(isNullable)) {
+ return Boolean.TRUE;
+ } else {
+ return Boolean.FALSE;
+ }
+ }
+
+
+
+}
diff --git a/src/main/java/io/openepi/agriculture/model/ModelsDeforestation.java b/src/main/java/io/openepi/agriculture/model/ModelsDeforestation.java
new file mode 100644
index 0000000..22e9efe
--- /dev/null
+++ b/src/main/java/io/openepi/agriculture/model/ModelsDeforestation.java
@@ -0,0 +1,232 @@
+/*
+ * Agriculture API
+ * This API is used to get aggregated data from Deforestation, Flood, Weather and Soil APIs.
+ *
+ * The version of the OpenAPI document: 1.0.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+
+package io.openepi.agriculture.model;
+
+import java.util.Objects;
+import com.google.gson.TypeAdapter;
+import com.google.gson.annotations.JsonAdapter;
+import com.google.gson.annotations.SerializedName;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.Arrays;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.TypeAdapter;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import io.openepi.agriculture.JSON;
+
+/**
+ * ModelsDeforestation
+ */
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2024-12-02T12:55:09.550932+01:00[Europe/Oslo]", comments = "Generator version: 7.8.0")
+public class ModelsDeforestation {
+ public static final String SERIALIZED_NAME_DATERANGE_TOT_TREELOSS = "daterange_tot_treeloss";
+ @SerializedName(SERIALIZED_NAME_DATERANGE_TOT_TREELOSS)
+ private BigDecimal daterangeTotTreeloss;
+
+ public static final String SERIALIZED_NAME_ERROR = "error";
+ @SerializedName(SERIALIZED_NAME_ERROR)
+ private String error;
+
+ public ModelsDeforestation() {
+ }
+
+ public ModelsDeforestation daterangeTotTreeloss(BigDecimal daterangeTotTreeloss) {
+ this.daterangeTotTreeloss = daterangeTotTreeloss;
+ return this;
+ }
+
+ /**
+ * Get daterangeTotTreeloss
+ * @return daterangeTotTreeloss
+ */
+ @javax.annotation.Nullable
+ public BigDecimal getDaterangeTotTreeloss() {
+ return daterangeTotTreeloss;
+ }
+
+ public void setDaterangeTotTreeloss(BigDecimal daterangeTotTreeloss) {
+ this.daterangeTotTreeloss = daterangeTotTreeloss;
+ }
+
+
+ public ModelsDeforestation error(String error) {
+ this.error = error;
+ return this;
+ }
+
+ /**
+ * Get error
+ * @return error
+ */
+ @javax.annotation.Nullable
+ public String getError() {
+ return error;
+ }
+
+ public void setError(String error) {
+ this.error = error;
+ }
+
+
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ ModelsDeforestation modelsDeforestation = (ModelsDeforestation) o;
+ return Objects.equals(this.daterangeTotTreeloss, modelsDeforestation.daterangeTotTreeloss) &&
+ Objects.equals(this.error, modelsDeforestation.error);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(daterangeTotTreeloss, error);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("class ModelsDeforestation {\n");
+ sb.append(" daterangeTotTreeloss: ").append(toIndentedString(daterangeTotTreeloss)).append("\n");
+ sb.append(" error: ").append(toIndentedString(error)).append("\n");
+ sb.append("}");
+ return sb.toString();
+ }
+
+ /**
+ * Convert the given object to string with each line indented by 4 spaces
+ * (except the first line).
+ */
+ private String toIndentedString(Object o) {
+ if (o == null) {
+ return "null";
+ }
+ return o.toString().replace("\n", "\n ");
+ }
+
+
+ public static HashSet openapiFields;
+ public static HashSet openapiRequiredFields;
+
+ static {
+ // a set of all properties/fields (JSON key names)
+ openapiFields = new HashSet();
+ openapiFields.add("daterange_tot_treeloss");
+ openapiFields.add("error");
+
+ // a set of required properties/fields (JSON key names)
+ openapiRequiredFields = new HashSet();
+ }
+
+ /**
+ * Validates the JSON Element and throws an exception if issues found
+ *
+ * @param jsonElement JSON Element
+ * @throws IOException if the JSON Element is invalid with respect to ModelsDeforestation
+ */
+ public static void validateJsonElement(JsonElement jsonElement) throws IOException {
+ if (jsonElement == null) {
+ if (!ModelsDeforestation.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null
+ throw new IllegalArgumentException(String.format("The required field(s) %s in ModelsDeforestation is not found in the empty JSON string", ModelsDeforestation.openapiRequiredFields.toString()));
+ }
+ }
+
+ Set> entries = jsonElement.getAsJsonObject().entrySet();
+ // check to see if the JSON string contains additional fields
+ for (Map.Entry entry : entries) {
+ if (!ModelsDeforestation.openapiFields.contains(entry.getKey())) {
+ throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `ModelsDeforestation` properties. JSON: %s", entry.getKey(), jsonElement.toString()));
+ }
+ }
+ JsonObject jsonObj = jsonElement.getAsJsonObject();
+ if ((jsonObj.get("error") != null && !jsonObj.get("error").isJsonNull()) && !jsonObj.get("error").isJsonPrimitive()) {
+ throw new IllegalArgumentException(String.format("Expected the field `error` to be a primitive type in the JSON string but got `%s`", jsonObj.get("error").toString()));
+ }
+ }
+
+ public static class CustomTypeAdapterFactory implements TypeAdapterFactory {
+ @SuppressWarnings("unchecked")
+ @Override
+ public TypeAdapter create(Gson gson, TypeToken type) {
+ if (!ModelsDeforestation.class.isAssignableFrom(type.getRawType())) {
+ return null; // this class only serializes 'ModelsDeforestation' and its subtypes
+ }
+ final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class);
+ final TypeAdapter thisAdapter
+ = gson.getDelegateAdapter(this, TypeToken.get(ModelsDeforestation.class));
+
+ return (TypeAdapter) new TypeAdapter() {
+ @Override
+ public void write(JsonWriter out, ModelsDeforestation value) throws IOException {
+ JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject();
+ elementAdapter.write(out, obj);
+ }
+
+ @Override
+ public ModelsDeforestation read(JsonReader in) throws IOException {
+ JsonElement jsonElement = elementAdapter.read(in);
+ validateJsonElement(jsonElement);
+ return thisAdapter.fromJsonTree(jsonElement);
+ }
+
+ }.nullSafe();
+ }
+ }
+
+ /**
+ * Create an instance of ModelsDeforestation given an JSON string
+ *
+ * @param jsonString JSON string
+ * @return An instance of ModelsDeforestation
+ * @throws IOException if the JSON string is invalid with respect to ModelsDeforestation
+ */
+ public static ModelsDeforestation fromJson(String jsonString) throws IOException {
+ return JSON.getGson().fromJson(jsonString, ModelsDeforestation.class);
+ }
+
+ /**
+ * Convert an instance of ModelsDeforestation to an JSON string
+ *
+ * @return JSON string
+ */
+ public String toJson() {
+ return JSON.getGson().toJson(this);
+ }
+}
+
diff --git a/src/main/java/io/openepi/agriculture/model/ModelsFlood.java b/src/main/java/io/openepi/agriculture/model/ModelsFlood.java
new file mode 100644
index 0000000..fb6e852
--- /dev/null
+++ b/src/main/java/io/openepi/agriculture/model/ModelsFlood.java
@@ -0,0 +1,351 @@
+/*
+ * Agriculture API
+ * This API is used to get aggregated data from Deforestation, Flood, Weather and Soil APIs.
+ *
+ * The version of the OpenAPI document: 1.0.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+
+package io.openepi.agriculture.model;
+
+import java.util.Objects;
+import com.google.gson.TypeAdapter;
+import com.google.gson.annotations.JsonAdapter;
+import com.google.gson.annotations.SerializedName;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
+import java.util.Arrays;
+import io.openepi.agriculture.model.ModelsIntensityEnum;
+import io.openepi.agriculture.model.ModelsPeakTimingEnum;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.TypeAdapter;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import io.openepi.agriculture.JSON;
+
+/**
+ * ModelsFlood
+ */
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2024-12-02T12:55:09.550932+01:00[Europe/Oslo]", comments = "Generator version: 7.8.0")
+public class ModelsFlood {
+ public static final String SERIALIZED_NAME_ERROR = "error";
+ @SerializedName(SERIALIZED_NAME_ERROR)
+ private String error;
+
+ public static final String SERIALIZED_NAME_INTENSITY = "intensity";
+ @SerializedName(SERIALIZED_NAME_INTENSITY)
+ private ModelsIntensityEnum intensity;
+
+ public static final String SERIALIZED_NAME_ISSUED_ON = "issued_on";
+ @SerializedName(SERIALIZED_NAME_ISSUED_ON)
+ private String issuedOn;
+
+ public static final String SERIALIZED_NAME_PEAK_DAY = "peak_day";
+ @SerializedName(SERIALIZED_NAME_PEAK_DAY)
+ private String peakDay;
+
+ public static final String SERIALIZED_NAME_PEAK_STEP = "peak_step";
+ @SerializedName(SERIALIZED_NAME_PEAK_STEP)
+ private Integer peakStep;
+
+ public static final String SERIALIZED_NAME_PEAK_TIMING = "peak_timing";
+ @SerializedName(SERIALIZED_NAME_PEAK_TIMING)
+ private ModelsPeakTimingEnum peakTiming;
+
+ public ModelsFlood() {
+ }
+
+ public ModelsFlood error(String error) {
+ this.error = error;
+ return this;
+ }
+
+ /**
+ * Get error
+ * @return error
+ */
+ @javax.annotation.Nullable
+ public String getError() {
+ return error;
+ }
+
+ public void setError(String error) {
+ this.error = error;
+ }
+
+
+ public ModelsFlood intensity(ModelsIntensityEnum intensity) {
+ this.intensity = intensity;
+ return this;
+ }
+
+ /**
+ * Get intensity
+ * @return intensity
+ */
+ @javax.annotation.Nullable
+ public ModelsIntensityEnum getIntensity() {
+ return intensity;
+ }
+
+ public void setIntensity(ModelsIntensityEnum intensity) {
+ this.intensity = intensity;
+ }
+
+
+ public ModelsFlood issuedOn(String issuedOn) {
+ this.issuedOn = issuedOn;
+ return this;
+ }
+
+ /**
+ * Get issuedOn
+ * @return issuedOn
+ */
+ @javax.annotation.Nullable
+ public String getIssuedOn() {
+ return issuedOn;
+ }
+
+ public void setIssuedOn(String issuedOn) {
+ this.issuedOn = issuedOn;
+ }
+
+
+ public ModelsFlood peakDay(String peakDay) {
+ this.peakDay = peakDay;
+ return this;
+ }
+
+ /**
+ * Get peakDay
+ * @return peakDay
+ */
+ @javax.annotation.Nullable
+ public String getPeakDay() {
+ return peakDay;
+ }
+
+ public void setPeakDay(String peakDay) {
+ this.peakDay = peakDay;
+ }
+
+
+ public ModelsFlood peakStep(Integer peakStep) {
+ this.peakStep = peakStep;
+ return this;
+ }
+
+ /**
+ * Get peakStep
+ * @return peakStep
+ */
+ @javax.annotation.Nullable
+ public Integer getPeakStep() {
+ return peakStep;
+ }
+
+ public void setPeakStep(Integer peakStep) {
+ this.peakStep = peakStep;
+ }
+
+
+ public ModelsFlood peakTiming(ModelsPeakTimingEnum peakTiming) {
+ this.peakTiming = peakTiming;
+ return this;
+ }
+
+ /**
+ * Get peakTiming
+ * @return peakTiming
+ */
+ @javax.annotation.Nullable
+ public ModelsPeakTimingEnum getPeakTiming() {
+ return peakTiming;
+ }
+
+ public void setPeakTiming(ModelsPeakTimingEnum peakTiming) {
+ this.peakTiming = peakTiming;
+ }
+
+
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ ModelsFlood modelsFlood = (ModelsFlood) o;
+ return Objects.equals(this.error, modelsFlood.error) &&
+ Objects.equals(this.intensity, modelsFlood.intensity) &&
+ Objects.equals(this.issuedOn, modelsFlood.issuedOn) &&
+ Objects.equals(this.peakDay, modelsFlood.peakDay) &&
+ Objects.equals(this.peakStep, modelsFlood.peakStep) &&
+ Objects.equals(this.peakTiming, modelsFlood.peakTiming);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(error, intensity, issuedOn, peakDay, peakStep, peakTiming);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("class ModelsFlood {\n");
+ sb.append(" error: ").append(toIndentedString(error)).append("\n");
+ sb.append(" intensity: ").append(toIndentedString(intensity)).append("\n");
+ sb.append(" issuedOn: ").append(toIndentedString(issuedOn)).append("\n");
+ sb.append(" peakDay: ").append(toIndentedString(peakDay)).append("\n");
+ sb.append(" peakStep: ").append(toIndentedString(peakStep)).append("\n");
+ sb.append(" peakTiming: ").append(toIndentedString(peakTiming)).append("\n");
+ sb.append("}");
+ return sb.toString();
+ }
+
+ /**
+ * Convert the given object to string with each line indented by 4 spaces
+ * (except the first line).
+ */
+ private String toIndentedString(Object o) {
+ if (o == null) {
+ return "null";
+ }
+ return o.toString().replace("\n", "\n ");
+ }
+
+
+ public static HashSet openapiFields;
+ public static HashSet openapiRequiredFields;
+
+ static {
+ // a set of all properties/fields (JSON key names)
+ openapiFields = new HashSet();
+ openapiFields.add("error");
+ openapiFields.add("intensity");
+ openapiFields.add("issued_on");
+ openapiFields.add("peak_day");
+ openapiFields.add("peak_step");
+ openapiFields.add("peak_timing");
+
+ // a set of required properties/fields (JSON key names)
+ openapiRequiredFields = new HashSet();
+ }
+
+ /**
+ * Validates the JSON Element and throws an exception if issues found
+ *
+ * @param jsonElement JSON Element
+ * @throws IOException if the JSON Element is invalid with respect to ModelsFlood
+ */
+ public static void validateJsonElement(JsonElement jsonElement) throws IOException {
+ if (jsonElement == null) {
+ if (!ModelsFlood.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null
+ throw new IllegalArgumentException(String.format("The required field(s) %s in ModelsFlood is not found in the empty JSON string", ModelsFlood.openapiRequiredFields.toString()));
+ }
+ }
+
+ Set> entries = jsonElement.getAsJsonObject().entrySet();
+ // check to see if the JSON string contains additional fields
+ for (Map.Entry entry : entries) {
+ if (!ModelsFlood.openapiFields.contains(entry.getKey())) {
+ throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `ModelsFlood` properties. JSON: %s", entry.getKey(), jsonElement.toString()));
+ }
+ }
+ JsonObject jsonObj = jsonElement.getAsJsonObject();
+ if ((jsonObj.get("error") != null && !jsonObj.get("error").isJsonNull()) && !jsonObj.get("error").isJsonPrimitive()) {
+ throw new IllegalArgumentException(String.format("Expected the field `error` to be a primitive type in the JSON string but got `%s`", jsonObj.get("error").toString()));
+ }
+ // validate the optional field `intensity`
+ if (jsonObj.get("intensity") != null && !jsonObj.get("intensity").isJsonNull()) {
+ ModelsIntensityEnum.validateJsonElement(jsonObj.get("intensity"));
+ }
+ if ((jsonObj.get("issued_on") != null && !jsonObj.get("issued_on").isJsonNull()) && !jsonObj.get("issued_on").isJsonPrimitive()) {
+ throw new IllegalArgumentException(String.format("Expected the field `issued_on` to be a primitive type in the JSON string but got `%s`", jsonObj.get("issued_on").toString()));
+ }
+ if ((jsonObj.get("peak_day") != null && !jsonObj.get("peak_day").isJsonNull()) && !jsonObj.get("peak_day").isJsonPrimitive()) {
+ throw new IllegalArgumentException(String.format("Expected the field `peak_day` to be a primitive type in the JSON string but got `%s`", jsonObj.get("peak_day").toString()));
+ }
+ // validate the optional field `peak_timing`
+ if (jsonObj.get("peak_timing") != null && !jsonObj.get("peak_timing").isJsonNull()) {
+ ModelsPeakTimingEnum.validateJsonElement(jsonObj.get("peak_timing"));
+ }
+ }
+
+ public static class CustomTypeAdapterFactory implements TypeAdapterFactory {
+ @SuppressWarnings("unchecked")
+ @Override
+ public TypeAdapter create(Gson gson, TypeToken type) {
+ if (!ModelsFlood.class.isAssignableFrom(type.getRawType())) {
+ return null; // this class only serializes 'ModelsFlood' and its subtypes
+ }
+ final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class);
+ final TypeAdapter thisAdapter
+ = gson.getDelegateAdapter(this, TypeToken.get(ModelsFlood.class));
+
+ return (TypeAdapter) new TypeAdapter() {
+ @Override
+ public void write(JsonWriter out, ModelsFlood value) throws IOException {
+ JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject();
+ elementAdapter.write(out, obj);
+ }
+
+ @Override
+ public ModelsFlood read(JsonReader in) throws IOException {
+ JsonElement jsonElement = elementAdapter.read(in);
+ validateJsonElement(jsonElement);
+ return thisAdapter.fromJsonTree(jsonElement);
+ }
+
+ }.nullSafe();
+ }
+ }
+
+ /**
+ * Create an instance of ModelsFlood given an JSON string
+ *
+ * @param jsonString JSON string
+ * @return An instance of ModelsFlood
+ * @throws IOException if the JSON string is invalid with respect to ModelsFlood
+ */
+ public static ModelsFlood fromJson(String jsonString) throws IOException {
+ return JSON.getGson().fromJson(jsonString, ModelsFlood.class);
+ }
+
+ /**
+ * Convert an instance of ModelsFlood to an JSON string
+ *
+ * @return JSON string
+ */
+ public String toJson() {
+ return JSON.getGson().toJson(this);
+ }
+}
+
diff --git a/src/main/java/io/openepi/agriculture/model/ModelsIntensityEnum.java b/src/main/java/io/openepi/agriculture/model/ModelsIntensityEnum.java
new file mode 100644
index 0000000..4c702ea
--- /dev/null
+++ b/src/main/java/io/openepi/agriculture/model/ModelsIntensityEnum.java
@@ -0,0 +1,82 @@
+/*
+ * Agriculture API
+ * This API is used to get aggregated data from Deforestation, Flood, Weather and Soil APIs.
+ *
+ * The version of the OpenAPI document: 1.0.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+
+package io.openepi.agriculture.model;
+
+import java.util.Objects;
+import com.google.gson.annotations.SerializedName;
+
+import java.io.IOException;
+import com.google.gson.TypeAdapter;
+import com.google.gson.JsonElement;
+import com.google.gson.annotations.JsonAdapter;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+
+/**
+ * Gets or Sets models.IntensityEnum
+ */
+@JsonAdapter(ModelsIntensityEnum.Adapter.class)
+public enum ModelsIntensityEnum {
+
+ P("P"),
+
+ R("R"),
+
+ Y("Y"),
+
+ G("G");
+
+ private String value;
+
+ ModelsIntensityEnum(String value) {
+ this.value = value;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(value);
+ }
+
+ public static ModelsIntensityEnum fromValue(String value) {
+ for (ModelsIntensityEnum b : ModelsIntensityEnum.values()) {
+ if (b.value.equals(value)) {
+ return b;
+ }
+ }
+ throw new IllegalArgumentException("Unexpected value '" + value + "'");
+ }
+
+ public static class Adapter extends TypeAdapter {
+ @Override
+ public void write(final JsonWriter jsonWriter, final ModelsIntensityEnum enumeration) throws IOException {
+ jsonWriter.value(enumeration.getValue());
+ }
+
+ @Override
+ public ModelsIntensityEnum read(final JsonReader jsonReader) throws IOException {
+ String value = jsonReader.nextString();
+ return ModelsIntensityEnum.fromValue(value);
+ }
+ }
+
+ public static void validateJsonElement(JsonElement jsonElement) throws IOException {
+ String value = jsonElement.getAsString();
+ ModelsIntensityEnum.fromValue(value);
+ }
+}
+
diff --git a/src/main/java/io/openepi/agriculture/model/ModelsPeakTimingEnum.java b/src/main/java/io/openepi/agriculture/model/ModelsPeakTimingEnum.java
new file mode 100644
index 0000000..cd5cf5a
--- /dev/null
+++ b/src/main/java/io/openepi/agriculture/model/ModelsPeakTimingEnum.java
@@ -0,0 +1,80 @@
+/*
+ * Agriculture API
+ * This API is used to get aggregated data from Deforestation, Flood, Weather and Soil APIs.
+ *
+ * The version of the OpenAPI document: 1.0.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+
+package io.openepi.agriculture.model;
+
+import java.util.Objects;
+import com.google.gson.annotations.SerializedName;
+
+import java.io.IOException;
+import com.google.gson.TypeAdapter;
+import com.google.gson.JsonElement;
+import com.google.gson.annotations.JsonAdapter;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+
+/**
+ * Gets or Sets models.PeakTimingEnum
+ */
+@JsonAdapter(ModelsPeakTimingEnum.Adapter.class)
+public enum ModelsPeakTimingEnum {
+
+ BB("BB"),
+
+ GC("GC"),
+
+ GB("GB");
+
+ private String value;
+
+ ModelsPeakTimingEnum(String value) {
+ this.value = value;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(value);
+ }
+
+ public static ModelsPeakTimingEnum fromValue(String value) {
+ for (ModelsPeakTimingEnum b : ModelsPeakTimingEnum.values()) {
+ if (b.value.equals(value)) {
+ return b;
+ }
+ }
+ throw new IllegalArgumentException("Unexpected value '" + value + "'");
+ }
+
+ public static class Adapter extends TypeAdapter {
+ @Override
+ public void write(final JsonWriter jsonWriter, final ModelsPeakTimingEnum enumeration) throws IOException {
+ jsonWriter.value(enumeration.getValue());
+ }
+
+ @Override
+ public ModelsPeakTimingEnum read(final JsonReader jsonReader) throws IOException {
+ String value = jsonReader.nextString();
+ return ModelsPeakTimingEnum.fromValue(value);
+ }
+ }
+
+ public static void validateJsonElement(JsonElement jsonElement) throws IOException {
+ String value = jsonElement.getAsString();
+ ModelsPeakTimingEnum.fromValue(value);
+ }
+}
+
diff --git a/src/main/java/io/openepi/agriculture/model/ModelsSoilType.java b/src/main/java/io/openepi/agriculture/model/ModelsSoilType.java
new file mode 100644
index 0000000..d761830
--- /dev/null
+++ b/src/main/java/io/openepi/agriculture/model/ModelsSoilType.java
@@ -0,0 +1,234 @@
+/*
+ * Agriculture API
+ * This API is used to get aggregated data from Deforestation, Flood, Weather and Soil APIs.
+ *
+ * The version of the OpenAPI document: 1.0.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+
+package io.openepi.agriculture.model;
+
+import java.util.Objects;
+import com.google.gson.TypeAdapter;
+import com.google.gson.annotations.JsonAdapter;
+import com.google.gson.annotations.SerializedName;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
+import java.util.Arrays;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.TypeAdapter;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import io.openepi.agriculture.JSON;
+
+/**
+ * ModelsSoilType
+ */
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2024-12-02T12:55:09.550932+01:00[Europe/Oslo]", comments = "Generator version: 7.8.0")
+public class ModelsSoilType {
+ public static final String SERIALIZED_NAME_ERROR = "error";
+ @SerializedName(SERIALIZED_NAME_ERROR)
+ private String error;
+
+ public static final String SERIALIZED_NAME_MOST_PROBABLE_SOIL_TYPE = "most_probable_soil_type";
+ @SerializedName(SERIALIZED_NAME_MOST_PROBABLE_SOIL_TYPE)
+ private String mostProbableSoilType;
+
+ public ModelsSoilType() {
+ }
+
+ public ModelsSoilType error(String error) {
+ this.error = error;
+ return this;
+ }
+
+ /**
+ * Get error
+ * @return error
+ */
+ @javax.annotation.Nullable
+ public String getError() {
+ return error;
+ }
+
+ public void setError(String error) {
+ this.error = error;
+ }
+
+
+ public ModelsSoilType mostProbableSoilType(String mostProbableSoilType) {
+ this.mostProbableSoilType = mostProbableSoilType;
+ return this;
+ }
+
+ /**
+ * The most probable soil type at the queried location
+ * @return mostProbableSoilType
+ */
+ @javax.annotation.Nullable
+ public String getMostProbableSoilType() {
+ return mostProbableSoilType;
+ }
+
+ public void setMostProbableSoilType(String mostProbableSoilType) {
+ this.mostProbableSoilType = mostProbableSoilType;
+ }
+
+
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ ModelsSoilType modelsSoilType = (ModelsSoilType) o;
+ return Objects.equals(this.error, modelsSoilType.error) &&
+ Objects.equals(this.mostProbableSoilType, modelsSoilType.mostProbableSoilType);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(error, mostProbableSoilType);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("class ModelsSoilType {\n");
+ sb.append(" error: ").append(toIndentedString(error)).append("\n");
+ sb.append(" mostProbableSoilType: ").append(toIndentedString(mostProbableSoilType)).append("\n");
+ sb.append("}");
+ return sb.toString();
+ }
+
+ /**
+ * Convert the given object to string with each line indented by 4 spaces
+ * (except the first line).
+ */
+ private String toIndentedString(Object o) {
+ if (o == null) {
+ return "null";
+ }
+ return o.toString().replace("\n", "\n ");
+ }
+
+
+ public static HashSet openapiFields;
+ public static HashSet openapiRequiredFields;
+
+ static {
+ // a set of all properties/fields (JSON key names)
+ openapiFields = new HashSet();
+ openapiFields.add("error");
+ openapiFields.add("most_probable_soil_type");
+
+ // a set of required properties/fields (JSON key names)
+ openapiRequiredFields = new HashSet();
+ }
+
+ /**
+ * Validates the JSON Element and throws an exception if issues found
+ *
+ * @param jsonElement JSON Element
+ * @throws IOException if the JSON Element is invalid with respect to ModelsSoilType
+ */
+ public static void validateJsonElement(JsonElement jsonElement) throws IOException {
+ if (jsonElement == null) {
+ if (!ModelsSoilType.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null
+ throw new IllegalArgumentException(String.format("The required field(s) %s in ModelsSoilType is not found in the empty JSON string", ModelsSoilType.openapiRequiredFields.toString()));
+ }
+ }
+
+ Set> entries = jsonElement.getAsJsonObject().entrySet();
+ // check to see if the JSON string contains additional fields
+ for (Map.Entry entry : entries) {
+ if (!ModelsSoilType.openapiFields.contains(entry.getKey())) {
+ throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `ModelsSoilType` properties. JSON: %s", entry.getKey(), jsonElement.toString()));
+ }
+ }
+ JsonObject jsonObj = jsonElement.getAsJsonObject();
+ if ((jsonObj.get("error") != null && !jsonObj.get("error").isJsonNull()) && !jsonObj.get("error").isJsonPrimitive()) {
+ throw new IllegalArgumentException(String.format("Expected the field `error` to be a primitive type in the JSON string but got `%s`", jsonObj.get("error").toString()));
+ }
+ if ((jsonObj.get("most_probable_soil_type") != null && !jsonObj.get("most_probable_soil_type").isJsonNull()) && !jsonObj.get("most_probable_soil_type").isJsonPrimitive()) {
+ throw new IllegalArgumentException(String.format("Expected the field `most_probable_soil_type` to be a primitive type in the JSON string but got `%s`", jsonObj.get("most_probable_soil_type").toString()));
+ }
+ }
+
+ public static class CustomTypeAdapterFactory implements TypeAdapterFactory {
+ @SuppressWarnings("unchecked")
+ @Override
+ public TypeAdapter create(Gson gson, TypeToken type) {
+ if (!ModelsSoilType.class.isAssignableFrom(type.getRawType())) {
+ return null; // this class only serializes 'ModelsSoilType' and its subtypes
+ }
+ final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class);
+ final TypeAdapter thisAdapter
+ = gson.getDelegateAdapter(this, TypeToken.get(ModelsSoilType.class));
+
+ return (TypeAdapter) new TypeAdapter() {
+ @Override
+ public void write(JsonWriter out, ModelsSoilType value) throws IOException {
+ JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject();
+ elementAdapter.write(out, obj);
+ }
+
+ @Override
+ public ModelsSoilType read(JsonReader in) throws IOException {
+ JsonElement jsonElement = elementAdapter.read(in);
+ validateJsonElement(jsonElement);
+ return thisAdapter.fromJsonTree(jsonElement);
+ }
+
+ }.nullSafe();
+ }
+ }
+
+ /**
+ * Create an instance of ModelsSoilType given an JSON string
+ *
+ * @param jsonString JSON string
+ * @return An instance of ModelsSoilType
+ * @throws IOException if the JSON string is invalid with respect to ModelsSoilType
+ */
+ public static ModelsSoilType fromJson(String jsonString) throws IOException {
+ return JSON.getGson().fromJson(jsonString, ModelsSoilType.class);
+ }
+
+ /**
+ * Convert an instance of ModelsSoilType to an JSON string
+ *
+ * @return JSON string
+ */
+ public String toJson() {
+ return JSON.getGson().toJson(this);
+ }
+}
+
diff --git a/src/main/java/io/openepi/agriculture/model/ModelsSummary.java b/src/main/java/io/openepi/agriculture/model/ModelsSummary.java
new file mode 100644
index 0000000..ff2ae57
--- /dev/null
+++ b/src/main/java/io/openepi/agriculture/model/ModelsSummary.java
@@ -0,0 +1,300 @@
+/*
+ * Agriculture API
+ * This API is used to get aggregated data from Deforestation, Flood, Weather and Soil APIs.
+ *
+ * The version of the OpenAPI document: 1.0.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+
+package io.openepi.agriculture.model;
+
+import java.util.Objects;
+import com.google.gson.TypeAdapter;
+import com.google.gson.annotations.JsonAdapter;
+import com.google.gson.annotations.SerializedName;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
+import java.util.Arrays;
+import io.openepi.agriculture.model.ModelsDeforestation;
+import io.openepi.agriculture.model.ModelsFlood;
+import io.openepi.agriculture.model.ModelsSoilType;
+import io.openepi.agriculture.model.ModelsWeather;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.TypeAdapter;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import io.openepi.agriculture.JSON;
+
+/**
+ * ModelsSummary
+ */
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2024-12-02T12:55:09.550932+01:00[Europe/Oslo]", comments = "Generator version: 7.8.0")
+public class ModelsSummary {
+ public static final String SERIALIZED_NAME_DEFORESTATION = "deforestation";
+ @SerializedName(SERIALIZED_NAME_DEFORESTATION)
+ private ModelsDeforestation deforestation;
+
+ public static final String SERIALIZED_NAME_FLOOD = "flood";
+ @SerializedName(SERIALIZED_NAME_FLOOD)
+ private ModelsFlood flood;
+
+ public static final String SERIALIZED_NAME_SOIL = "soil";
+ @SerializedName(SERIALIZED_NAME_SOIL)
+ private ModelsSoilType soil;
+
+ public static final String SERIALIZED_NAME_WEATHER = "weather";
+ @SerializedName(SERIALIZED_NAME_WEATHER)
+ private ModelsWeather weather;
+
+ public ModelsSummary() {
+ }
+
+ public ModelsSummary deforestation(ModelsDeforestation deforestation) {
+ this.deforestation = deforestation;
+ return this;
+ }
+
+ /**
+ * deforestation from 2001 to 2022 in the given coordinates.
+ * @return deforestation
+ */
+ @javax.annotation.Nullable
+ public ModelsDeforestation getDeforestation() {
+ return deforestation;
+ }
+
+ public void setDeforestation(ModelsDeforestation deforestation) {
+ this.deforestation = deforestation;
+ }
+
+
+ public ModelsSummary flood(ModelsFlood flood) {
+ this.flood = flood;
+ return this;
+ }
+
+ /**
+ * Flood forecast in the given coordinates.
+ * @return flood
+ */
+ @javax.annotation.Nullable
+ public ModelsFlood getFlood() {
+ return flood;
+ }
+
+ public void setFlood(ModelsFlood flood) {
+ this.flood = flood;
+ }
+
+
+ public ModelsSummary soil(ModelsSoilType soil) {
+ this.soil = soil;
+ return this;
+ }
+
+ /**
+ * The most probable soil type in the given coordinates.
+ * @return soil
+ */
+ @javax.annotation.Nullable
+ public ModelsSoilType getSoil() {
+ return soil;
+ }
+
+ public void setSoil(ModelsSoilType soil) {
+ this.soil = soil;
+ }
+
+
+ public ModelsSummary weather(ModelsWeather weather) {
+ this.weather = weather;
+ return this;
+ }
+
+ /**
+ * Current weather and rain forecast in the given coordinates.
+ * @return weather
+ */
+ @javax.annotation.Nullable
+ public ModelsWeather getWeather() {
+ return weather;
+ }
+
+ public void setWeather(ModelsWeather weather) {
+ this.weather = weather;
+ }
+
+
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ ModelsSummary modelsSummary = (ModelsSummary) o;
+ return Objects.equals(this.deforestation, modelsSummary.deforestation) &&
+ Objects.equals(this.flood, modelsSummary.flood) &&
+ Objects.equals(this.soil, modelsSummary.soil) &&
+ Objects.equals(this.weather, modelsSummary.weather);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(deforestation, flood, soil, weather);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("class ModelsSummary {\n");
+ sb.append(" deforestation: ").append(toIndentedString(deforestation)).append("\n");
+ sb.append(" flood: ").append(toIndentedString(flood)).append("\n");
+ sb.append(" soil: ").append(toIndentedString(soil)).append("\n");
+ sb.append(" weather: ").append(toIndentedString(weather)).append("\n");
+ sb.append("}");
+ return sb.toString();
+ }
+
+ /**
+ * Convert the given object to string with each line indented by 4 spaces
+ * (except the first line).
+ */
+ private String toIndentedString(Object o) {
+ if (o == null) {
+ return "null";
+ }
+ return o.toString().replace("\n", "\n ");
+ }
+
+
+ public static HashSet openapiFields;
+ public static HashSet openapiRequiredFields;
+
+ static {
+ // a set of all properties/fields (JSON key names)
+ openapiFields = new HashSet();
+ openapiFields.add("deforestation");
+ openapiFields.add("flood");
+ openapiFields.add("soil");
+ openapiFields.add("weather");
+
+ // a set of required properties/fields (JSON key names)
+ openapiRequiredFields = new HashSet();
+ }
+
+ /**
+ * Validates the JSON Element and throws an exception if issues found
+ *
+ * @param jsonElement JSON Element
+ * @throws IOException if the JSON Element is invalid with respect to ModelsSummary
+ */
+ public static void validateJsonElement(JsonElement jsonElement) throws IOException {
+ if (jsonElement == null) {
+ if (!ModelsSummary.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null
+ throw new IllegalArgumentException(String.format("The required field(s) %s in ModelsSummary is not found in the empty JSON string", ModelsSummary.openapiRequiredFields.toString()));
+ }
+ }
+
+ Set> entries = jsonElement.getAsJsonObject().entrySet();
+ // check to see if the JSON string contains additional fields
+ for (Map.Entry entry : entries) {
+ if (!ModelsSummary.openapiFields.contains(entry.getKey())) {
+ throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `ModelsSummary` properties. JSON: %s", entry.getKey(), jsonElement.toString()));
+ }
+ }
+ JsonObject jsonObj = jsonElement.getAsJsonObject();
+ // validate the optional field `deforestation`
+ if (jsonObj.get("deforestation") != null && !jsonObj.get("deforestation").isJsonNull()) {
+ ModelsDeforestation.validateJsonElement(jsonObj.get("deforestation"));
+ }
+ // validate the optional field `flood`
+ if (jsonObj.get("flood") != null && !jsonObj.get("flood").isJsonNull()) {
+ ModelsFlood.validateJsonElement(jsonObj.get("flood"));
+ }
+ // validate the optional field `soil`
+ if (jsonObj.get("soil") != null && !jsonObj.get("soil").isJsonNull()) {
+ ModelsSoilType.validateJsonElement(jsonObj.get("soil"));
+ }
+ // validate the optional field `weather`
+ if (jsonObj.get("weather") != null && !jsonObj.get("weather").isJsonNull()) {
+ ModelsWeather.validateJsonElement(jsonObj.get("weather"));
+ }
+ }
+
+ public static class CustomTypeAdapterFactory implements TypeAdapterFactory {
+ @SuppressWarnings("unchecked")
+ @Override
+ public TypeAdapter create(Gson gson, TypeToken type) {
+ if (!ModelsSummary.class.isAssignableFrom(type.getRawType())) {
+ return null; // this class only serializes 'ModelsSummary' and its subtypes
+ }
+ final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class);
+ final TypeAdapter thisAdapter
+ = gson.getDelegateAdapter(this, TypeToken.get(ModelsSummary.class));
+
+ return (TypeAdapter) new TypeAdapter() {
+ @Override
+ public void write(JsonWriter out, ModelsSummary value) throws IOException {
+ JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject();
+ elementAdapter.write(out, obj);
+ }
+
+ @Override
+ public ModelsSummary read(JsonReader in) throws IOException {
+ JsonElement jsonElement = elementAdapter.read(in);
+ validateJsonElement(jsonElement);
+ return thisAdapter.fromJsonTree(jsonElement);
+ }
+
+ }.nullSafe();
+ }
+ }
+
+ /**
+ * Create an instance of ModelsSummary given an JSON string
+ *
+ * @param jsonString JSON string
+ * @return An instance of ModelsSummary
+ * @throws IOException if the JSON string is invalid with respect to ModelsSummary
+ */
+ public static ModelsSummary fromJson(String jsonString) throws IOException {
+ return JSON.getGson().fromJson(jsonString, ModelsSummary.class);
+ }
+
+ /**
+ * Convert an instance of ModelsSummary to an JSON string
+ *
+ * @return JSON string
+ */
+ public String toJson() {
+ return JSON.getGson().toJson(this);
+ }
+}
+
diff --git a/src/main/java/io/openepi/agriculture/model/ModelsWeather.java b/src/main/java/io/openepi/agriculture/model/ModelsWeather.java
new file mode 100644
index 0000000..024e0b9
--- /dev/null
+++ b/src/main/java/io/openepi/agriculture/model/ModelsWeather.java
@@ -0,0 +1,388 @@
+/*
+ * Agriculture API
+ * This API is used to get aggregated data from Deforestation, Flood, Weather and Soil APIs.
+ *
+ * The version of the OpenAPI document: 1.0.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+
+package io.openepi.agriculture.model;
+
+import java.util.Objects;
+import com.google.gson.TypeAdapter;
+import com.google.gson.annotations.JsonAdapter;
+import com.google.gson.annotations.SerializedName;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.Arrays;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.TypeAdapter;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import io.openepi.agriculture.JSON;
+
+/**
+ * ModelsWeather
+ */
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2024-12-02T12:55:09.550932+01:00[Europe/Oslo]", comments = "Generator version: 7.8.0")
+public class ModelsWeather {
+ public static final String SERIALIZED_NAME_AIR_TEMPERATURE = "air_temperature";
+ @SerializedName(SERIALIZED_NAME_AIR_TEMPERATURE)
+ private BigDecimal airTemperature;
+
+ public static final String SERIALIZED_NAME_CLOUD_AREA_FRACTION = "cloud_area_fraction";
+ @SerializedName(SERIALIZED_NAME_CLOUD_AREA_FRACTION)
+ private BigDecimal cloudAreaFraction;
+
+ public static final String SERIALIZED_NAME_ERROR = "error";
+ @SerializedName(SERIALIZED_NAME_ERROR)
+ private String error;
+
+ public static final String SERIALIZED_NAME_PRECIPITATION_AMOUNT = "precipitation_amount";
+ @SerializedName(SERIALIZED_NAME_PRECIPITATION_AMOUNT)
+ private BigDecimal precipitationAmount;
+
+ public static final String SERIALIZED_NAME_RELATIVE_HUMIDITY = "relative_humidity";
+ @SerializedName(SERIALIZED_NAME_RELATIVE_HUMIDITY)
+ private BigDecimal relativeHumidity;
+
+ public static final String SERIALIZED_NAME_WIND_FROM_DIRECTION = "wind_from_direction";
+ @SerializedName(SERIALIZED_NAME_WIND_FROM_DIRECTION)
+ private BigDecimal windFromDirection;
+
+ public static final String SERIALIZED_NAME_WIND_SPEED = "wind_speed";
+ @SerializedName(SERIALIZED_NAME_WIND_SPEED)
+ private BigDecimal windSpeed;
+
+ public static final String SERIALIZED_NAME_WIND_SPEED_OF_GUST = "wind_speed_of_gust";
+ @SerializedName(SERIALIZED_NAME_WIND_SPEED_OF_GUST)
+ private BigDecimal windSpeedOfGust;
+
+ public ModelsWeather() {
+ }
+
+ public ModelsWeather airTemperature(BigDecimal airTemperature) {
+ this.airTemperature = airTemperature;
+ return this;
+ }
+
+ /**
+ * Get airTemperature
+ * @return airTemperature
+ */
+ @javax.annotation.Nullable
+ public BigDecimal getAirTemperature() {
+ return airTemperature;
+ }
+
+ public void setAirTemperature(BigDecimal airTemperature) {
+ this.airTemperature = airTemperature;
+ }
+
+
+ public ModelsWeather cloudAreaFraction(BigDecimal cloudAreaFraction) {
+ this.cloudAreaFraction = cloudAreaFraction;
+ return this;
+ }
+
+ /**
+ * Get cloudAreaFraction
+ * @return cloudAreaFraction
+ */
+ @javax.annotation.Nullable
+ public BigDecimal getCloudAreaFraction() {
+ return cloudAreaFraction;
+ }
+
+ public void setCloudAreaFraction(BigDecimal cloudAreaFraction) {
+ this.cloudAreaFraction = cloudAreaFraction;
+ }
+
+
+ public ModelsWeather error(String error) {
+ this.error = error;
+ return this;
+ }
+
+ /**
+ * Get error
+ * @return error
+ */
+ @javax.annotation.Nullable
+ public String getError() {
+ return error;
+ }
+
+ public void setError(String error) {
+ this.error = error;
+ }
+
+
+ public ModelsWeather precipitationAmount(BigDecimal precipitationAmount) {
+ this.precipitationAmount = precipitationAmount;
+ return this;
+ }
+
+ /**
+ * Get precipitationAmount
+ * @return precipitationAmount
+ */
+ @javax.annotation.Nullable
+ public BigDecimal getPrecipitationAmount() {
+ return precipitationAmount;
+ }
+
+ public void setPrecipitationAmount(BigDecimal precipitationAmount) {
+ this.precipitationAmount = precipitationAmount;
+ }
+
+
+ public ModelsWeather relativeHumidity(BigDecimal relativeHumidity) {
+ this.relativeHumidity = relativeHumidity;
+ return this;
+ }
+
+ /**
+ * Get relativeHumidity
+ * @return relativeHumidity
+ */
+ @javax.annotation.Nullable
+ public BigDecimal getRelativeHumidity() {
+ return relativeHumidity;
+ }
+
+ public void setRelativeHumidity(BigDecimal relativeHumidity) {
+ this.relativeHumidity = relativeHumidity;
+ }
+
+
+ public ModelsWeather windFromDirection(BigDecimal windFromDirection) {
+ this.windFromDirection = windFromDirection;
+ return this;
+ }
+
+ /**
+ * Get windFromDirection
+ * @return windFromDirection
+ */
+ @javax.annotation.Nullable
+ public BigDecimal getWindFromDirection() {
+ return windFromDirection;
+ }
+
+ public void setWindFromDirection(BigDecimal windFromDirection) {
+ this.windFromDirection = windFromDirection;
+ }
+
+
+ public ModelsWeather windSpeed(BigDecimal windSpeed) {
+ this.windSpeed = windSpeed;
+ return this;
+ }
+
+ /**
+ * Get windSpeed
+ * @return windSpeed
+ */
+ @javax.annotation.Nullable
+ public BigDecimal getWindSpeed() {
+ return windSpeed;
+ }
+
+ public void setWindSpeed(BigDecimal windSpeed) {
+ this.windSpeed = windSpeed;
+ }
+
+
+ public ModelsWeather windSpeedOfGust(BigDecimal windSpeedOfGust) {
+ this.windSpeedOfGust = windSpeedOfGust;
+ return this;
+ }
+
+ /**
+ * Get windSpeedOfGust
+ * @return windSpeedOfGust
+ */
+ @javax.annotation.Nullable
+ public BigDecimal getWindSpeedOfGust() {
+ return windSpeedOfGust;
+ }
+
+ public void setWindSpeedOfGust(BigDecimal windSpeedOfGust) {
+ this.windSpeedOfGust = windSpeedOfGust;
+ }
+
+
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ ModelsWeather modelsWeather = (ModelsWeather) o;
+ return Objects.equals(this.airTemperature, modelsWeather.airTemperature) &&
+ Objects.equals(this.cloudAreaFraction, modelsWeather.cloudAreaFraction) &&
+ Objects.equals(this.error, modelsWeather.error) &&
+ Objects.equals(this.precipitationAmount, modelsWeather.precipitationAmount) &&
+ Objects.equals(this.relativeHumidity, modelsWeather.relativeHumidity) &&
+ Objects.equals(this.windFromDirection, modelsWeather.windFromDirection) &&
+ Objects.equals(this.windSpeed, modelsWeather.windSpeed) &&
+ Objects.equals(this.windSpeedOfGust, modelsWeather.windSpeedOfGust);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(airTemperature, cloudAreaFraction, error, precipitationAmount, relativeHumidity, windFromDirection, windSpeed, windSpeedOfGust);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("class ModelsWeather {\n");
+ sb.append(" airTemperature: ").append(toIndentedString(airTemperature)).append("\n");
+ sb.append(" cloudAreaFraction: ").append(toIndentedString(cloudAreaFraction)).append("\n");
+ sb.append(" error: ").append(toIndentedString(error)).append("\n");
+ sb.append(" precipitationAmount: ").append(toIndentedString(precipitationAmount)).append("\n");
+ sb.append(" relativeHumidity: ").append(toIndentedString(relativeHumidity)).append("\n");
+ sb.append(" windFromDirection: ").append(toIndentedString(windFromDirection)).append("\n");
+ sb.append(" windSpeed: ").append(toIndentedString(windSpeed)).append("\n");
+ sb.append(" windSpeedOfGust: ").append(toIndentedString(windSpeedOfGust)).append("\n");
+ sb.append("}");
+ return sb.toString();
+ }
+
+ /**
+ * Convert the given object to string with each line indented by 4 spaces
+ * (except the first line).
+ */
+ private String toIndentedString(Object o) {
+ if (o == null) {
+ return "null";
+ }
+ return o.toString().replace("\n", "\n ");
+ }
+
+
+ public static HashSet openapiFields;
+ public static HashSet openapiRequiredFields;
+
+ static {
+ // a set of all properties/fields (JSON key names)
+ openapiFields = new HashSet();
+ openapiFields.add("air_temperature");
+ openapiFields.add("cloud_area_fraction");
+ openapiFields.add("error");
+ openapiFields.add("precipitation_amount");
+ openapiFields.add("relative_humidity");
+ openapiFields.add("wind_from_direction");
+ openapiFields.add("wind_speed");
+ openapiFields.add("wind_speed_of_gust");
+
+ // a set of required properties/fields (JSON key names)
+ openapiRequiredFields = new HashSet();
+ }
+
+ /**
+ * Validates the JSON Element and throws an exception if issues found
+ *
+ * @param jsonElement JSON Element
+ * @throws IOException if the JSON Element is invalid with respect to ModelsWeather
+ */
+ public static void validateJsonElement(JsonElement jsonElement) throws IOException {
+ if (jsonElement == null) {
+ if (!ModelsWeather.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null
+ throw new IllegalArgumentException(String.format("The required field(s) %s in ModelsWeather is not found in the empty JSON string", ModelsWeather.openapiRequiredFields.toString()));
+ }
+ }
+
+ Set> entries = jsonElement.getAsJsonObject().entrySet();
+ // check to see if the JSON string contains additional fields
+ for (Map.Entry entry : entries) {
+ if (!ModelsWeather.openapiFields.contains(entry.getKey())) {
+ throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `ModelsWeather` properties. JSON: %s", entry.getKey(), jsonElement.toString()));
+ }
+ }
+ JsonObject jsonObj = jsonElement.getAsJsonObject();
+ if ((jsonObj.get("error") != null && !jsonObj.get("error").isJsonNull()) && !jsonObj.get("error").isJsonPrimitive()) {
+ throw new IllegalArgumentException(String.format("Expected the field `error` to be a primitive type in the JSON string but got `%s`", jsonObj.get("error").toString()));
+ }
+ }
+
+ public static class CustomTypeAdapterFactory implements TypeAdapterFactory {
+ @SuppressWarnings("unchecked")
+ @Override
+ public TypeAdapter create(Gson gson, TypeToken type) {
+ if (!ModelsWeather.class.isAssignableFrom(type.getRawType())) {
+ return null; // this class only serializes 'ModelsWeather' and its subtypes
+ }
+ final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class);
+ final TypeAdapter thisAdapter
+ = gson.getDelegateAdapter(this, TypeToken.get(ModelsWeather.class));
+
+ return (TypeAdapter) new TypeAdapter() {
+ @Override
+ public void write(JsonWriter out, ModelsWeather value) throws IOException {
+ JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject();
+ elementAdapter.write(out, obj);
+ }
+
+ @Override
+ public ModelsWeather read(JsonReader in) throws IOException {
+ JsonElement jsonElement = elementAdapter.read(in);
+ validateJsonElement(jsonElement);
+ return thisAdapter.fromJsonTree(jsonElement);
+ }
+
+ }.nullSafe();
+ }
+ }
+
+ /**
+ * Create an instance of ModelsWeather given an JSON string
+ *
+ * @param jsonString JSON string
+ * @return An instance of ModelsWeather
+ * @throws IOException if the JSON string is invalid with respect to ModelsWeather
+ */
+ public static ModelsWeather fromJson(String jsonString) throws IOException {
+ return JSON.getGson().fromJson(jsonString, ModelsWeather.class);
+ }
+
+ /**
+ * Convert an instance of ModelsWeather to an JSON string
+ *
+ * @return JSON string
+ */
+ public String toJson() {
+ return JSON.getGson().toJson(this);
+ }
+}
+
diff --git a/src/test/java/io/openepi/agriculture/api/AgricultureApiTest.java b/src/test/java/io/openepi/agriculture/api/AgricultureApiTest.java
new file mode 100644
index 0000000..6ac74bd
--- /dev/null
+++ b/src/test/java/io/openepi/agriculture/api/AgricultureApiTest.java
@@ -0,0 +1,93 @@
+/*
+ * Agriculture API
+ * This API is used to get aggregated data from Deforestation, Flood, Weather and Soil APIs.
+ *
+ * The version of the OpenAPI document: 1.0.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+
+package io.openepi.agriculture.api;
+
+import io.openepi.agriculture.model.*;
+import io.openepi.common.ApiException;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.math.BigDecimal;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+/**
+ * API tests for AgricultureApi
+ */
+public class AgricultureApiTest {
+
+ @Mock
+ private AgricultureApi api = new AgricultureApi();
+
+ @BeforeEach
+ public void setUp() throws Exception {
+ MockitoAnnotations.openMocks(this);
+ }
+
+ /**
+ * Get summary of agriculture data
+ *
+ * Gets aggregated data from Deforestation, Flood, Weather and Soil APIs. See the [API documentation](https://developer.openepi.io) for more information. There is an error field for each of the APIs. If a certain API does not respond, it will instead return with an error message in the field that belong to that API.
+ *
+ * @throws ApiException if the Api call fails
+ */
+ @Test
+ public void getSummaryTest() throws ApiException {
+ BigDecimal lon = new BigDecimal("33.57");
+ BigDecimal lat = BigDecimal.valueOf(-1.37);
+
+ ModelsSummary mockResponse = new ModelsSummary();
+
+ // Mock deforestation data
+ ModelsDeforestation mockDeforestation = new ModelsDeforestation();
+ mockDeforestation.setDaterangeTotTreeloss(new BigDecimal("123"));
+ mockResponse.setDeforestation(mockDeforestation);
+
+ // Mock flood data
+ ModelsFlood mockFlood = new ModelsFlood();
+ mockFlood.setIntensity(ModelsIntensityEnum.Y);
+ mockFlood.setIssuedOn("Testdate");
+ mockFlood.setPeakDay("Testday");
+ mockFlood.setPeakTiming(ModelsPeakTimingEnum.BB);
+ mockFlood.setPeakStep(1);
+ mockResponse.setFlood(mockFlood);
+
+ // Mock weather data
+ ModelsWeather mockWeather = new ModelsWeather();
+ mockWeather.setAirTemperature(new BigDecimal("123"));
+ mockWeather.setCloudAreaFraction(new BigDecimal("123"));
+ mockWeather.setPrecipitationAmount(new BigDecimal("123"));
+ mockWeather.setRelativeHumidity(new BigDecimal("123"));
+ mockWeather.setWindFromDirection(new BigDecimal("123"));
+ mockWeather.setWindSpeed(new BigDecimal("123"));
+ mockWeather.setWindSpeedOfGust(new BigDecimal("123"));
+ mockResponse.setWeather(mockWeather);
+
+ // Mock soil data
+ ModelsSoilType mockSoil = new ModelsSoilType();
+ mockSoil.setMostProbableSoilType("Dirt");
+ mockResponse.setSoil(mockSoil);
+
+ when(api.getSummary(lon, lat)).thenReturn(mockResponse);
+
+ ModelsSummary response = api.getSummary(lon, lat);
+ assertEquals(new BigDecimal("123"), response.getDeforestation().getDaterangeTotTreeloss());
+ }
+}