Package com.googlecode.gwt.test.gin

Source Code of com.googlecode.gwt.test.gin.GInjectorCreateHandler

package com.googlecode.gwt.test.gin;

import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

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

import com.google.gwt.core.client.GWT;
import com.google.gwt.inject.client.GinModule;
import com.google.gwt.inject.client.GinModules;
import com.google.gwt.inject.client.Ginjector;
import com.google.gwt.inject.rebind.GinjectorBindings;
import com.google.gwt.inject.rebind.adapter.GinModuleAdapter;
import com.google.gwt.inject.rebind.util.GuiceUtil;
import com.google.gwt.inject.rebind.util.MemberCollector;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.googlecode.gwt.test.GwtCreateHandler;
import com.googlecode.gwt.test.GwtTreeLogger;

/**
* Handle {@link GWT#create(Class)} for {@link Ginjector}.
*
* @author Alex Dobjanschi
* @author Gael Lazzari
*
*/
public class GInjectorCreateHandler implements GwtCreateHandler {

   private static final Logger LOGGER = LoggerFactory.getLogger(GInjectorCreateHandler.class);

   // map used as cache to store bindings between gin and guice proxy injectors
   private Map<Class<? extends Ginjector>, Object> injectors;

   public Object create(Class<?> classLiteral) throws Exception {
      // Make sure this is a Ginjector
      if (!Ginjector.class.isAssignableFrom(classLiteral)) {
         return null;
      }

      @SuppressWarnings("unchecked")
      Class<? extends Ginjector> ginjectorClass = (Class<? extends Ginjector>) classLiteral;

      if (injectors == null) {
         injectors = new HashMap<Class<? extends Ginjector>, Object>();
      }

      Object guiceInjectorProxy = injectors.get(classLiteral);

      if (guiceInjectorProxy != null) {
         LOGGER.debug("Proxy for class '" + ginjectorClass.getName()
                  + "'has been found in cache. It is returned");
         return guiceInjectorProxy;
      }

      Class<? extends GinModule>[] ginModules = readGinModules(ginjectorClass);

      // create a set of Guice Module bases on the GinModules
      Set<Module> guiceModules = readGuiceModules(ginModules, ginjectorClass);

      // Use Guice SPI to solve deferred binding dependencies
      DeferredBindingModule deferredBindingModule = DeferredBindingModule.getDeferredBindingModule(
               ginjectorClass, guiceModules);
      guiceModules.add(deferredBindingModule);

      // Instantiate an injector, based on the modules read above + the
      // deferredBindingModule
      Injector injector = Guice.createInjector(guiceModules);

      LOGGER.debug("creating new Proxy for class '" + ginjectorClass.getName() + "'");

      guiceInjectorProxy = Proxy.newProxyInstance(this.getClass().getClassLoader(),
               new Class[]{ginjectorClass}, new GinInjectorInvocationHandler(injector));

      injectors.put(ginjectorClass, guiceInjectorProxy);

      return guiceInjectorProxy;
   }

   private Class<? extends GinModule>[] readGinModules(Class<? extends Ginjector> classLiteral) {
      LOGGER.debug("inspecting classLiteral " + classLiteral);
      GinModules annotation = classLiteral.getAnnotation(GinModules.class);
      if (annotation == null) {
         // Throw an exception if we don't find this specific annotation.
         throw new IllegalArgumentException(classLiteral.getName()
                  + " doesn't have any @GinModules annotation present");
      }

      Class<? extends GinModule>[] ginModules = annotation.value();

      if (ginModules == null || ginModules.length == 0) {
         // there are no GinModules present in the Ginjector.
         throw new IllegalArgumentException(classLiteral.getName()
                  + " doesn't have any GinModules. " + "Runtime should not work.");
      }

      LOGGER.debug("discovered modules " + annotation);
      return ginModules;
   }

   private Set<Module> readGuiceModules(Class<? extends GinModule>[] classLiterals,
            Class<? extends Ginjector> ginectorClass) throws Exception {

      Set<Module> modules = new HashSet<Module>();
      for (Class<? extends GinModule> literal : classLiterals) {
         LOGGER.debug("wrapping GinModule literal " + literal);
         MemberCollector memberCollector = new MemberCollector(GwtTreeLogger.get());
         GuiceUtil guiceUtil = new GuiceUtil(memberCollector);
         modules.add(new GinModuleAdapter(literal.newInstance(), new GinjectorBindings(null,
                  GwtTreeLogger.get(), guiceUtil, ginectorClass, null, memberCollector, null, null)));
      }

      return modules;

   }
}
TOP

Related Classes of com.googlecode.gwt.test.gin.GInjectorCreateHandler

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.