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

com.getperka.flatpack.client.impl.RequestBase Maven / Gradle / Ivy

There is a newer version: 2.21.0
Show newest version
/*
 * #%L
 * FlatPack Client
 * %%
 * Copyright (C) 2012 Perka Inc.
 * %%
 * Licensed 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.
 * #L%
 */
package com.getperka.flatpack.client.impl;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.getperka.flatpack.client.Request;
import com.getperka.flatpack.util.FlatPackCollections;

abstract class RequestBase, X> implements Request {
  private static final Pattern pathArgPattern = Pattern.compile("[{][^}]*[}]");
  private final ApiBase api;
  private final Object[] args;
  private Object entity;
  private Map headers = Collections.emptyMap();
  private final String method;
  private final String path;
  private Map queryParams = Collections.emptyMap();
  private final boolean hasPayload;

  protected RequestBase(ApiBase api, String method, String path, boolean hasPayload, Object... args) {
    this.api = api;
    this.args = args;
    this.method = method;
    this.path = path;
    this.hasPayload = hasPayload;
  }

  @Override
  public X execute() throws IOException {
    String replacedPath = path;

    // Replace all {foo} in the path with the args
    Matcher m = pathArgPattern.matcher(replacedPath);
    int index = 0;
    while (m.find() && index < args.length) {
      replacedPath = m.replaceFirst(args[index++].toString());
      m = pathArgPattern.matcher(replacedPath);
    }

    StringBuilder sb = new StringBuilder(replacedPath);
    // Now add query parameters
    if (!queryParams.isEmpty()) {
      sb.append("?");
      boolean needsAmp = false;
      for (Map.Entry entry : queryParams.entrySet()) {
        if (needsAmp) {
          sb.append("&");
        } else {
          needsAmp = true;
        }
        sb.append(entry.getKey()).append("=")
            .append(URLEncoder.encode(entry.getValue().toString(), "UTF8"));
      }
    }

    URI sendTo = api.getServerBase().resolve(sb.toString());

    HttpURLConnection conn = (HttpURLConnection) sendTo.toURL().openConnection();
    conn.setDoOutput(hasPayload);
    conn.setRequestMethod(method);
    for (Map.Entry entry : headers.entrySet()) {
      conn.setRequestProperty(entry.getKey(), entry.getValue().toString());
    }
    conn = api.filter(conn);
    writeEntity(conn);
    return execute(conn);
  }

  public Object getEntity() {
    return entity;
  }

  @Override
  public R header(String name, Object value) {
    if (headers.isEmpty()) {
      headers = FlatPackCollections.mapForIteration();
    }
    headers.put(name, value);
    return as();
  }

  @Override
  public R queryParameter(String name, Object value) {
    if (queryParams.isEmpty()) {
      queryParams = FlatPackCollections.mapForIteration();
    }
    queryParams.put(name, value);
    return as();
  }

  public void setEntity(Object entity) {
    this.entity = entity;
  }

  @SuppressWarnings("unchecked")
  protected R as() {
    return (R) this;
  }

  protected abstract X execute(HttpURLConnection response) throws IOException;

  protected ApiBase getApi() {
    return api;
  }

  /**
   * Returns {@code true} for a 2XX series response code.
   */
  protected boolean isOk(int statusCode) {
    return statusCode >= 200 && statusCode < 300;
  }

  protected abstract void writeEntity(HttpURLConnection connection) throws IOException;
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy