Android Open Source - Android-API Request Engine






From Project

Back to project page Android-API.

License

The source code is released under:

Apache License

If you think the Android project Android-API listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.clearblade.platform.api.internal;
/* w w  w .  j a v  a2  s .  c  o m*/
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.security.cert.X509Certificate;

import com.clearblade.platform.api.ClearBlade;

import android.util.Log;

/**
 * This class consists of methods that configure and execute API Calls
 * <p>
 * This class is currently not thread safe.
 * A typical example of this classes usage:
 * <pre>
 *
 *RequestProperties headers = new RequestProperties.Builder().method("DELETE").endPoint("apidev/" + collection).qs(queryString).build();
 *  request.setHeaders(headers);
 *  
 *  ApiResponse<String> result = request.execute();
 *  // If there was an error log it,
 *  if(result.getError()) {  
 *    throw new Exception("Call to delete failed:"+result.getData());
 *  } else {
 *    this.json = convertJsonStringInToJsonObject(result.getData());
 *  }
 * </pre>
 * </p>
 * @author Clyde Byrd III
 * @author Aaron Allsbrook
 * @since 1.0
 * @see HttpURLConnection
 * @see PlatformResponse
 *
 */
public class RequestEngine {
  private final String TAG = "RequestEngine";
  
  //internal flag for understanding the use of SSL on the platform server
  private int isSSL = -1;
  
  private RequestProperties headers;
  
  /**
   * Constructs a RequestEngine Object with null RequestProperties object
   */
  public RequestEngine() {
    this.headers = null;
  }

  /**
   * Constructs a RequestEngine Object with given RequestProperties object
   * @param headers
   */
  public RequestEngine(RequestProperties headers) {
    this.headers = headers;
  }

  /**
   * Returns an ApiResponse<String> object that contains the 
   * results of the API call. The String in ApiResponse<String>.getData()
   * is usually converted to a more useful object.
   * @return result stores the condition of the ApiRequest
   */
  public PlatformResponse<String> execute() {
    return request();
  }
  
  /**
   * Returns an ApiResponse<String> object that contains the 
   * results of the API call. The String in ApiResponse<String>.getData()
   * is usually converted to a more useful object.
   * @return result stores the condition of the ApiRequest
   */
  public PlatformResponse<String> executeOnActivity() {
    return request();
  }
  
  /**
   * Returns the output from an InputStream
   * @param in inputStream to get data from
   * @return output A string gathered from the inputStream
   * @throws IOException
   */
  private String readStream(InputStream in) throws IOException {
    StringBuilder sb = new StringBuilder();  
    BufferedReader r = new BufferedReader(new InputStreamReader(in), 4096);  
    for (String line = r.readLine(); line != null; line =r.readLine()){  
      sb.append(line);  
    }  
    in.close();  
    return sb.toString();
  }

    
  /**
   * Sets the RequestEngine Object's headers to the given RequestProperties
   * object.
   * @param headers RequestProperties to make API Call from
   */
  public void setHeaders(RequestProperties headers) {
    this.headers = headers;
  }
  
  
  /**
   * Returns an ApiResponse<String> object that contains the 
   * results of the API call. The String in ApiResponse<String>.getData()
   * is usually converted to a more useful object.
   * @private
   * @return result stores the condition of the ApiRequest
   * @throws IllegalArguementExecption will be thrown if headers is null
   */
  private PlatformResponse<String> request(){
    if(this.headers == null){
      throw new IllegalArgumentException("The headers must not be null!");
    }
    
    HttpURLConnection urlConnection = null;
    // used to determine if error happened during call
    boolean err = false;

    // The two variables hold the server Status codes.
    int responseCode = 0;
    String responseMessage = null;

    PlatformResponse<String> result = null;
    SSLContext ctx=null;
    try {
      if (isSSL() && ClearBlade.getAllowUntrusted()) {
        ctx = createUntrustedManager(ctx);
        HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
      }
      String method = this.headers.getMethod();
      String charset = "UTF-8";
      URL url = new URL(this.headers.getUri());
      
      if (isSSL()){
        urlConnection = (HttpsURLConnection) url.openConnection();
        
      }else {
        urlConnection = (HttpURLConnection) url.openConnection();
        
      }
      
      urlConnection.setRequestMethod(method);
      urlConnection.setConnectTimeout(this.headers.getTimeout());

      //things get ugly here. most requests should just need usertoken, but you need key/secret
      // to get token on the auth request and to register new user. also both token and key/secret 
      // are needed for logout and auth check requests. so if the url cotains the logout or check 
      // endpoints, we add all 3, otherwise we add token
      String reqURL = this.headers.getUri().toLowerCase();
      boolean isLogoutOrAuthCheck = (reqURL.contains("/user/logout") ||
                      reqURL.contains("/user/checkauth"));
      boolean isAuthOrReg = (reqURL.contains("/user/auth") ||
                  reqURL.contains("/user/anon") ||
                  reqURL.contains("/user/reg"));
      String userToken = ClearBlade.getCurrentUser().getAuthToken();
      if(isLogoutOrAuthCheck){
        urlConnection.setRequestProperty("CLEARBLADE-SYSTEMKEY", Util.getSystemKey());
        urlConnection.setRequestProperty("CLEARBLADE-SYSTEMSECRET", Util.getSystemSecret());
        urlConnection.setRequestProperty("ClearBlade-UserToken", userToken);
      }else if(isAuthOrReg){
        urlConnection.setRequestProperty("CLEARBLADE-SYSTEMKEY", Util.getSystemKey());
        urlConnection.setRequestProperty("CLEARBLADE-SYSTEMSECRET", Util.getSystemSecret());
      }else if(userToken != null){
        urlConnection.setRequestProperty("ClearBlade-UserToken", userToken);
      }
      urlConnection.setRequestProperty("Accept", "application/json");
      urlConnection.setRequestProperty("Accept-Charset", charset);
      
      OutputStream output = null;

      if (method.equalsIgnoreCase("POST") || method.equalsIgnoreCase("PUT")) {
        urlConnection.setDoOutput(true);
        urlConnection.setFixedLengthStreamingMode(this.headers.getBody().length());
        //setDoOutput implicitly sets method to POST so re-set method for PUTs
        urlConnection.setRequestMethod(method);
        // Content-Type is necessary for POST and PUTS
        urlConnection.setRequestProperty("Content-Type", "application/json");
        
        output = urlConnection.getOutputStream();
        output.write(this.headers.getBody().getBytes(charset));
      }
      
      //TODO : what is the expense of getResponseCode(), getResponseMessage(), getInputStream()
      responseCode = urlConnection.getResponseCode();
      responseMessage = urlConnection.getResponseMessage();

      
      if(responseCode / 100 == 2) {  // If the response code is within 200 range success
        InputStream in = new BufferedInputStream(urlConnection.getInputStream());
        String json = readStream(in);
        result = new PlatformResponse<String>(err, json);
        Util.logger(TAG,method + " "+ responseCode + ":" + responseMessage, false);

      } else {  // else an Error Occurred 
        String errMessage;
        InputStream in = new BufferedInputStream(urlConnection.getErrorStream());
        errMessage = readStream(in);
        String errResp = responseCode + ":" + responseMessage + ":" + errMessage;
        Util.logger(TAG,errResp, true);
        err = true;
        result = new PlatformResponse<String>(err,errResp);
      }
    }catch(Exception e) {

      String caught = null;
      if(e instanceof MalformedURLException) {
        caught = "MalformedURLException: ";
      } else if (e instanceof UnsupportedEncodingException) {
        caught = "UnsupportedEncodingException: ";
      } else if (e instanceof ProtocolException) {
        caught = "ProtocolException: ";
      } else if (e instanceof IOException) {
        caught = "IOException: ";
      } else {
        caught = "Exception: ";
      }
      err = true;
      e.printStackTrace();
      result = new PlatformResponse<String>(err,"RequestEngine Caught " + caught + e.getMessage());
    }
    finally {
      // Make sure to close connection
      if (urlConnection!= null){
        urlConnection.disconnect();
      }
    }

    return result;


  }
  
  /**
   * Internal function to identify if the hosted platform is running under SSL
   * @return true if the platform uri contains https at the start
   */
  private boolean isSSL() {
    if (isSSL == -1) {
      if (this.headers.getUri().startsWith("https")){
        // if starts with https, then SSL is in use 
        isSSL = 1;  
      }else {
        isSSL=0;
      }
    }
    if (isSSL==1){
      return true;
    }
    return false;
  }
  
  /**
   * Internal function to hack around unsigned certificates on platform servers.  
   * @param ctx
   * @return SSLContext object that has a TrustManager that will accept all certificates
   * @throws KeyManagementException
   * @throws NoSuchAlgorithmException
   */
  private SSLContext createUntrustedManager(SSLContext ctx) throws KeyManagementException, NoSuchAlgorithmException{
    ctx = SSLContext.getInstance("SSL");
    ctx.init(null, new TrustManager[] {
      
         new X509TrustManager() {
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
              return null;
            }

      @Override
      public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType)
          throws CertificateException {
        System.out.println("AARON : checking for client trusted");
      }

      @Override
      public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType)
          throws CertificateException {
        System.out.println("AARON : checking for server trusted");
        
      }

         }
    }, new java.security.SecureRandom());
    return ctx;
  }

}




Java Source Code List

com.clearblade.platform.api.ClearBladeException.java
com.clearblade.platform.api.ClearBlade.java
com.clearblade.platform.api.CodeCallback.java
com.clearblade.platform.api.Code.java
com.clearblade.platform.api.Collection.java
com.clearblade.platform.api.DataCallback.java
com.clearblade.platform.api.HistoryItem.java
com.clearblade.platform.api.History.java
com.clearblade.platform.api.InitCallback.java
com.clearblade.platform.api.Item.java
com.clearblade.platform.api.MessageCallback.java
com.clearblade.platform.api.Message.java
com.clearblade.platform.api.QueryResponse.java
com.clearblade.platform.api.Query.java
com.clearblade.platform.api.User.java
com.clearblade.platform.api.internal.DataTask.java
com.clearblade.platform.api.internal.MessageMqttCallback.java
com.clearblade.platform.api.internal.MessageReceiver.java
com.clearblade.platform.api.internal.MessageService.java
com.clearblade.platform.api.internal.MessageTask.java
com.clearblade.platform.api.internal.PlatformCallback.java
com.clearblade.platform.api.internal.PlatformResponse.java
com.clearblade.platform.api.internal.RequestEngine.java
com.clearblade.platform.api.internal.RequestProperties.java
com.clearblade.platform.api.internal.UserTask.java
com.clearblade.platform.api.internal.Util.java