Package com.googlecode.gwtrpccommlayer.client.impl

Source Code of com.googlecode.gwtrpccommlayer.client.impl.ProxyImpl$AsynchCallBackRunnable

package com.googlecode.gwtrpccommlayer.client.impl;

import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.googlecode.gwtrpccommlayer.client.function.ResponseSerializer;
import com.googlecode.gwtrpccommlayer.shared.GwtRpcCommLayerPojoConstants;
import com.googlecode.gwtrpccommlayer.shared.GwtRpcCommLayerPojoRequest;
import com.googlecode.gwtrpccommlayer.shared.GwtRpcCommLayerPojoResponse;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.cookie.Cookie;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.impl.client.DefaultHttpClient;

import javax.xml.ws.Response;
import java.io.*;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;

/**
* Created by IntelliJ IDEA.
* User: dan
* Date: 10/30/10
* Time: 10:04 PM
*/
public class ProxyImpl implements IGwtRpcClientSideProxy{

  static int DEFAULT_STANDARD_PORT   = 80;
  static int DEFAULT_SECURE_PORT     = 443;

  private HashMap<String,Cookie> cookies = null;


  private boolean showResponseHeaders = false;
    private final ResponseSerializer responseSerializer;
    private URL url;

    @Inject
    public ProxyImpl(ResponseSerializer responseSerializer, URL url, @Assisted HashMap<String,Cookie> cookies) {
        this.responseSerializer = responseSerializer;
        this.url = url;
        this.cookies = cookies;
    }

  boolean doesListIncludeGwtAsynchCallback(Class[] interfaces)
  {
    Class target = AsyncCallback.class;
    for (Class intf : interfaces)
    {
      if ( intf.getName().equals(target.getName()))
      {
        return true;
      }
    }
    return false;
  }

  Object invoke_asynchronousMode(Object proxy, Method method, Object[] args) throws Throwable
  {
    if ( args.length == 0 )
    {
      throw new RuntimeException("A minimum of (1) object is required for asynchronous mode");
    }

    AsyncCallback theCallback = (AsyncCallback) args[args.length-1];

    /*
     * Wrap the Method (and Method arguments)
     */
    GwtRpcCommLayerPojoRequest pojoRequest = new GwtRpcCommLayerPojoRequest();

    pojoRequest.setMethodName(method.getName());
    if ( args != null )
    {

      for (Object object : args)
      {
        if ( object != theCallback )//the last object is always going to be the callback implementation
        {
          pojoRequest.getMethodParameters().add( (Serializable) object);
        }
      }
    }

    /*
     * This block now makes it possible to execute in a "asynchronous" mode
     */

    GwtRpcCommLayerPojoResponse pojoResp = null;
    try
    {
      pojoResp = executeRequest(pojoRequest);
      if ( pojoResp != null )
      {
        Object result = pojoResp.getResponseInstance();
        AsynchCallBackRunnable runnable = new AsynchCallBackRunnable(theCallback, result);
        Thread thread = new Thread(runnable);
        thread.start();
        return null;
      }
      else
      {
        throw new RuntimeException("No valid GwtRpcCommLayerPojoResponse returned. Check for http errors in log.");
      }
    }
    catch(Throwable caught)
    {
      AsynchCallBackRunnable runnable = new AsynchCallBackRunnable(theCallback, caught);
      Thread thread = new Thread(runnable);
      thread.start();
      return null;
    }
  }

  Object invoke_synchronousMode(Object proxy, Method method, Object[] args) throws Throwable
  {
    /*
     * Wrap the Method (and Method arguments)
     */
    GwtRpcCommLayerPojoRequest pojoRequest = new GwtRpcCommLayerPojoRequest();

    pojoRequest.setMethodName(method.getName());
    if ( args != null )
    {
      for (Object object : args)
      {
        //pojoRequest.getMethodParameters().add( (Serializable) object);
                pojoRequest.getMethodParameters().add( object.getClass());
      }
    }


    /*
     * This is the original block of code that executed for the "synchronous" mode
     */
    GwtRpcCommLayerPojoResponse pojoResp = executeRequest(pojoRequest);
    if ( pojoResp != null )
    {
      return pojoResp.getResponseInstance();
    }
    else
    {
      throw new RuntimeException("No valid GwtRpcCommLayerPojoResponse returned. Check for http errors in log.");
    }


  }

  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
  {
    int mode = 0;//default to synchronous mode

    if ( args != null && args.length > 0 )
    {
      Object last = args[args.length-1];
      if ( doesListIncludeGwtAsynchCallback(last.getClass().getInterfaces()))
      {
        mode = 1;
      }
    }

    if ( mode == 0 )
    {
      return invoke_synchronousMode(proxy, method, args);
    }
    else
    {
      return invoke_asynchronousMode(proxy, method, args);
    }
  }

  /**
   * The URL that this client shall interact with
   */
  public void setUrl(URL url)
  {

  }

  /**
   * Set this to true for debugging
   */
  public void setShowResponseHeaders(boolean b)
  {
    this.showResponseHeaders = b;
  }

  /**
   * Main method that executes to make call to remote server
   * this method uses an HTTP POST method and can keep state if needed (using cookies)
   * @throws IOException
   */
  protected synchronized GwtRpcCommLayerPojoResponse executeRequest(GwtRpcCommLayerPojoRequest pojoRequest) throws IOException
  {
    /*
     * Create HTTP CLIENT
     */
    DefaultHttpClient httpclient = new DefaultHttpClient();

    /*
     * Add Cookies to the request
     * this enables a state-full set of transactions
     * to take place. While this is NOT required for the
     * GwtRpcCommLayer framework, the actually developer might have this
     * requirement embedded into his/her servlet(s) and thus
     * this makes to possible to communicate just like
     * a browser would
     *
     */
    if ( getCookies().size() > 0 )
    {
      for (Cookie cookie : getCookies().values())
      {
        httpclient.getCookieStore().addCookie(cookie);
      }
    }


    /*
     * SERIALZED THE POJO-REQUEST OBJECT INTO BYTES
     */
    byte[] pojoByteArray = serializeIntoBytes(pojoRequest);
    long length = pojoByteArray.length;
        ByteArrayInputStream in = new ByteArrayInputStream(pojoByteArray);
        InputStreamEntity reqEntity = new InputStreamEntity(in, length);
        reqEntity.setContentType("binary/octet-stream");
        reqEntity.setChunked(false);


    /*
     * CONSTRUCT THE URL
     */
    String url = createFullyQualifiedURL();

    /*
     * Create POST instance
     */
    HttpPost httppost = new HttpPost(url);
    httppost.setEntity(reqEntity);

    /*
     * Add the correct user-agent
     */
        httppost.addHeader(GwtRpcCommLayerPojoConstants.GWT_RPC_COMM_LAYER_CLIENT_KEY, GwtRpcCommLayerPojoConstants.GWT_RPC_COMM_LAYER_POJO_CLIENT);

    /*
     * Notify any last minute listener
     */
        onBeforeRequest(httppost);
        HttpResponse response = httpclient.execute(httppost);
        //return

        /*
         * Provide a call back for timing, error handling, etc
         */
        onAfterRequest(httppost, response);

        /*
         * Check for server error
         */
        if ( response.getStatusLine().getStatusCode() >= 400 && response.getStatusLine().getStatusCode() <= 599 )
        {
          onResponseError(response.getStatusLine().getStatusCode(), response);
          return null;
        }
        else if (response.getFirstHeader("Content-Type") != null && !response.getFirstHeader("Content-Type").getValue().equals("binary/octet-stream"))
        {
          onResponseError("Content-Type must be 'binary/octet-stream'");
          return null;
        }
        else
        {
          /*
           * Provide a call-back for examining the response headers
           */
          if ( isShowResponseHeaders() && response.getAllHeaders() != null )
          {
            dumpResponseHeaders(response.getAllHeaders());
          }

          /*
           * Provide a call-back for examining the response cookies
           */
          List<Cookie> cookies = httpclient.getCookieStore().getCookies();
          if ( cookies != null )
          {
            recordCookies(cookies);
          }


          HttpEntity resEntity = response.getEntity();
          byte[] respData = deserializeIntoBytes(resEntity);
          try
          {
            GwtRpcCommLayerPojoResponse pojoResp = createInstanceFromBytes(respData);
            return pojoResp;
          }
          catch(ClassNotFoundException e)
          {
            throw new IOException(e);
          }

        }

  }

  /*
   * ---------------- METHODS THAT CAN BE EXTENDED BY SUB-CLASSES -------------
   */

  protected String createFullyQualifiedURL()
  {
    /*
     * Configure the URL and PATH
     */
    StringBuffer buff = new StringBuffer();
        buff.append(url.getProtocol());
    buff.append("://");
    buff.append(url.getHost());
    if ( url.getPort() != DEFAULT_STANDARD_PORT && url.getPort() != DEFAULT_SECURE_PORT )
    {
      buff.append(":"+url.getPort());
    }
    buff.append(url.getPath());
    if ( url.getQuery() != null )
    {
      buff.append("?");
      buff.append(url.getQuery());
    }
    return buff.toString();
  }

  protected byte[] serializeIntoBytes(GwtRpcCommLayerPojoRequest pojoRequest) throws IOException
  {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream objOut = new ObjectOutputStream(bos);
        objOut.writeObject(pojoRequest);
        objOut.flush();
        objOut.close();

        byte[] all = bos.toByteArray();
        return all;
  }

  protected byte[] deserializeIntoBytes(HttpEntity respEntity ) throws IOException
  {
      byte[] b = new byte[512];
      ByteArrayOutputStream buff = new ByteArrayOutputStream();
      InputStream respIn = respEntity.getContent();
      while(true)
      {
        int vv = respIn.read(b);
        if ( vv == -1 )
        {
          break;
        }
        buff.write(b, 0, vv);
      }
      return buff.toByteArray();
  }

  protected GwtRpcCommLayerPojoResponse createInstanceFromBytes(byte[] data) throws IOException, ClassNotFoundException
  {
      ObjectInputStream objIn = new ObjectInputStream(new ByteArrayInputStream(data));
      Object instance = objIn.readObject();
      GwtRpcCommLayerPojoResponse pojoResp = (GwtRpcCommLayerPojoResponse) instance;

      return pojoResp;
  }

  protected void recordCookies(List<Cookie> cookies)
  {
     for (Cookie cookie : cookies)
         {
           getCookies().put(cookie.getName(), cookie);
     }
  }

  protected void dumpResponseHeaders(Header header[])
  {
      for (Header header2 : header)
      {
        System.out.println("" + header2.getName() + ":" + header2.getValue() );
    }
  }

  /**
   * Provides a call-back for future functionality. Will get called before the actual HTTP Request is executed
   * @param httppost
   */
  protected void onBeforeRequest(HttpPost httppost)
  {
  }

  /**
   * Provides a call-back for future functionality. Will get called after the response is returned
   * @param httppost
   * @param response
   */
  protected void onAfterRequest(HttpPost httppost, HttpResponse response)
  {
  }

  /**
   * Called in the event of an HTTP Response Error (400 through 599)
   * @param errorCode
   * @param response
   */
  protected void onResponseError(int errorCode, HttpResponse response)
  {
    System.out.println("HTTP_ERROR code=" + errorCode + " " + response.getStatusLine().getReasonPhrase() );
  }

  /**
   * Called in the event of an general error outside of the http protocol
   * @param errorCode
   * @param response
   */
  protected void onResponseError(String error)
  {
    System.out.println("Response Error=" + error);
  }











  /*
   * ---------------------------- GETTER/SETTER METHODS ---------------------------
   */

  /**
   * @param cookies the cookies to set
   */
  public void setCookies(HashMap<String,Cookie> cookies)
  {
    this.cookies = cookies;
  }

  /**
   * @return the cookies
   */
  public HashMap<String,Cookie> getCookies()
  {
    return cookies;
  }




   /**
    * @return the showResponseHeaders
    */
   boolean isShowResponseHeaders()
   {
       return showResponseHeaders;
   }


   /*
    * This class is for use with the asynchronous mode
    */
   static class AsynchCallBackRunnable<T> implements Runnable
   {

       AsyncCallback<T> callback;
       Throwable caughtThrowable;
       T result;

       public AsynchCallBackRunnable(AsyncCallback<T> callback, T result)
       {
           this.callback = callback;
           this.result = result;
       }

       public AsynchCallBackRunnable(AsyncCallback<T> callback, Throwable caughtThrowable)
       {
           this.callback = callback;
           this.caughtThrowable = caughtThrowable;
       }

       public void run()
       {
           try
           {
               if ( this.result != null )
               {
                   this.callback.onSuccess(this.result);
               }
               else if ( this.caughtThrowable != null )
               {
                   this.callback.onFailure(this.caughtThrowable);
               }
               else
               {
                   throw new RuntimeException("Both 'success' and 'failure' payload objects are null. This should never occur.");
               }
           }
           catch(Throwable caught)
           {
               System.err.println("Failure in Asynch dispatch thread. " + caught.toString() );
               caught.printStackTrace();
           }
       }

   }

  public void pushCookies(Collection<Cookie> cookies) {
    if(cookies != null) {
      for(Cookie cookie : cookies) {
        this.cookies.put(cookie.getName(), cookie);
      }
    }
  }

}
TOP

Related Classes of com.googlecode.gwtrpccommlayer.client.impl.ProxyImpl$AsynchCallBackRunnable

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.