View Javadoc
1   /*
2    * DavMail POP/IMAP/SMTP/CalDav/LDAP Exchange Gateway
3    * Copyright (C) 2010  Mickael Guessant
4    *
5    * This program is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU General Public License
7    * as published by the Free Software Foundation; either version 2
8    * of the License, or (at your option) any later version.
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with this program; if not, write to the Free Software
17   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18   */
19  
20  package davmail.exchange.graph;
21  
22  import davmail.exception.HttpBadRequestException;
23  import davmail.exception.HttpConflictException;
24  import davmail.exception.HttpForbiddenException;
25  import davmail.exception.HttpNotFoundException;
26  import davmail.exception.HttpPreconditionFailedException;
27  import davmail.exception.HttpTokenExpiredException;
28  import davmail.http.HttpClientAdapter;
29  import davmail.util.IOUtil;
30  import org.apache.http.Header;
31  import org.apache.http.HttpEntity;
32  import org.apache.http.HttpResponse;
33  import org.apache.http.HttpStatus;
34  import org.apache.http.client.ResponseHandler;
35  import org.apache.log4j.Logger;
36  import org.codehaus.jettison.json.JSONException;
37  import org.codehaus.jettison.json.JSONObject;
38  
39  import java.io.IOException;
40  import java.io.InputStream;
41  import java.nio.charset.StandardCharsets;
42  import java.util.zip.GZIPInputStream;
43  
44  /**
45   * Generic JSON response handler for graph API calls
46   */
47  public class JsonResponseHandler implements ResponseHandler<JSONObject> {
48  
49      protected static final Logger LOGGER = Logger.getLogger("davmail.exchange.JsonResponseHandler");
50  
51      @Override
52      public JSONObject handleResponse(HttpResponse response) throws IOException {
53          JSONObject jsonResponse = null;
54          Header contentTypeHeader = response.getFirstHeader("Content-Type");
55          if (contentTypeHeader != null && contentTypeHeader.getValue().startsWith("application/json")) {
56              try {
57                  jsonResponse = new JSONObject(new String(readResponse(response), StandardCharsets.UTF_8));
58              } catch (JSONException e) {
59                  throw new IOException(e.getMessage(), e);
60              }
61          } else {
62              HttpEntity httpEntity = response.getEntity();
63              if (httpEntity != null) {
64                  try {
65                      return new JSONObject().put("response", new String(readResponse(response), StandardCharsets.UTF_8));
66                  } catch (JSONException e) {
67                      throw new IOException("Invalid response content");
68                  }
69              }
70          }
71          // check http error code
72          int statusCode = response.getStatusLine().getStatusCode();
73          if (statusCode >= 400) {
74              String errorMessage = null;
75              String errorCode = null;
76              if (jsonResponse != null && jsonResponse.optJSONObject("error") != null) {
77                  try {
78                      JSONObject jsonError = jsonResponse.getJSONObject("error");
79                      errorCode = jsonError.optString("code", null);
80                      errorMessage = errorCode + " " + jsonError.optString("message");
81  
82                      if (LOGGER.isDebugEnabled()) {
83                          LOGGER.debug(statusCode+" "+response.getStatusLine().getReasonPhrase()+" " + jsonError);
84                      }
85                  } catch (JSONException e) {
86                      // ignore
87                  }
88              }
89              if (errorMessage == null) {
90                  errorMessage = response.getStatusLine().getReasonPhrase();
91              }
92              if (statusCode == HttpStatus.SC_UNAUTHORIZED && "InvalidAuthenticationToken".equals(errorCode)) {
93                  throw new HttpTokenExpiredException(errorMessage);
94              }
95              if (statusCode == HttpStatus.SC_FORBIDDEN) {
96                  throw new HttpForbiddenException(errorCode, errorMessage);
97              }
98              if (statusCode == HttpStatus.SC_NOT_FOUND) {
99                  throw new HttpNotFoundException(errorMessage);
100             }
101             if (statusCode == HttpStatus.SC_CONFLICT) {
102                 throw new HttpConflictException(errorMessage);
103             }
104             if (statusCode == HttpStatus.SC_PRECONDITION_FAILED) {
105                 throw new HttpPreconditionFailedException(errorMessage);
106             }
107             if (statusCode == HttpStatus.SC_BAD_REQUEST) {
108                 throw new HttpBadRequestException(errorMessage);
109             }
110             throw new IOException(errorMessage);
111         }
112         // ensure non-null response
113         if (jsonResponse == null) {
114             jsonResponse = new JSONObject();
115         }
116         return jsonResponse;
117     }
118 
119     protected byte[] readResponse(HttpResponse response) throws IOException {
120         byte[] content;
121         try (InputStream inputStream = response.getEntity().getContent()) {
122             if (HttpClientAdapter.isGzipEncoded(response)) {
123                 content = IOUtil.readFully(new GZIPInputStream(inputStream));
124             } else {
125                 content = IOUtil.readFully(inputStream);
126             }
127         }
128         return content;
129     }
130 }