com.github.javadev.undescriptive.client.AsyncClient.java Source code

Java tutorial

Introduction

Here is the source code for com.github.javadev.undescriptive.client.AsyncClient.java

Source

package com.github.javadev.undescriptive.client;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.joda.JodaModule;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
import com.github.javadev.undescriptive.protocol.request.*;
import com.github.javadev.undescriptive.protocol.response.*;
import com.ning.http.client.AsyncCompletionHandler;
import com.ning.http.client.AsyncHttpClient;
import com.ning.http.client.AsyncHttpClient.BoundRequestBuilder;
import com.ning.http.client.AsyncHttpClientConfig;
import com.ning.http.client.AsyncHttpClientConfig.Builder;
import com.ning.http.client.Realm;
import com.ning.http.client.Response;

import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

public class AsyncClient {
    private static final String BASE_URL = "http://www.dragonsofmugloar.com";
    private static final String WEATHER_URL = "/weather/api/report/";

    private final static ObjectMapper MAPPER = new ObjectMapper().registerModule(new JodaModule())
            .registerModule(new SimpleModule()).configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    private final static XmlMapper XML_MAPPER = new XmlMapper();

    private static final int[][] SOLUTIONS = { { 8, 8, 4, 0 }, { 10, 6, 3, 1 }, { 8, 7, 5, 0 }, { 10, 5, 4, 1 },
            { 8, 6, 6, 0 }, { 10, 4, 4, 2 }, { 7, 7, 6, 0 }, { 10, 4, 4, 2 }, { 8, 8, 3, 1 }, { 10, 6, 2, 2 },
            { 8, 7, 4, 1 }, { 10, 5, 4, 1 }, { 8, 6, 5, 1 }, { 10, 4, 5, 1 }, { 7, 7, 5, 1 }, { 9, 5, 4, 2 },
            { 7, 6, 6, 1 }, { 9, 4, 4, 3 }, { 8, 8, 2, 2 }, { 10, 6, 3, 1 }, { 8, 7, 3, 2 }, { 10, 5, 4, 1 },
            { 8, 6, 4, 2 }, { 10, 4, 3, 3 }, { 7, 7, 4, 2 }, { 10, 5, 4, 1 }, { 8, 5, 5, 2 }, { 10, 5, 4, 1 },
            { 7, 6, 5, 2 }, { 10, 4, 4, 2 }, { 6, 6, 6, 2 }, { 10, 4, 3, 3 }, { 8, 6, 3, 3 }, { 10, 4, 4, 2 },
            { 7, 7, 3, 3 }, { 10, 4, 4, 2 }, { 8, 5, 4, 3 }, { 10, 4, 4, 2 }, { 7, 6, 4, 3 }, { 9, 4, 5, 2 },
            { 7, 5, 5, 3 }, { 9, 5, 4, 2 }, { 6, 6, 5, 3 }, { 8, 5, 4, 3 }, { 8, 4, 4, 4 }, { 10, 4, 3, 3 },
            { 7, 5, 4, 4 }, { 10, 4, 3, 3 }, { 6, 6, 4, 4 }, { 10, 4, 3, 3 }, { 6, 5, 5, 4 }, { 10, 4, 3, 3 },
            { 5, 5, 5, 5 }, { 10, 4, 3, 3 } };

    private final AsyncHttpClient httpClient;
    private final String baseUrl;

    private AsyncClient(final AsyncHttpClient httpClient, final String baseUrl) {
        this.httpClient = httpClient;
        this.baseUrl = baseUrl;
    }

    private static AsyncHttpClientConfig commonSetup(final AsyncHttpClientConfig.Builder configBuilder) {
        final Realm realm = new Realm.RealmBuilder().build();
        configBuilder.setRealm(realm);
        return configBuilder.build();
    }

    public static AsyncClient createDefault() {
        return new AsyncClient(new AsyncHttpClient(commonSetup(new Builder())), BASE_URL);
    }

    public static AsyncClient create(final AsyncHttpClientConfig config) {
        return new AsyncClient(new AsyncHttpClient(commonSetup(new Builder(config))), BASE_URL);
    }

    public void close() {
        this.httpClient.close();
    }

    public void closeAsynchronously() {
        this.httpClient.closeAsynchronously();
    }

    private BoundRequestBuilder get(final String resourceUrl) {
        return this.httpClient.prepareGet(this.baseUrl + resourceUrl);
    }

    private BoundRequestBuilder put(final String resourceUrl, final HasParams hasParams) {
        final BoundRequestBuilder builder = this.httpClient.preparePut(this.baseUrl + resourceUrl);
        final Map<String, Object> params = hasParams.getParams();
        try {
            final String objectAsString = MAPPER.writeValueAsString(params);
            builder.addHeader("Content-Type", "application/json; charset=utf-8");
            builder.setBody(objectAsString);
        } catch (Exception ignore) {
        }
        return builder;
    }

    public ListenableFuture<GameResponse> getGame() {
        return execute(GameResponse.class, get("/api/game"));
    }

    public ListenableFuture<SolutionResponse> sendSolution(Integer id, SolutionRequest solutionRequest) {
        return execute(SolutionResponse.class, put("/api/game/" + id + "/solution", solutionRequest));
    }

    public SolutionRequest generateGameSolution(GameResponseItem gameResponseItem,
            WeatherResponse weatherResponse) {
        if ("T E".equals(weatherResponse.getCode())) {
            return SolutionRequest.builder().scale(5).claw(5).wing(5).fire(5).build();
        } else if ("HVA".equals(weatherResponse.getCode())) {
            return SolutionRequest.builder().scale(10).claw(10).wing(0).fire(0).build();
        }

        final List<Integer> knightAttrs = Arrays.asList(gameResponseItem.getAttack(), gameResponseItem.getArmor(),
                gameResponseItem.getAgility(), gameResponseItem.getEndurance());
        final Integer[] indexes = { 0, 1, 2, 3 };

        Arrays.sort(indexes, new Comparator<Integer>() {
            @Override
            public int compare(final Integer o1, final Integer o2) {
                return knightAttrs.get(o1).compareTo(knightAttrs.get(o2));
            }
        });
        int maxIndex = indexes[3];
        int secondMaxIndex = indexes[2];
        int thirdMaxIndex = indexes[1];
        int forthMaxIndex = indexes[0];
        int[] dragonAttrs = new int[] { 0, 0, 0, 0 };
        for (int index = 0; index < SOLUTIONS.length; index += 2) {
            if (knightAttrs.get(maxIndex) == SOLUTIONS[index][0]
                    && knightAttrs.get(secondMaxIndex) == SOLUTIONS[index][1]
                    && knightAttrs.get(thirdMaxIndex) == SOLUTIONS[index][2]
                    && knightAttrs.get(forthMaxIndex) == SOLUTIONS[index][3]) {
                dragonAttrs[maxIndex] = SOLUTIONS[index + 1][0];
                dragonAttrs[secondMaxIndex] = SOLUTIONS[index + 1][1];
                dragonAttrs[thirdMaxIndex] = SOLUTIONS[index + 1][2];
                dragonAttrs[forthMaxIndex] = SOLUTIONS[index + 1][3];
                break;
            }
        }
        final SolutionRequest request = SolutionRequest.builder().scale(dragonAttrs[0]).claw(dragonAttrs[1])
                .wing(dragonAttrs[2]).fire(dragonAttrs[3]).build();
        return request;
    }

    public ListenableFuture<WeatherResponse> getWeather(Integer id) {
        return execute(WeatherResponse.class, get(WEATHER_URL + id));
    }

    private static <T> ListenableFuture<T> execute(final Class<T> clazz, final BoundRequestBuilder request) {
        final SettableFuture<T> guavaFut = SettableFuture.create();
        try {
            request.execute(new GuavaFutureConverter<T>(clazz, guavaFut));
        } catch (final IOException e) {
            guavaFut.setException(e);
        }
        return guavaFut;
    }

    private static class GuavaFutureConverter<T> extends AsyncCompletionHandler<T> {
        private final Class<T> clazz;
        private final SettableFuture<T> guavaFut;

        public GuavaFutureConverter(final Class<T> clazz, final SettableFuture<T> guavaFut) {
            this.clazz = clazz;
            this.guavaFut = guavaFut;
        }

        private static boolean isSuccess(final Response response) {
            final int statusCode = response.getStatusCode();
            return (statusCode > 199 && statusCode < 400);
        }

        @Override
        public void onThrowable(final Throwable t) {
            guavaFut.setException(t);
        }

        @Override
        public T onCompleted(final Response response) throws Exception {
            if (isSuccess(response)) {
                final T value = clazz == WeatherResponse.class
                        ? XML_MAPPER.readValue(response.getResponseBody(), clazz)
                        : MAPPER.readValue(response.getResponseBody(), clazz);
                guavaFut.set(value);
                return value;
            } else {
                throw new UnsupportedOperationException(response.getResponseBody());
            }
        }
    }

    public static void main(String... args) {
        final String message = "Dragons of Mugloar solution.\n\n"
                + "For docs, license, tests, and downloads, see: http://javadev.github.io/undescriptive-project";
        System.out.println(message);
    }
}