Package com.googlecode.gwt.test.rpc

Source Code of com.googlecode.gwt.test.rpc.RemoteServiceCreateHandler$DefaultGwtRpcExceptionHandler

package com.googlecode.gwt.test.rpc;

import java.lang.reflect.Proxy;

import javassist.CtClass;
import javassist.bytecode.annotation.AnnotationImpl;
import javassist.bytecode.annotation.StringMemberValue;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
import com.googlecode.gwt.test.GwtCreateHandler;
import com.googlecode.gwt.test.exceptions.GwtTestRpcException;
import com.googlecode.gwt.test.internal.GwtClassPool;
import com.googlecode.gwt.test.utils.GwtReflectionUtils;

/**
* <p>
* The {@link GwtCreateHandler} class used to create {@link RemoteService} sub-interface instances.
* It returns an asynchrone proxy of the service and handles the simulation of GWT-RPC serialization
* through a {@link GwtRpcInvocationHandler} and the exception management through a
* {@link GwtRpcExceptionHandler}.
* </p>
*
* <p>
* Before delegating the remote service object instantiation to the abstract
* {@link RemoteServiceCreateHandler#findService(Class, String)} method, this class ensure that a
* corresponding async interface is available for the RemoteService subinterface to create.
* </p>
*
* @author Bertrand Paquet
* @author Gael Lazzari
*
*/
public abstract class RemoteServiceCreateHandler implements GwtCreateHandler {

   private class DefaultGwtRpcExceptionHandler implements GwtRpcExceptionHandler {

      public void handle(Throwable t, AsyncCallback<?> callback) {
         callback.onFailure(t);
      }

   }
   private class DefaultGwtRpcSerializerHandler implements GwtRpcSerializerHandler {

      public <T> T serializeUnserialize(T o) throws Exception {
         return DeepCopy.copy(o);
      }

   }

   private static final Logger logger = LoggerFactory.getLogger(RemoteServiceCreateHandler.class);

   private final GwtRpcExceptionHandler exceptionHandler;
   private final GwtRpcSerializerHandler serializerHander;

   public RemoteServiceCreateHandler() {
      exceptionHandler = getExceptionHandler();
      serializerHander = getSerializerHandler();
   }

   public Object create(Class<?> classLiteral) throws Exception {

      if (!RemoteService.class.isAssignableFrom(classLiteral)) {
         return null;
      }

      String className = classLiteral.getName();
      logger.debug("Try to create Remote service class " + className);

      String asyncName = className + "Async";
      String relativePath = getRemoveServiceRelativePath(classLiteral);
      Class<?> asyncClazz = GwtReflectionUtils.getClass(asyncName);
      if (asyncClazz == null) {
         throw new GwtTestRpcException("Remote serivce Async class not found : " + asyncName);
      }
      logger.debug("Searching remote service implementing " + className);

      // try to find
      Object service = findService(classLiteral, relativePath);

      if (service == null) {
         return null;
      }

      GwtRpcInvocationHandler handler = new GwtRpcInvocationHandler(asyncClazz, service,
               exceptionHandler, serializerHander);

      return Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{asyncClazz}, handler);
   }

   /**
    * Method which actually is responsible for getting the {@link RemoteService} sub-interface
    * implementation.
    *
    * @param remoteServiceClass {@link RemoteService} sub-interface to get an implementation.
    * @param remoteServiceRelativePath the associated relative path, which is provided in
    *           {@link RemoteServiceRelativePath} annotation.
    * @return The corresponding remote service implementation.
    */
   protected abstract Object findService(Class<?> remoteServiceClass,
            String remoteServiceRelativePath);

   /**
    * Specify the handler to use to handle GWT-RPC errors.
    *
    * @return The handler to use to handle GWT-RPC errors.
    */
   protected GwtRpcExceptionHandler getExceptionHandler() {
      return new DefaultGwtRpcExceptionHandler();
   }

   /**
    * Specify the handler to use to simulate the GWT-RPC serialization
    *
    * @return The handler to use to simulate the GWT-RPC serialization.
    */
   protected GwtRpcSerializerHandler getSerializerHandler() {
      return new DefaultGwtRpcSerializerHandler();
   }

   private String getRemoveServiceRelativePath(Class<?> clazz) {
      CtClass ctClass = GwtClassPool.getCtClass((clazz));
      Object[] annotations = ctClass.getAvailableAnnotations();
      for (Object o : annotations) {
         if (Proxy.isProxyClass(o.getClass())) {
            AnnotationImpl annotation = (AnnotationImpl) Proxy.getInvocationHandler(o);
            if (annotation.getTypeName().equals(RemoteServiceRelativePath.class.getName())) {
               return ((StringMemberValue) annotation.getAnnotation().getMemberValue("value")).getValue();
            }
         }
      }
      throw new GwtTestRpcException("Cannot find the '@"
               + RemoteServiceRelativePath.class.getSimpleName()
               + "' annotation on RemoteService interface '" + clazz.getName() + "'");
   }

}
TOP

Related Classes of com.googlecode.gwt.test.rpc.RemoteServiceCreateHandler$DefaultGwtRpcExceptionHandler

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.