Upgraded all dependencies
[facebook-utils] / src / main / java / de / juplo / facebook / GraphApiErrorHandler.java
1 package de.juplo.facebook;
2
3 import java.io.ByteArrayInputStream;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.util.List;
7 import org.springframework.http.HttpHeaders;
8 import org.springframework.http.HttpStatus;
9 import org.springframework.http.client.ClientHttpResponse;
10 import org.springframework.http.converter.HttpMessageConverter;
11 import org.springframework.http.converter.HttpMessageNotReadableException;
12 import org.springframework.security.oauth2.client.http.OAuth2ErrorHandler;
13 import org.springframework.util.FileCopyUtils;
14 import org.springframework.web.client.HttpMessageConverterExtractor;
15 import org.springframework.web.client.RestClientException;
16 import org.springframework.web.client.RestTemplate;
17
18
19
20 /**
21  *
22  * @author kai
23  */
24 public class GraphApiErrorHandler extends OAuth2ErrorHandler
25 {
26   private final OAuth2ErrorHandler errorHandler;
27   private List<HttpMessageConverter<?>> messageConverters =
28       new RestTemplate().getMessageConverters();
29
30
31   public GraphApiErrorHandler(OAuth2ErrorHandler errorHandler)
32   {
33     super(null);
34     this.errorHandler = errorHandler;
35   }
36
37
38         /**
39          * @param messageConverters the messageConverters to set
40          */
41   @Override
42   public void setMessageConverters(
43       List<HttpMessageConverter<?>> messageConverters
44       )
45   {
46     this.messageConverters = messageConverters;
47     errorHandler.setMessageConverters(messageConverters);
48   }
49
50   @Override
51   public boolean hasError(ClientHttpResponse response) throws IOException
52   {
53     return
54         HttpStatus.Series.CLIENT_ERROR.equals(response.getStatusCode().series())
55         || this.errorHandler.hasError(response);
56   }
57
58   @Override
59   public void handleError(final ClientHttpResponse response) throws IOException
60   {
61     if (!HttpStatus.Series.CLIENT_ERROR.equals(response.getStatusCode().series()))
62     {
63       // We should only care about 400 level errors. Ex: A 500 server error shouldn't
64       // be an oauth related error.
65       errorHandler.handleError(response);
66     }
67     else
68     {
69       // Need to use buffered response because input stream may need to be consumed multiple times.
70       ClientHttpResponse bufferedResponse = new ClientHttpResponse()
71       {
72         private byte[] lazyBody;
73
74         @Override
75         public HttpStatus getStatusCode() throws IOException
76         {
77           return response.getStatusCode();
78         }
79
80         @Override
81         public synchronized InputStream getBody() throws IOException
82         {
83           if (lazyBody == null) {
84             InputStream bodyStream = response.getBody();
85             if (bodyStream != null) {
86               lazyBody = FileCopyUtils.copyToByteArray(bodyStream);
87             }
88             else {
89               lazyBody = new byte[0];
90             }
91           }
92           return new ByteArrayInputStream(lazyBody);
93         }
94
95         @Override
96         public HttpHeaders getHeaders()
97         {
98           return response.getHeaders();
99         }
100
101         @Override
102         public String getStatusText() throws IOException
103         {
104           return response.getStatusText();
105         }
106
107         @Override
108         public void close()
109         {
110           response.close();
111         }
112
113         @Override
114         public int getRawStatusCode() throws IOException
115         {
116           return response.getRawStatusCode();
117         }
118       };
119
120
121       HttpMessageConverterExtractor<GraphApiException> extractor =
122           new HttpMessageConverterExtractor<>(
123               GraphApiException.class,
124               messageConverters
125               );
126
127       try
128       {
129         GraphApiException body = extractor.extractData(bufferedResponse);
130         if (body != null)
131         {
132           // If we can get an OAuth2Exception already from the body, it is likely
133           // to have more information than the header does, so just re-throw it
134           // here.
135           body.setHttpErrorCode(response.getRawStatusCode());
136           throw body;
137         }
138       }
139       catch (RestClientException|HttpMessageNotReadableException e)
140       {
141         // ignore
142       }
143
144       errorHandler.handleError(bufferedResponse);
145     }
146   }
147 }