gt:         return submitRequest(req, rq);
context: /*
   * #%L
   * Alfresco Remote API
   * %%
   * Copyright (C) 2005 - 2016 Alfresco Software Limited
   * %%
   * This file is part of the Alfresco software. 
   * If the software was purchased under a paid Alfresco license, the terms of 
   * the paid license agreement will prevail.  Otherwise, the software is 
   * provided under the following open source license terms:
   * 
   * Alfresco is free software: you can redistribute it and/or modify
   * it under the terms of the GNU Lesser General Public License as published by
   * the Free Software Foundation, either version 3 of the License, or
   * (at your option) any later version.
   * 
   * Alfresco is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU Lesser General Public License for more details.
   * 
   * You should have received a copy of the GNU Lesser General Public License
   * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
   * #L%
   */
  package org.alfresco.rest.api.tests.client;
  
  import java.io.BufferedInputStream;
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.OutputStream;
  import java.io.UnsupportedEncodingException;
  import java.net.URLEncoder;
  import java.text.MessageFormat;
  import java.util.HashMap;
  import java.util.Map;
  import java.util.Map.Entry;
  
  import org.alfresco.error.AlfrescoRuntimeException;
  import org.alfresco.opencmis.CMISDispatcherRegistry.Binding;
  import org.alfresco.repo.tenant.TenantService;
  import org.alfresco.repo.tenant.TenantUtil;
  import org.alfresco.repo.web.scripts.BaseWebScriptTest.PatchMethod;
  import org.alfresco.rest.api.tests.client.AuthenticatedHttp.HttpRequestCallback;
  import org.alfresco.rest.framework.Api;
  import org.alfresco.rest.framework.Api.SCOPE;
  import org.alfresco.rest.framework.core.ResourceInspector;
  import org.alfresco.rest.framework.resource.EntityResource;
  import org.alfresco.rest.framework.resource.RelationshipResource;
  import org.alfresco.service.cmr.repository.NodeRef;
  import org.alfresco.util.Pair;
  import org.apache.commons.httpclient.Header;
  import org.apache.commons.httpclient.HttpException;
  import org.apache.commons.httpclient.HttpMethod;
  import org.apache.commons.httpclient.HttpMethodBase;
  import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
  import org.apache.commons.httpclient.methods.DeleteMethod;
  import org.apache.commons.httpclient.methods.GetMethod;
  import org.apache.commons.httpclient.methods.HeadMethod;
  import org.apache.commons.httpclient.methods.OptionsMethod;
  import org.apache.commons.httpclient.methods.PostMethod;
  import org.apache.commons.httpclient.methods.PutMethod;
  import org.apache.commons.httpclient.methods.RequestEntity;
  import org.apache.commons.httpclient.methods.StringRequestEntity;
  import org.apache.commons.httpclient.methods.TraceMethod;
  import org.apache.commons.lang.StringUtils;
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
  import org.springframework.core.io.support.ResourcePatternResolver;
  import org.springframework.core.type.AnnotationMetadata;
  import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
  import org.springframework.core.type.classreading.MetadataReader;
  import org.springframework.core.type.classreading.MetadataReaderFactory;
  
  /**
   * A http client for talking to the rest apis. The caller can pass in a rest api
   * implementation class to the http method (get, post, put, delete supported)
   * and the url will be generated.
   *
   * @author steveglover
   */
  public class PublicApiHttpClient
  {
      private static final Log logger = LogFactory.getLog(PublicApiHttpClient.class);
  
      private static final String OLD_BASE_URL = "{0}://{1}:{2}{3}{4}{5}/api/";
      private static final String INDEX_URL = "{0}://{1}:{2}{3}{4}";
      private static final String BASE_URL = "{0}://{1}:{2}{3}{4}{5}/{6}/{7}/versions/{8}";
      private static final String PUBLICAPI_CMIS_SERVICE_URL = "{0}://{1}:{2}{3}{4}cmis/versions/{5}/{6}";
      private static final String PUBLICAPI_CMIS_URL = "{0}://{1}:{2}{3}{4}{5}/{6}/cmis/versions/{7}/{8}";
      private static final String PUBLICAPI_CMIS_URL_SUFFIX = "{0}/{1}/cmis/versions/{2}/{3}";
      private static final String ATOM_PUB_URL = "{0}://{1}:{2}{3}cmisatom";
  
      private String scheme = "http";
      private String host = "localhost";
      private int port = 8081;
  
      private String contextPath;
      private String servletName;
      private AuthenticatedHttp authenticatedHttp;
  
      private ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
      private MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(this.resourcePatternResolver);
  
      // can be overriden by other clients like the workflow client
      protected String apiName = "alfresco";
  
      public PublicApiHttpClient(String host, int port, String contextPath, String servletName, AuthenticatedHttp authenticatedHttp)
      {
          this("http", host, port, contextPath, servletName, authenticatedHttp);
      }
  
      public PublicApiHttpClient(String scheme, String host, int port, String contextPath, String servletName, AuthenticatedHttp authenticatedHttp)
      {
          super();
          this.scheme = scheme;
          this.host = host;
          this.port = port;
          this.contextPath = contextPath;
          if (this.contextPath != null && !this.contextPath.isEmpty() && !this.contextPath.endsWith("/"))
          {
              this.contextPath = this.contextPath + "/";
          }
          if (this.contextPath != null && !this.contextPath.startsWith("/"))
          {
              this.contextPath = "/" + this.contextPath;
          }
          this.servletName = servletName;
          if (this.servletName != null && !this.servletName.isEmpty() && !this.servletName.endsWith("/"))
          {
              this.servletName = this.servletName + "/";
          }
          this.authenticatedHttp = authenticatedHttp;
      }
  
      public String getCmisUrl(String repositoryId, String operation)
      {
          StringBuilder url = new StringBuilder();
          if (repositoryId == null)
          {
              url.append(MessageFormat.format(ATOM_PUB_URL, new Object[] { scheme, host, String.valueOf(port), contextPath }));
          }
          else
          {
              url.append(MessageFormat.format(ATOM_PUB_URL, new Object[] { scheme, host, String.valueOf(port), contextPath }));
              url.append("/");
              url.append(repositoryId);
          }
  
          if (operation != null)
          {
              url.append("/");
              url.append(operation);
          }
  
          return url.toString();
      }
  
      public String getPublicApiCmisUrl(String networkId, Binding binding, String version, String operation)
      {
          StringBuilder url = new StringBuilder();
          if (networkId == null)
          {
              url.append(MessageFormat.format(PUBLICAPI_CMIS_SERVICE_URL,
                          new Object[] { scheme, host, String.valueOf(port), contextPath, servletName, version, binding.toString().toLowerCase() }));
          }
          else
          {
              url.append(MessageFormat.format(PUBLICAPI_CMIS_URL, new Object[] { scheme, host, String.valueOf(port), contextPath, servletName,
                          networkId, "public", version, binding.toString().toLowerCase() }));
          }
  
          if (operation != null)
          {
              url.append("/");
              url.append(operation);
          }
  
          return url.toString();
      }
  
      public String getPublicApiCmisUrlSuffix(String networkId, Binding binding, String version, String operation)
      {
          StringBuilder url = new StringBuilder();
  
          url.append(MessageFormat.format(PUBLICAPI_CMIS_URL_SUFFIX, new Object[] { networkId, "public", version, binding.toString().toLowerCase() }));
  
          if (operation != null)
          {
              url.append("/");
              url.append(operation);
          }
  
          return url.toString();
      }
  
      public void setHost(String host)
      {
          this.host = host;
      }
  
      public void setPort(int port)
      {
          this.port = port;
      }
  
      public void setContextPath(String contextPath)
      {
          this.contextPath = contextPath;
      }
  
      public void init()
      {
      }
  
      private void log(String msg)
      {
          if (logger.isDebugEnabled())
          {
              logger.debug(msg);
          }
      }
  
      protected AnnotationMetadata getAnnotationMetadata(String classname) throws IOException
      {
          MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(classname);
          AnnotationMetadata annotationMetaData = metadataReader.getAnnotationMetadata();
          return annotationMetaData;
      }
  
      public HttpResponse submitRequest(HttpMethod req, final RequestContext rq) throws HttpException, IOException
      {
          try
          {
              final long start = System.currentTimeMillis();
  
              final HttpRequestCallback<HttpResponse> callback = new HttpRequestCallback<HttpResponse>()
              {
                  @Override
                  public HttpResponse onCallSuccess(HttpMethod method) throws Exception
                  {
                      long end = System.currentTimeMillis();
  
                      Map<String, String> headersMap = null;
                      Header[] headers = method.getResponseHeaders();
                      if (headers != null)
                      {
                          headersMap = new HashMap<String, String>(headers.length);
                          for (Header header : headers)
                          {
                              headersMap.put(header.getName(), header.getValue());
                          }
                      }
  
                      return new HttpResponse(method, rq.getRunAsUser(), method.getResponseBody(), headersMap, (end - start));
                  }
  
                  @Override
                  public boolean onError(HttpMethod method, Throwable t)
                  {
                      return false;
                  }
              };
  
              HttpResponse response = null;
              if (rq.getPassword() != null)
              {
                  response = authenticatedHttp.executeHttpMethodAuthenticated(req, rq.getRunAsUser(), rq.getPassword(), callback);
              }
              else
              {
                  response = authenticatedHttp.executeHttpMethodAuthenticated(req, rq.getRunAsUser(), callback);
              }
              return response;
          }
          finally
          {
              if (req != null)
              {
                  req.releaseConnection();
              }
          }
      }
  
      public HttpResponse get(final RequestContext rq, final String urlSuffix, Map<String, String> params) throws IOException
      {
          RestApiEndpoint endpoint = new RestApiEndpoint(rq.getNetworkId(), urlSuffix, params);
          String url = endpoint.getUrl();
  
          GetMethod req = new GetMethod(url);
  