package com.yammer.dropwizard.client;

import com.sun.jersey.api.client.filter.GZIPContentEncodingFilter;
import com.sun.jersey.client.apache4.ApacheHttpClient4Handler;
import com.sun.jersey.client.apache4.config.ApacheHttpClient4Config;
import com.sun.jersey.client.apache4.config.DefaultApacheHttpClient4Config;
import com.yammer.dropwizard.config.Environment;
import com.yammer.dropwizard.jersey.JacksonMessageBodyProvider;
import org.apache.http.client.HttpClient;

import java.util.concurrent.TimeUnit;

import static com.google.common.base.Preconditions.checkNotNull;

public class JerseyClientFactory {
    private final JerseyClientConfiguration configuration;
    private final HttpClientFactory factory;
    private final ApacheHttpClient4Config config;

    public JerseyClientFactory(JerseyClientConfiguration configuration) {
        this.configuration = configuration;
        this.factory = new HttpClientFactory(configuration);
        this.config = new DefaultApacheHttpClient4Config();
    }

    /**
     * Adds the given object as a Jersey provider.
     *
     * @param provider    a Jersey provider
     */
    public JerseyClientFactory addProvider(Object provider) {
        config.getSingletons().add(checkNotNull(provider));
        return this;
    }

    /**
     * Adds the given class as a Jersey provider.
     * <p/><b>N.B.:</b> This class must either have a no-args constructor or use Jersey's built-in
     * dependency injection.
     *
     * @param klass    a Jersey provider class
     */
    public JerseyClientFactory addProvider(Class<?> klass) {
        config.getClasses().add(checkNotNull(klass));
        return this;
    }

    public JerseyClient build(Environment environment) {
        final HttpClient client = factory.build();

        final ApacheHttpClient4Handler handler = new ApacheHttpClient4Handler(client, null, true);
        config.getSingletons().add(new JacksonMessageBodyProvider(environment.getObjectMapperFactory().build()));

        final JerseyClient jerseyClient = new JerseyClient(handler, config);
        jerseyClient.setExecutorService(environment.managedExecutorService("jersey-client-%d",
                                                                           configuration.getMinThreads(),
                                                                           configuration.getMaxThreads(),
                                                                           60,
                                                                           TimeUnit.SECONDS));

        if (configuration.isGzipEnabled()) {
            jerseyClient.addFilter(new GZIPContentEncodingFilter(configuration.isCompressRequestEntity()));
        }

        return jerseyClient;
    }
}

@@ -28,24 +28,76 @@
 rd.client;%0A%0A
+import com.fasterxml.jackson.databind.ObjectMapper;%0A
 import com.s
@@ -511,24 +511,69 @@
 ttpClient;%0A%0A
+import java.util.concurrent.ExecutorService;%0A
 import java.
@@ -1813,24 +1813,750 @@
 ironment) %7B%0A
+        final ExecutorService threadPool = environment.managedExecutorService(%22jersey-client-%25d%22,%0A                                                                              configuration.getMinThreads(),%0A                                                                              configuration.getMaxThreads(),%0A                                                                              60,%0A                                                                              TimeUnit.SECONDS);%0A        final ObjectMapper objectMapper = environment.getObjectMapperFactory().build();%0A%0A        return build(threadPool, objectMapper);%0A    %7D%0A%0A    public JerseyClient build(ExecutorService threadPool, ObjectMapper objectMapper) %7B%0A
         fina
@@ -2586,33 +2586,32 @@
 actory.build();%0A
-%0A
         final Ap
@@ -2763,57 +2763,24 @@
 der(
-environment.getObjectMapperFactory().build()
+objectMapper
 ));%0A
-%0A
     
@@ -2896,446 +2896,18 @@
 ice(
-environment.managedExecutorService(%22jersey-client-%25d%22,%0A                                                                           configuration.getMinThreads(),%0A                                                                           configuration.getMaxThreads(),%0A                                                                           60,%0A                                                                           TimeUnit.SECONDS)
+threadPool
 );%0A%0A

Allow building JerseyClients outside of an Environment.