Package com.gistlabs.mechanize.requestor

Source Code of com.gistlabs.mechanize.requestor.RequestBuilder

/**
* Copyright (C) 2012-2014 Gist Labs, LLC. (http://gistlabs.com)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package com.gistlabs.mechanize.requestor;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.ContentBody;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.message.BasicNameValuePair;

import com.gistlabs.mechanize.exceptions.MechanizeExceptionFactory;
import com.gistlabs.mechanize.headers.Header;
import com.gistlabs.mechanize.headers.Headers;
import com.gistlabs.mechanize.parameters.Parameter;
import com.gistlabs.mechanize.parameters.Parameters;
import com.gistlabs.mechanize.util.apache.URIBuilder;
import com.gistlabs.mechanize.util.apache.URLEncodedUtils;

public class RequestBuilder<Resource> {
  private final PageRequestor<Resource> requestor;
  private String uri;
  private final Parameters parameters = new Parameters();
  private final Headers setHeaders = new Headers();
  private final Headers addHeaders = new Headers();
  private final Map<String, ContentBody> files = new HashMap<String, ContentBody>();
  private boolean isMultiPart = false;

  public RequestBuilder(final PageRequestor<Resource> requestor) {
    this.requestor = requestor;
  }

  public RequestBuilder(final PageRequestor<Resource> requestor, final String uri) {
    this(requestor);
    setUri(uri);
  }

  private void setUri(final String uri) {
    this.uri = uri;

    if(uri.contains("?"))
      for(NameValuePair param : URLEncodedUtils.parse(uri.substring(uri.indexOf('?') + 1), Charset.forName("UTF-8")))
        parameters.add(param.getName(), param.getValue());
  }

  public RequestBuilder<Resource> multiPart() {
    this.isMultiPart = true;
    return this;
  }

  public RequestBuilder<Resource> add(final String name, final String ... values) {
    parameters.add(name, values);
    return this;
  }

  public RequestBuilder<Resource> set(final String name, final String ... values) {
    parameters.set(name, values);
    return this;
  }

  public RequestBuilder<Resource> set(final Parameters parameters) {
    for(String name : parameters.getNames())
      set(name, parameters.get(name));

    return this;
  }

  public RequestBuilder<Resource> add(final Parameters parameters) {
    for(String name : parameters.getNames())
      add(name, parameters.get(name));

    return this;
  }

  public RequestBuilder<Resource> addHeader(final String name, final String ... values) {
    addHeaders.add(name, values);
    return this;
  }

  public RequestBuilder<Resource> setHeader(final String name, final String ... values) {
    setHeaders.set(name, values);
    return this;
  }

  public RequestBuilder<Resource> setHeaders(final Headers headers) {
    for(String name : headers.getNames())
      setHeader(name, headers.get(name));

    return this;
  }

  public RequestBuilder<Resource> addHeaders(final Headers headers) {
    for(String name :headers.getNames())
      addHeader(name, headers.get(name));

    return this;
  }

  public RequestBuilder<Resource> accept(final String contentType) {
    this.setHeader("Accept", contentType);
    return this;
  }

  /** Adds a file to the request also making the request to become a multi-part post request or removes any file registered
   *  under the given name if the file value is null. */
  public RequestBuilder<Resource> set(final String name, final File file) {
    return set(name, file != null ? new FileBody(file) : null);
  }

  /** Adds an ContentBody object. */
  public RequestBuilder<Resource> set(final String name, final ContentBody contentBody) {
    if(contentBody != null)
      files.put(name, contentBody);
    else
      files.remove(name);
    return this;
  }

  public Parameters parameters() {
    return parameters;
  }

  public <T extends Resource> T get() {
    if(hasFiles())
      throw new UnsupportedOperationException("Files can not be send using a get request");
    HttpRequestBase request = composeGetRequest(uri, parameters);
    buildHeaders(request);
    return requestor.request(request);
  }

  public <T extends Resource> T post() {
    //    HttpPost request = (!hasFiles()) || isMultiPart ? composePostRequest(getBaseUri(), parameters) :
    //      composeMultiPartFormRequest(getBaseUri(), parameters, files);
    HttpPost request = (hasFiles() || isMultiPart) ? composeMultiPartFormRequest(getBaseUri(), parameters, files) :
      composePostRequest(getBaseUri(), parameters);
    buildHeaders(request);
    return requestor.request(request);
  }

  private boolean hasFiles() {
    return !files.isEmpty();
  }

  private String getBaseUri() {
    return uri.contains("?") ? uri.substring(0, uri.indexOf('?')) : uri;
  }

  private void buildHeaders(final HttpRequestBase request) {
    for(Header header : this.setHeaders)
      for(String value : header)
        request.setHeader(header.getName(), value);
    for(Header header : this.addHeaders)
      for(String value : header)
        request.addHeader(header.getName(), value);
  }

  private HttpRequestBase composeGetRequest(String uri, final Parameters parameters) {
    try {
      URIBuilder builder = new URIBuilder(uri);

      for(Parameter param : parameters)
        if(param.isSingleValue())
          builder.setParameter(param.getName(), param.getValue());
        else
          for(String value : param.getValues())
            builder.addParameter(param.getName(), value);

      URI requestURI = builder.build();
      uri = requestURI.toString();
      return new HttpGet(requestURI);
    }
    catch(URISyntaxException e) {
      throw MechanizeExceptionFactory.newException(e);
    }
  }

  private HttpPost composePostRequest(final String uri, final Parameters parameters) {
    HttpPost request = new HttpPost(uri);
    List<NameValuePair> formparams = new ArrayList<NameValuePair>();
    for(Parameter param : parameters)
      if(param.isSingleValue())
        formparams.add(new BasicNameValuePair(param.getName(), param.getValue()));
      else
        for(String value : param.getValues())
          formparams.add(new BasicNameValuePair(param.getName(), value));
    try {
      UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, "UTF-8");
      request.setEntity(entity);
    } catch (UnsupportedEncodingException e) {
      throw MechanizeExceptionFactory.newException(e);
    }

    return request;
  }

  private HttpPost composeMultiPartFormRequest(final String uri, final Parameters parameters, final Map<String, ContentBody> files) {
    HttpPost request = new HttpPost(uri);
    MultipartEntity multiPartEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);

    try {
      Charset utf8 = Charset.forName("UTF-8");
      for(Parameter param : parameters)
        if(param.isSingleValue())
          multiPartEntity.addPart(param.getName(), new StringBody(param.getValue(), utf8));
        else
          for(String value : param.getValues())
            multiPartEntity.addPart(param.getName(), new StringBody(value, utf8));
    } catch (UnsupportedEncodingException e) {
      throw MechanizeExceptionFactory.newException(e);
    }

    List<String> fileNames = new ArrayList<String>(files.keySet());
    Collections.sort(fileNames);
    for(String name : fileNames) {
      ContentBody contentBody = files.get(name);
      multiPartEntity.addPart(name, contentBody);
    }
    request.setEntity(multiPartEntity);
    return request;
  }
}
TOP

Related Classes of com.gistlabs.mechanize.requestor.RequestBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.