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

com.googlecode.gwt.test.gin.GInjectorCreateHandler Maven / Gradle / Ivy

There is a newer version: 0.63
Show newest version
package com.googlecode.gwt.test.gin;

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;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

/**
 * 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, 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 ginjectorClass = (Class) classLiteral;

        if (injectors == null) {
            injectors = new HashMap, 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[] ginModules = readGinModules(ginjectorClass);

        // create a set of Guice Module bases on the GinModules
        Set 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[] readGinModules(Class 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[] 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 readGuiceModules(Class[] classLiterals,
                                         Class ginectorClass) throws Exception {

        Set modules = new HashSet();
        for (Class 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;

    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy