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