All Downloads are FREE. Search and download functionalities are using the official Maven repository.

be.skylark.weather.darkskyclient.client.DarkSkyClient Maven / Gradle / Ivy

package be.skylark.weather.darkskyclient.client;

import be.skylark.weather.darkskyclient.entities.DsBlock;
import be.skylark.weather.darkskyclient.entities.DsMeta;
import be.skylark.weather.darkskyclient.errors.DsForecastException;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import be.skylark.weather.darkskyclient.entities.DsResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.commons.text.StringSubstitutor;
import org.apache.http.client.utils.URIBuilder;
import org.glassfish.jersey.client.filter.EncodingFilter;
import org.glassfish.jersey.message.GZipEncoder;

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.math.BigDecimal;
import java.net.URISyntaxException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * This is the main class of the library that provides the access to the DarkSky API
 */
@NoArgsConstructor
public class DarkSkyClient {

    private static final String API_KEY_PARAM = "apiKey" ;
    private static final String LATITUDE_PARAM = "latitude" ;
    private static final String LONGITUDE_PARAM = "longitude" ;
    private static final String UNIX_TIME_PARAM = "unixTime" ;

    @Getter @Setter private String baseApiUrl ;
    @Getter @Setter private String forecastPath ;
    @Getter @Setter private String timeMachinePath ;
    @Getter @Setter private String apiKey ;

    private Client restClient = ClientBuilder.newClient().register(GZipEncoder.class).register(EncodingFilter.class) ;

    /**
     * Contacts the DarkSky API and ask for a Forecast
     * @param forecastRequest The forecast request
     * @return The DarkSky Forecast
     * @throws DsForecastException Exception raised if any error occurs
     */
    public DsResponse getForecast(final DsForecastRequest forecastRequest) throws DsForecastException {

        if ( StringUtils.isBlank(this.apiKey)
                || forecastRequest == null
                || forecastRequest.getLatitude() == null
                || forecastRequest.getLongitude() == null ) {
            throw new IllegalArgumentException("Missing parameter for the Forecast request");
        }

        Map urlParameters = buildParametersMap(forecastRequest.getLatitude(),forecastRequest.getLongitude(),null ) ;
        StringSubstitutor urlGenerator = new StringSubstitutor( urlParameters ) ;

        try {
            URIBuilder uriBuilder = new URIBuilder(urlGenerator.replace(StringUtils.join(baseApiUrl, forecastPath)));

            if ( forecastRequest.getExcludeBlocks() != null && forecastRequest.getExcludeBlocks().size() > 0 ) {
                String excludeBlocks = forecastRequest.getExcludeBlocks().stream().map(DsBlock::getValue).collect(Collectors.joining(","));
                uriBuilder.addParameter( DarkSkyClientHelper.EXCLUDE_BLOCKS , excludeBlocks );
            }
            if ( forecastRequest.getExtendHourly() != null && forecastRequest.getExtendHourly() ) {
                uriBuilder.addParameter( DarkSkyClientHelper.EXTEND_HOURLY , DarkSkyClientHelper.EXTEND_HOURLY_VALUE );
            }
            if ( forecastRequest.getLang() != null ) {
                uriBuilder.addParameter( DarkSkyClientHelper.LANG , forecastRequest.getLang().getValue() ) ;
            }
            if ( forecastRequest.getUnits() != null ) {
                uriBuilder.addParameter( DarkSkyClientHelper.UNITS , forecastRequest.getUnits().getValue() ) ;
            }
            return performDarkSkyCall(uriBuilder.build().toString()) ;

        } catch ( URISyntaxException e ) {
            throw new DsForecastException("Unable to build the DarkSky API URL", e);
        } catch ( WebApplicationException e ) {
            throw new DsForecastException("Unable to reach the DarkSky API !", e);
        }
    }

    /**
     * Contacts the DarkSky API and ask for a Time Machine report
     * @param timeMachineRequest The time machine request
     * @return The DarkSky Forecast
     * @throws DsForecastException Exception raised if any error occurs
     */
    public DsResponse getTimeMachine(final DsTimeMachineRequest timeMachineRequest) throws DsForecastException {

        if ( StringUtils.isBlank(this.apiKey)
                || timeMachineRequest == null
                || timeMachineRequest.getLatitude() == null
                || timeMachineRequest.getLongitude() == null
                || timeMachineRequest.getTime() == null ) {
            throw new IllegalArgumentException("Missing parameter for the Time Machine request");
        }

        Map urlParameters = buildParametersMap(timeMachineRequest.getLatitude(),timeMachineRequest.getLongitude(),timeMachineRequest.getTime() ) ;
        StringSubstitutor urlGenerator = new StringSubstitutor( urlParameters ) ;

        try {
            URIBuilder uriBuilder = new URIBuilder(urlGenerator.replace(StringUtils.join(baseApiUrl, timeMachinePath)));
            if ( timeMachineRequest.getExcludeBlocks() != null && timeMachineRequest.getExcludeBlocks().size() > 0 ) {
                String excludeBlocks = timeMachineRequest.getExcludeBlocks().stream().map(DsBlock::getValue).collect(Collectors.joining(","));
                uriBuilder.addParameter( DarkSkyClientHelper.EXCLUDE_BLOCKS , excludeBlocks );
            }
            if ( timeMachineRequest.getLang() != null ) {
                uriBuilder.addParameter( DarkSkyClientHelper.LANG , timeMachineRequest.getLang().getValue() ) ;
            }
            if ( timeMachineRequest.getUnits() != null ) {
                uriBuilder.addParameter( DarkSkyClientHelper.UNITS , timeMachineRequest.getUnits().getValue() ) ;
            }
            return performDarkSkyCall(uriBuilder.build().toString()) ;

        } catch ( URISyntaxException e ) {
            throw new DsForecastException("Unable to build the DarkSky API URL", e);
        } catch ( WebApplicationException e ) {
            throw new DsForecastException("Unable to reach the DarkSky API !", e);
        }
    }

    private Map buildParametersMap(BigDecimal latitude, BigDecimal longitude, Long unixTime) {
        Map urlParameters = new LinkedHashMap<>() ;
        urlParameters.put( API_KEY_PARAM, this.apiKey ) ;
        urlParameters.put( LATITUDE_PARAM, latitude.toString() );
        urlParameters.put( LONGITUDE_PARAM, longitude.toString() );
        if ( unixTime != null ) {
            urlParameters.put( UNIX_TIME_PARAM, unixTime.toString() );
        }
        return urlParameters ;
    }

    private DsResponse performDarkSkyCall(final String uri) throws DsForecastException {
        Response forecast = restClient.target(uri).request(MediaType.APPLICATION_JSON_TYPE).get() ;
        if ( forecast != null && forecast.getStatus() == Response.Status.OK.getStatusCode() ) {
            DsMeta meta = DsMeta.builder()
                    .cacheControl(forecast.getHeaderString(DsMeta.HEADER_CACHE_CONTROL))
                    .apiCalls(NumberUtils.toInt(forecast.getHeaderString(DsMeta.HEADER_API_CALLS),NumberUtils.INTEGER_ZERO))
                    .responseTime(forecast.getHeaderString(DsMeta.HEADER_RESPONSE_TIME))
                    .build();
            DsResponse dsForecast = forecast.readEntity(DsResponse.class) ;
            dsForecast.setMetaData( meta );
            return dsForecast ;
        }
        if ( forecast != null )
            throw new DsForecastException(String.format("Unable to perform the DarkSky API call ; HTTP code returned is %d", forecast.getStatus())) ;
        throw new DsForecastException("Unable to reach the DarkSky API ; no answer received") ;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy