Refactored classes in thematically packages
[facebook-errors] / src / main / java / de / juplo / facebook / client / GraphApiErrorHandler.java
diff --git a/src/main/java/de/juplo/facebook/client/GraphApiErrorHandler.java b/src/main/java/de/juplo/facebook/client/GraphApiErrorHandler.java
new file mode 100644 (file)
index 0000000..faff55e
--- /dev/null
@@ -0,0 +1,148 @@
+package de.juplo.facebook.client;
+
+import de.juplo.facebook.exceptions.GraphApiException;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.HttpMessageNotReadableException;
+import org.springframework.security.oauth2.client.http.OAuth2ErrorHandler;
+import org.springframework.util.FileCopyUtils;
+import org.springframework.web.client.HttpMessageConverterExtractor;
+import org.springframework.web.client.RestClientException;
+import org.springframework.web.client.RestTemplate;
+
+
+
+/**
+ *
+ * @author kai
+ */
+public class GraphApiErrorHandler extends OAuth2ErrorHandler
+{
+  private final OAuth2ErrorHandler errorHandler;
+  private List<HttpMessageConverter<?>> messageConverters =
+      new RestTemplate().getMessageConverters();
+
+
+  public GraphApiErrorHandler(OAuth2ErrorHandler errorHandler)
+  {
+    super(null);
+    this.errorHandler = errorHandler;
+  }
+
+
+       /**
+        * @param messageConverters the messageConverters to set
+        */
+  @Override
+  public void setMessageConverters(
+      List<HttpMessageConverter<?>> messageConverters
+      )
+  {
+    this.messageConverters = messageConverters;
+    errorHandler.setMessageConverters(messageConverters);
+  }
+
+  @Override
+  public boolean hasError(ClientHttpResponse response) throws IOException
+  {
+    return
+        HttpStatus.Series.CLIENT_ERROR.equals(response.getStatusCode().series())
+        || this.errorHandler.hasError(response);
+  }
+
+  @Override
+  public void handleError(final ClientHttpResponse response) throws IOException
+  {
+    if (!HttpStatus.Series.CLIENT_ERROR.equals(response.getStatusCode().series()))
+    {
+      // We should only care about 400 level errors. Ex: A 500 server error shouldn't
+      // be an oauth related error.
+      errorHandler.handleError(response);
+    }
+    else
+    {
+      // Need to use buffered response because input stream may need to be consumed multiple times.
+      ClientHttpResponse bufferedResponse = new ClientHttpResponse()
+      {
+        private byte[] lazyBody;
+
+        @Override
+        public HttpStatus getStatusCode() throws IOException
+        {
+          return response.getStatusCode();
+        }
+
+        @Override
+        public synchronized InputStream getBody() throws IOException
+        {
+          if (lazyBody == null) {
+            InputStream bodyStream = response.getBody();
+            if (bodyStream != null) {
+              lazyBody = FileCopyUtils.copyToByteArray(bodyStream);
+            }
+            else {
+              lazyBody = new byte[0];
+            }
+          }
+          return new ByteArrayInputStream(lazyBody);
+        }
+
+        @Override
+        public HttpHeaders getHeaders()
+        {
+          return response.getHeaders();
+        }
+
+        @Override
+        public String getStatusText() throws IOException
+        {
+          return response.getStatusText();
+        }
+
+        @Override
+        public void close()
+        {
+          response.close();
+        }
+
+        @Override
+        public int getRawStatusCode() throws IOException
+        {
+          return response.getRawStatusCode();
+        }
+      };
+
+
+      HttpMessageConverterExtractor<GraphApiException> extractor =
+          new HttpMessageConverterExtractor<>(
+              GraphApiException.class,
+              messageConverters
+              );
+
+      try
+      {
+        GraphApiException body = extractor.extractData(bufferedResponse);
+        if (body != null)
+        {
+          // If we can get an OAuth2Exception already from the body, it is likely
+          // to have more information than the header does, so just re-throw it
+          // here.
+          body.setHttpErrorCode(response.getRawStatusCode());
+          throw body;
+        }
+      }
+      catch (RestClientException|HttpMessageNotReadableException e)
+      {
+        // ignore
+      }
+
+      errorHandler.handleError(bufferedResponse);
+    }
+  }
+}