All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.qas.api.internal.util.Https Maven / Gradle / Ivy

The newest version!
package org.qas.api.internal.util;

import static org.qas.api.internal.util.google.base.Strings.nullToEmpty;
import static org.qas.api.net.UriEncoder.encode;

import org.qas.api.Request;
import org.qas.api.http.HttpMethod;
import org.qas.api.internal.util.google.base.Strings;
import org.qas.api.net.UriEncoder;
import org.qas.api.net.UrlEncoder;

import java.net.URI;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Map;

/**
 * Https
 *
 * @author Dzung Nguyen
 * @version $Id Https 2014-03-27 09:36:30z dungvnguyen $
 * @since 1.0
 */
public final class Https {
  //~ class properties ========================================================
  /**
   * header element format.
   */
  public static final String HEADER_ELEMENT_FORMAT = "%s=\"%s\"";

  /**
   * query string element format.
   */
  public static final String QUERY_STRING_ELEMENT_FORMAT = "%s=%s";

  //~ class members ===========================================================
  private Https() {
    throw new AssertionError("The Https utilities class must not be instantiated!");
  }

  /**
   * Returns {@code true} if the specified URI is using a non-standard port.
   *
   * @param uri the URI object to determine the default port.
   * @return {@code true} if the specified URI is using a non-standard port,
   * {@code false} otherwise.
   */
  public static boolean isUsingNonDefaultPort(URI uri) {
    String scheme = uri.getScheme().toLowerCase();
    int port = uri.getPort();

    if (port <= 0) return false;
    if (scheme.equals("http") && port == 80) return false;
    return !(scheme.equals("https") && port == 443);
  }

  public static String pathEncode(String resourcePath) {
    return encode(resourcePath).replace("%2F", "/");
  }

  /**
   * Returns {@code true} if the specified request has no payload and the POST method.
   *
   * @param request the {@link Request} to determine using payload for query parameter.
   * @return {@code true} if the request has no payload and using payload for query
   * parameter, {@code false} otherwise.
   */
  public static boolean usePayloadForQueryParameters(Request request) {
    return (HttpMethod.POST.equals(request.getHttpMethod()) || HttpMethod.PUT.equals(request.getHttpMethod()))
      && (request.getContent() == null);
  }

  /**
   * @param source source
   * @return the object representation as String.
   */
  public static String toSafeString(Object source) {
    return (source == null ? null : source.toString());
  }

  /**
   * Encodes the iterator as percent encode.
   *
   * @param iterator the given Iterator object to encode.
   * @return the percent encode of object.
   */
  public static String percentEncode(Iterator iterator) {
    if (iterator == null || !iterator.hasNext()) {
      return "";
    }

    final StringBuilder encode = new StringBuilder();
    encode.append(encode(nullToEmpty(toSafeString(iterator.next()))));

    while (iterator.hasNext()) {
      encode.append('&')
        .append(nullToEmpty(encode(toSafeString(iterator.next()))));
    }

    return encode.toString();
  }

  /**
   * Converts the parameter to query string parameter.
   *
   * @param parameters the given map of parameters.
   * @param encoding   the given encoding.
   * @return the query string.
   */
  public static String toQueryString(Map parameters, Charset encoding) {
    if (parameters == null || parameters.isEmpty()) return null;
    StringBuilder queryStringBuilder = new StringBuilder();

    for (Iterator> it = parameters.entrySet().iterator(); it.hasNext(); ) {
      Map.Entry entry = it.next();
      queryStringBuilder.append(UriEncoder.encode(entry.getKey(), encoding))
        .append("=");

      if (!Strings.isNullOrEmpty(entry.getValue())) {
        queryStringBuilder.append(UriEncoder.encode(entry.getValue(), encoding));
      }

      if (it.hasNext()) {
        queryStringBuilder.append("&");
      }
    }

    return queryStringBuilder.toString();
  }

  /**
   * Checks the given name is oauth parameter.
   *
   * @param name the given parameter name to check.
   * @return if the given name is oauth parameter name.
   */
  private static boolean isOauthParam(String name) {
    return (name != null && name.startsWith("oauth_"));
  }

  /**
   * Helper method to concatenate a parameter and its value to a pair that can
   * be used in an HTTP header. This method percent encodes both parts before
   * joining them.
   *
   * @param name  the OAuth parameter name, e.g. oauth_token
   * @param value the OAuth parameter value, e.g. 'hello oauth'
   * @return a name/value pair, e.g. oauth_token="hello%20oauth"
   */
  public static String toHeaderElement(String name, String value) {
    if (isOauthParam(name)) {
      return format(HEADER_ELEMENT_FORMAT,
        encode(nullToEmpty(name)),
        encode(nullToEmpty(value)));
    } else {
      return format(HEADER_ELEMENT_FORMAT,
        encode(nullToEmpty(name)),
        toSafeString(value));
    }
  }

  /**
   * Helper method to concatenate a parameter and its value to a pair that can
   * be used in an HTTP header. This method percent encodes both parts before
   * joining them.
   *
   * @param name  the OAuth parameter name, e.g. oauth_token
   * @param value the OAuth parameter value, e.g. 'hello oauth'
   * @return a name/value pair, e.g. oauth_token="hello%20oauth"
   */
  public static String toQueryElement(String name, String value) {
    return format(QUERY_STRING_ELEMENT_FORMAT,
      encode(nullToEmpty(name)),
      encode(nullToEmpty(value)));
  }

  /**
   * Substitutes each {@code %s} in {@code template} with an argument. These
   * are matched by position - the first {@code %s} gets {@code args[0]}, etc.
   * If there are more arguments than placeholders, the unmatched arguments will
   * be appended to the end of the formatted message in square braces.
   *
   * @param template a non-null string containing 0 or more {@code %s}
   *                 placeholders.
   * @param args     the arguments to be substituted into the message
   *                 template. Arguments are converted to strings using
   *                 {@link String#valueOf(Object)}. Arguments can be null.
   * @return string
   */
  public static String format(String template, Object... args) {
    // start substituting the arguments into the '%s' placeholders
    StringBuilder builder = new StringBuilder(
      template.length() + 16 * args.length);
    int templateStart = 0;
    int i = 0;
    while (i < args.length) {
      int placeholderStart = template.indexOf("%s", templateStart);
      if (placeholderStart == -1) {
        break;
      }
      builder.append(template.substring(templateStart, placeholderStart));
      builder.append(args[i++]);
      templateStart = placeholderStart + 2;
    }

    builder.append(template.substring(templateStart));

    // if we run out of placeholders, append the extra args in square braces
    if (i < args.length) {
      builder.append(" [");
      builder.append(args[i++]);
      while (i < args.length) {
        builder.append(", ");
        builder.append(args[i++]);
      }
      builder.append("]");
    }

    return builder.toString();
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy