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

com.googlecode.gwt.test.internal.GwtFactory Maven / Gradle / Ivy

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

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.dev.CompilerContext;
import com.google.gwt.dev.cfg.ModuleDef;
import com.google.gwt.dev.cfg.ModuleDefLoader;
import com.google.gwt.dev.javac.CompilationState;
import com.google.gwt.dev.shell.JsValueGlue;
import com.googlecode.gwt.test.GwtTreeLogger;
import com.googlecode.gwt.test.exceptions.GwtTestException;
import com.googlecode.gwt.test.internal.rewrite.OverlayTypesRewriter;

import java.net.URL;
import java.net.URLClassLoader;
import java.util.List;
import java.util.regex.Pattern;

/**
 * An unique place for internal singleton which are ClassLoader independent and can eventually be
 * reset. For internal use only.
 *
 * @author Gael Lazzari
 */
public class GwtFactory {

    private static GwtFactory instance;

    private static final Pattern SUREFIRE_BOOTER_JAR_PATTERN = Pattern.compile("^.*surefire.*\\.jar$");

    public static GwtFactory get() {
        return instance;
    }

    public static boolean initializeIfNeeded() {

        URL currentSurefireBooterJarUrl = findSureFireBooterJarUrl();

        if (instance == null) {
            // first return
            instance = new GwtFactory(currentSurefireBooterJarUrl);
            return true;
        }

        if (instance.surefireBooterJarUrl != null
                && !instance.surefireBooterJarUrl.equals(currentSurefireBooterJarUrl)
                || instance.surefireBooterJarUrl == null && currentSurefireBooterJarUrl != null) {
            // surefire booter jar has changed : this should never happen since
            // surefire-plugin runs each sub-module tests in an isolated
            // classloader
            // but just in case it would happen in the future, recompute everything
            // :-o
            instance = new GwtFactory(currentSurefireBooterJarUrl);

            return true;
        }

        return false;
    }

    private static URL findSureFireBooterJarUrl() {
        ClassLoader parent = Thread.currentThread().getContextClassLoader();
        if (parent instanceof URLClassLoader) {
            URL[] parentUrls = ((URLClassLoader) parent).getURLs();
            if (parentUrls.length == 1
                    && SUREFIRE_BOOTER_JAR_PATTERN.matcher(parentUrls[0].getPath()).matches()) {
                return parentUrls[0];
            }
        }

        return null;
    }

    private final CompilationState compilationState;
    private final CompilerContext compilerContext;
    private final CompilerContext.Builder compilerContextBuilder = new CompilerContext.Builder();
    private final ConfigurationLoader configurationLoader;
    private final GwtClassLoader gwtClassLoader;
    private final ModuleDef moduleDef;

    private final OverlayTypesRewriter overlayRewriter;

    private final URL surefireBooterJarUrl;

    private GwtFactory(URL surefireBooterJarUrl) {
        configurationLoader = new ConfigurationLoader(surefireBooterJarUrl);

        this.surefireBooterJarUrl = surefireBooterJarUrl;

        // create a the temporary classloader used to build the CompilationState object which needs
        // access to the project's resources (.java file)
        ClassLoader defaultClassLoader = Thread.currentThread().getContextClassLoader();

        CompilationStateClassLoader tempCl = new CompilationStateClassLoader(defaultClassLoader,
                configurationLoader);
        // ClassLoader classLoaderForResources =
        // createTemporaryClassLoaderForResourceLoading(surefireBooterJarUrl);
        Thread.currentThread().setContextClassLoader(tempCl);

        try {
            // create every gwt stuff, searching for resources in the setup
            // 'src-directories' entries in
            // META-INF/gwt-test-utils.properties files
            CompilerContext tempContext = compilerContextBuilder.build();
            moduleDef = createModuleDef(configurationLoader, tempContext);
            compilerContext = compilerContextBuilder.module(moduleDef).build();
            compilationState = createCompilationState(moduleDef, compilerContext);
            overlayRewriter = createOverlayRewriter(compilationState);
            gwtClassLoader = GwtClassLoader.createClassLoader(configurationLoader, compilationState,
                    overlayRewriter);
        } catch (UnableToCompleteException e) {
            // log related errors
            GwtTreeLogger.get().onUnableToCompleteError();
            throw new GwtTestException("Error while generating gwt-test-utils prerequisites", e);
        } finally {
            // reset the default classloader
            Thread.currentThread().setContextClassLoader(defaultClassLoader);
        }
    }

    public GwtClassLoader getClassLoader() {
        return gwtClassLoader;
    }

    public CompilationState getCompilationState() {
        return compilationState;
    }

    public ConfigurationLoader getConfigurationLoader() {
        return configurationLoader;
    }

    public ModuleDef getModuleDef() {
        return moduleDef;
    }

    public OverlayTypesRewriter getOverlayRewriter() {
        return overlayRewriter;
    }

    private CompilationState createCompilationState(ModuleDef moduleDef,
                                                    CompilerContext compilerContext) throws UnableToCompleteException {
        TreeLogger treeLogger = GwtTreeLogger.get();
        return moduleDef.getCompilationState(treeLogger, compilerContext);
    }

    private ModuleDef createModuleDef(ConfigurationLoader configurationLoader,
                                      CompilerContext compilerContext) throws UnableToCompleteException {
        List gwtModules = configurationLoader.getGwtModules();
        String[] inherits = gwtModules.toArray(new String[gwtModules.size()]);
        return ModuleDefLoader.createSyntheticModule(GwtTreeLogger.get(),
                "com.googlecode.gwt.test.Aggregator", inherits, false);
    }

    private OverlayTypesRewriter createOverlayRewriter(CompilationState compilationState) {
        TypeOracle typeOracle = compilationState.getTypeOracle();
        JClassType jsoType = typeOracle.findType(JsValueGlue.JSO_CLASS);

        // If we couldn't find the JSO class, we don't need to do any rewrites.
        return jsoType != null ? new OverlayTypesRewriter(compilationState, jsoType) : null;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy