/**
* i-net software provides programming examples for illustration only, without warranty
* either expressed or implied, including, but not limited to, the implied warranties
* of merchantability and/or fitness for a particular purpose. This programming example
* assumes that you are familiar with the programming language being demonstrated and
* the tools used to create and debug procedures. i-net software support professionals
* can help explain the functionality of a particular procedure, but they will not modify
* these examples to provide added functionality or construct procedures to meet your
* specific needs.
*
* Copyright © 1999-2025 i-net software GmbH, Berlin, Germany.
**/
package com.inet.taskplanner.openweathermap;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import com.inet.http.servlet.ClientLocale;
import com.inet.lib.json.Json;
import com.inet.lib.util.EncodingFunctions;
import com.inet.taskplanner.server.api.error.TaskExecutionException;
import com.inet.taskplanner.server.api.job.ConditionDefinition;
import com.inet.taskplanner.server.api.job.Job;
import com.inet.taskplanner.server.api.job.JobResultContainer;
import com.inet.taskplanner.server.api.job.ResultContainer;
import com.inet.taskplanner.server.api.result.StringTextResult;
/**
* A handler that connects to the open weather map API and queries the current weather information.
* This instance is created by the according factory and executes the job.
*/
public class OpenWeatherMapJob extends Job {
// The URL to the openweathermap.org API
private static final String API_URL = "https://api.openweathermap.org/data/2.5/";
// Value, defined by the user
private String apiKey;
private String location;
private Units units = Units.DEFAULT;
// current temperature is stored as member in this instance to allow the condition to be evaluated afterwards
private double currentTemperature = 0d;
// Will be set to true if the user requested a stopping of the job
private boolean stopRequested = false;
/**
* Creates the job.
* @param apiKey the open weather map api key
* @param location the set location to get the weather data for
* @param units the selected unit setting
* @param condition the optional condition that can be applies
*/
public OpenWeatherMapJob( String apiKey, String location, String units, ConditionDefinition condition ) {
super( condition );
this.apiKey = apiKey;
this.location = location;
if( units != null ) {
try {
this.units = Units.valueOf( units );
} catch( IllegalArgumentException iae ) {
// Fallback to DEFAULT
}
}
}
/**
* {@inheritDoc}
*/
@Override
protected JobResultContainer run() throws TaskExecutionException {
try {
String cityAndCountry = "q=" + EncodingFunctions.encodeUrlParameter( location ); // Location as City,CountryCode as search query
String appID = "appid=" + EncodingFunctions.encodeUrlParameter( apiKey ); // App ID, entered by the user
String language = "lang=" + EncodingFunctions.encodeUrlParameter( ClientLocale.getThreadLocale().getLanguage().toLowerCase() ); // Current language settings retrieved from the client locale
String unitSettings = "units=" + EncodingFunctions.encodeUrlParameter( units.name().toLowerCase() ); // The units, selected by the user
// Create the target URL
URL target = new URL( API_URL + "weather?" + cityAndCountry + "&" + appID + "&" + language + "&" + unitSettings );
if( stopRequested ) {
return null;
}
// Open the connection and read the data from the input stream
URLConnection connection = target.openConnection();
try (InputStream inputStream = connection.getInputStream()) {
if( stopRequested ) {
return null;
}
// Read the data with the JSON-Parser into a WeatherData instance.
// the HashMap for extraFields is set, to allow additional fields int the response data that can be ignored. Values that do not match a field, will be added to this map.
WeatherData weatherData = new Json().fromJson( inputStream, WeatherData.class, new HashMap