/* See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * Esri Inc. licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.esri.gpt.agp.client; import java.util.logging.Level; import java.util.logging.Logger; import com.esri.gpt.framework.http.ContentHandler; import com.esri.gpt.framework.http.ContentProvider; import com.esri.gpt.framework.http.HttpClientException; import com.esri.gpt.framework.http.HttpClientRequest; import com.esri.gpt.framework.http.StringHandler; import com.esri.gpt.framework.http.StringProvider; import com.esri.gpt.framework.util.Val; import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HttpClient; import org.json.JSONObject; /** * An ArcGIS Portal client. */ public class AgpClient { /** class variables ========================================================= */ /** The Logger. */ private static final Logger LOGGER = Logger.getLogger(AgpClient.class.getName()); /** instance variables ====================================================== */ private HttpClient batchHttpClient; /** constructors ============================================================ */ /** Default constructor. */ public AgpClient() { super(); this.batchHttpClient = new HttpClient(); } /** methods ================================================================= */ /** * Closes any open resources. */ public void close() { if ((this.batchHttpClient != null) && (this.batchHttpClient.getHttpConnectionManager() != null)) { this.batchHttpClient.getHttpConnectionManager().closeIdleConnections(0); } this.batchHttpClient = null; } /** * Executes a request expecting a JSON response. * @param url the URL * @param requestHeader optional request header properties * @param contentProvider the request body content provider * @return the JSON response object * @throws Exception is an exception occurs */ public JSONObject executeJsonRequest(String url, AgpProperties requestHeader, ContentProvider contentProvider) throws Exception { LOGGER.finest("Sending URL: "+url); StringHandler handler = new StringHandler(); this.executeRequest(url,requestHeader,contentProvider,handler); String sResponse = handler.getContent(); LOGGER.finest("Response for URL: "+url+"\n"+sResponse); JSONObject jsoResponse = null; try { if (sResponse == null) { LOGGER.finest("Response for URL: "+url+"\nnull response"); } else if (sResponse.length() == 0) { LOGGER.finest("Response for URL: "+url+"\nempty response"); } else { jsoResponse = new JSONObject(sResponse); if (jsoResponse.has("error") && (!jsoResponse.isNull("error"))) { AgpError agpError = new AgpError(); agpError.parse(jsoResponse); throw new AgpException(agpError); } } } catch (AgpException e) { LOGGER.log(Level.FINEST,"Request failed.",e); throw e; } catch (Throwable t) { LOGGER.log(Level.FINEST,"Request failed.",t); AgpError agpError = new AgpError(); agpError.setMessage(t.toString()); throw new AgpException(agpError); } return jsoResponse; } /** * Executes a request expecting a JSON response. * @param url the URL * @param requestHeader optional request header properties * @param content the request body content * @param contentType the request body content type * @return the JSON response object * @throws Exception is an exception occurs */ public JSONObject executeJsonRequest(String url, AgpProperties requestHeader, StringBuilder content, String contentType) throws Exception { ContentProvider provider = null; if ((content != null) && (content.length() > 0)) { provider = new StringProvider(content.toString(),contentType); } return this.executeJsonRequest(url,requestHeader,provider); } /** * Executes a request. * @param url the URL * @param requestHeader optional request header properties * @param contentProvider the request body content provider * @param contentHandler the response body content handler * @throws Exception is an exception occurs */ public void executeRequest(String url, AgpProperties requestHeader, ContentProvider contentProvider, ContentHandler contentHandler) throws Exception { HttpClientRequest http = new HttpClientRequest(); http.setRetries(-1); http.setBatchHttpClient(this.batchHttpClient); http.setUrl(url); if (requestHeader != null) { for (AgpProperty prop: requestHeader.values()) { http.setRequestHeader(prop.getName(),prop.getValue()); } } http.setContentProvider(contentProvider); http.setContentHandler(contentHandler); try { http.execute(); } catch (HttpClientException ex) { boolean doThrow = true; if (ex.getHttpStatusCode()==302) { // This part of the code deals with redirect issue which accurs when // harvesting from arcgis.com Header hdrLocation = http.getResponseInfo().getResponseHeader("Location"); if (hdrLocation!=null) { String location = Val.chkStr(hdrLocation.getValue()); if (url.endsWith("/data") && location.contains("ago-item-storage")) { location = location.replaceAll("^https:", "http:"); doThrow = false; HttpClientRequest http2 = new HttpClientRequest(); http2.setUrl(location); http2.setRetries(-1); http2.setContentHandler(contentHandler); http2.execute(); } } } if (doThrow) { throw ex; } } } }