package org.ambraproject.wombat.service;

import com.google.common.base.Preconditions;
import com.google.common.io.Closeables;
import com.google.common.io.Closer;
import com.google.gson.Gson;
import org.ambraproject.wombat.config.RuntimeConfiguration;
import org.ambraproject.wombat.util.TrustingHttpClient;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;

public class SoaServiceImpl implements SoaService {

  @Autowired
  private RuntimeConfiguration runtimeConfiguration;
  @Autowired
  private Gson gson;

  @Override
  public InputStream requestStream(String address) throws IOException {
    URI targetUri;
    try {
      targetUri = new URL(runtimeConfiguration.getServer(), Preconditions.checkNotNull(address)).toURI();
    } catch (MalformedURLException e) {
      throw new IllegalArgumentException(e);
    } catch (URISyntaxException e) {
      throw new IllegalArgumentException(e);
    }

    HttpClient client = ("https".equals(targetUri.getScheme()) && runtimeConfiguration.trustUnsignedServer())
        ? TrustingHttpClient.create() : new DefaultHttpClient();
    HttpGet get = new HttpGet(targetUri);
    HttpResponse response = client.execute(get);
    HttpEntity entity = response.getEntity();
    if (entity == null) {
      throw new RuntimeException("No response");
    }
    return entity.getContent();
  }

  @Override
  public String requestString(String address) throws IOException {
    String response;
    InputStream stream = null;
    boolean threw = true;
    try {
      stream = requestStream(address);
      response = IOUtils.toString(stream);
      threw = false;
    } finally {
      Closeables.close(stream, threw);
    }
    return response;
  }

  @Override
  public <T> T requestObject(String address, Class<T> responseClass) throws IOException {
    Preconditions.checkNotNull(responseClass);

    T responseObject;
    Closer closer = Closer.create();
    Reader reader;
    InputStream responseStream;
    try {
      responseStream = closer.register(requestStream(address));
      reader = closer.register(new InputStreamReader(responseStream));
      responseObject = gson.fromJson(reader, responseClass);
    } finally {
      closer.close();
    }
    return responseObject;
  }

}

@@ -84,48 +84,8 @@
 ns;%0A
-import com.google.common.io.Closeables;%0A
 impo
@@ -578,16 +578,52 @@
 wired;%0A%0A
+import java.io.BufferedInputStream;%0A
 import j
@@ -1421,49 +1421,8 @@
  = (
-%22https%22.equals(targetUri.getScheme()) && 
 runt
@@ -1458,16 +1458,57 @@
 dServer(
+) && %22https%22.equals(targetUri.getScheme()
 ))%0A     
@@ -1909,107 +1909,94 @@
     
-String response;%0A    InputStream stream = null;%0A    boolean threw = true;%0A    try %7B%0A      stream = 
+Closer closer = Closer.create();%0A    try %7B%0A      InputStream stream = closer.register(
 requ
@@ -2013,16 +2013,17 @@
 address)
+)
 ;%0A      
@@ -2024,24 +2024,20 @@
       re
-sponse =
+turn
  IOUtils
@@ -2054,16 +2054,56 @@
 stream);
+ // buffered%0A    %7D catch (Throwable t) %7B
 %0A      t
@@ -2108,18 +2108,28 @@
  thr
-ew = false
+ow closer.rethrow(t)
 ;%0A  
@@ -2152,67 +2152,29 @@
     
-C
+c
 lose
-ables
+r
 .close(
-stream, threw);%0A    %7D%0A    return response;
+);%0A    %7D
 %0A  %7D
@@ -2327,31 +2327,8 @@
 ss);
-%0A%0A    T responseObject;
 %0A   
@@ -2369,23 +2369,16 @@
     
-Reader reader;%0A
+try %7B%0A  
     
@@ -2393,72 +2393,56 @@
 eam 
-responseStream;%0A    try %7B%0A      responseStream = closer.register
+stream = closer.register(new BufferedInputStream
 (req
@@ -2461,24 +2461,25 @@
 ddress))
+)
 ;%0A      
 reader =
@@ -2470,16 +2470,23 @@
 ;%0A      
+Reader 
 reader =
@@ -2528,17 +2528,9 @@
 der(
-responseS
+s
 trea
@@ -2546,22 +2546,12 @@
   re
-sponseObject =
+turn
  gso
@@ -2581,24 +2581,83 @@
 onseClass);%0A
+    %7D catch (Throwable t) %7B%0A      throw closer.rethrow(t);%0A
     %7D finall
@@ -2692,35 +2692,8 @@
   %7D%0A
-    return responseObject;%0A
   %7D%0A

Clean up stream-handling