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.HttpForbiddenException;
23  import davmail.exception.HttpNotFoundException;
24  import davmail.http.HttpClientAdapter;
25  import davmail.util.IOUtil;
26  import org.apache.http.Header;
27  import org.apache.http.HttpEntity;
28  import org.apache.http.HttpResponse;
29  import org.apache.http.HttpStatus;
30  import org.apache.http.client.ResponseHandler;
31  import org.codehaus.jettison.json.JSONException;
32  import org.codehaus.jettison.json.JSONObject;
33  
34  import java.io.IOException;
35  import java.io.InputStream;
36  import java.nio.charset.StandardCharsets;
37  import java.util.zip.GZIPInputStream;
38  
39  /**
40   * Generic Json response handler for graph API calls
41   */
42  public class JsonResponseHandler implements ResponseHandler<JSONObject> {
43      @Override
44      public JSONObject handleResponse(HttpResponse response) throws IOException {
45          JSONObject jsonResponse = null;
46          Header contentTypeHeader = response.getFirstHeader("Content-Type");
47          if (contentTypeHeader != null && contentTypeHeader.getValue().startsWith("application/json")) {
48              try {
49                  jsonResponse = new JSONObject(new String(readResponse(response), StandardCharsets.UTF_8));
50              } catch (JSONException e) {
51                  throw new IOException(e.getMessage(), e);
52              }
53          } else {
54              HttpEntity httpEntity = response.getEntity();
55              if (httpEntity != null) {
56                  try {
57                      return new JSONObject().put("response", new String(readResponse(response), StandardCharsets.UTF_8));
58                  } catch (JSONException e) {
59                      throw new IOException("Invalid response content");
60                  }
61              }
62          }
63          // check http error code
64          if (response.getStatusLine().getStatusCode() >= 400) {
65              String errorMessage = null;
66              if (jsonResponse != null && jsonResponse.optJSONObject("error") != null) {
67                  try {
68                      JSONObject jsonError = jsonResponse.getJSONObject("error");
69                      errorMessage = jsonError.optString("code") + " " + jsonError.optString("message");
70                  } catch (JSONException e) {
71                      // ignore
72                  }
73              }
74              if (errorMessage == null) {
75                  errorMessage = response.getStatusLine().getReasonPhrase();
76              }
77              if (response.getStatusLine().getStatusCode() == HttpStatus.SC_FORBIDDEN) {
78                  throw new HttpForbiddenException(errorMessage);
79              }
80              if (response.getStatusLine().getStatusCode() == HttpStatus.SC_NOT_FOUND) {
81                  throw new HttpNotFoundException(errorMessage);
82              }
83              throw new IOException(errorMessage);
84          }
85          return jsonResponse;
86      }
87  
88      protected byte[] readResponse(HttpResponse response) throws IOException {
89          byte[] content;
90          try (InputStream inputStream = response.getEntity().getContent()) {
91              if (HttpClientAdapter.isGzipEncoded(response)) {
92                  content = IOUtil.readFully(new GZIPInputStream(inputStream));
93              } else {
94                  content = IOUtil.readFully(inputStream);
95              }
96          }
97          return content;
98      }
99  }