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