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

com.googlecode.gwt.test.internal.handlers.GeneratorCreateHandler Maven / Gradle / Ivy

There is a newer version: 0.63
Show newest version
/*
 * Copyright 2010 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */

package com.googlecode.gwt.test.internal.handlers;

import com.google.gwt.core.ext.PropertyOracle;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.TreeLogger.Type;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.linker.ArtifactSet;
import com.google.gwt.dev.RebindCache;
import com.google.gwt.dev.cfg.BindingProperty;
import com.google.gwt.dev.cfg.ConfigurationProperty;
import com.google.gwt.dev.cfg.ModuleDef;
import com.google.gwt.dev.cfg.PropertyCombinations;
import com.google.gwt.dev.javac.CompilationState;
import com.google.gwt.dev.javac.CompiledClass;
import com.google.gwt.dev.javac.JsniMethod;
import com.google.gwt.dev.shell.*;
import com.google.gwt.dev.util.Name;
import com.google.gwt.junit.client.WithProperties;
import com.google.gwt.junit.client.WithProperties.Property;
import com.googlecode.gwt.test.GwtCreateHandler;
import com.googlecode.gwt.test.GwtTreeLogger;
import com.googlecode.gwt.test.exceptions.GwtTestConfigurationException;
import com.googlecode.gwt.test.internal.GwtFactory;
import com.googlecode.gwt.test.internal.GwtTestDataHolder;
import com.googlecode.gwt.test.utils.GwtReflectionUtils;

import java.lang.reflect.Modifier;
import java.util.*;

/**
 * This is a wrapper around GWT's compilation tools
 */
public class GeneratorCreateHandler implements GwtCreateHandler {

    private static final ArtifactAcceptor ARTIFACT_ACCEPTOR = new ArtifactAcceptor() {

        public void accept(TreeLogger logger, ArtifactSet newlyGeneratedArtifacts)
                throws UnableToCompleteException {

        }
    };

    private static Map moduleSpaceHosts = new HashMap();

    private static final RebindCache REBIND_CACHE = new RebindCache();

    protected Map compiledClassMap = new HashMap();

    private final CompilationState compilationState;
    private final TreeLogger logger = GwtTreeLogger.get();

    private final ModuleDef moduleDef;

    private PropertyOracle propertyOracle;

    public GeneratorCreateHandler(CompilationState compilationState, ModuleDef moduleDef) {
        this.compilationState = compilationState;
        this.moduleDef = moduleDef;
    }

    public Object create(Class classLiteral) throws Exception {
        Class c = generate(classLiteral);

        if (c.isInterface() || Modifier.isAbstract(c.getModifiers())) {
            return null;
        }
        return GwtReflectionUtils.instantiateClass(c);
    }

    public Class generate(Class classLiteral) throws UnableToCompleteException {
        CompiledClass compiledClass = compile(classLiteral.getCanonicalName());
        if (compiledClass == null) {
            return classLiteral;
        }

        try {
            return GwtFactory.get().getClassLoader().loadClass(compiledClass.getSourceName());
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    public ModuleDef getGwtModule() {
        return moduleDef;
    }

    protected PropertyOracle getPropertyOracle() {
        if (propertyOracle == null) {
            PropertyCombinations permutations = new PropertyCombinations(moduleDef.getProperties(),
                    moduleDef.getActiveLinkerNames());

            SortedSet configPropSet = moduleDef.getProperties().getConfigurationProperties();
            ConfigurationProperty[] configProps = configPropSet.toArray(new ConfigurationProperty[configPropSet.size()]);

            BindingProperty[] orderedProperties = permutations.getOrderedProperties();

            WithProperties withProperties = GwtTestDataHolder.get().getCurrentWithProperties();

            String[] processedProperties;
            if (withProperties != null) {
                processedProperties = replaceOrderedPropertyValues(orderedProperties,
                        permutations.getOrderedPropertyValues(0), withProperties);
            } else {
                processedProperties = permutations.getOrderedPropertyValues(0);
            }

            propertyOracle = new StaticPropertyOracle(orderedProperties, processedProperties,
                    configProps);
        }

        return propertyOracle;
    }

    private CompiledClass compile(String literalName) throws UnableToCompleteException {
        CompiledClass compiledClass = compiledClassMap.get(literalName);
        if (compiledClass != null) {
            logger.log(Type.INFO, "Using cached resource for " + literalName);
            return compiledClass;
        }

        if (moduleDef == null) {
            throw new RuntimeException("Gwt module is not set.");
        }

        logger.log(Type.INFO, "Generating " + literalName);

        String className;
        className = getModuleSpaceHost().rebind(logger, literalName);

        String internalName = Name.BinaryName.toInternalName(className);

        compiledClass = compilationState.getClassFileMap().get(internalName);

        if (compiledClass != null) {
            compiledClassMap.put(literalName, compiledClass);
        }

        return compiledClass;
    }

    private ModuleSpace createModuleSpace(ModuleSpaceHost host) {

        return new ModuleSpace(GwtTreeLogger.get(), host, moduleDef.getCanonicalName()) {

            public void createNativeMethods(TreeLogger logger, List jsniMethods,
                                            DispatchIdOracle dispatchIdOracle) {
                // this method should never be called
                throw new UnsupportedOperationException(
                        "ModuleSpace.createNativeMethods(..) not supported by gwt-test-utils");
            }

            @Override
            protected void createStaticDispatcher(TreeLogger logger) {
                // this method should never be called
                throw new UnsupportedOperationException(
                        "ModuleSpace.createStaticDispatcher(..) not supported by gwt-test-utils");

            }

            @Override
            protected JsValue doInvoke(String name, Object jthis, Class[] types, Object[] args)
                    throws Throwable {
                // this method should never be called
                throw new UnsupportedOperationException(
                        "ModuleSpace.doInvoke(..) not supported by gwt-test-utils");
            }

            @Override
            protected Object getStaticDispatcher() {
                // this method should never be called
                throw new UnsupportedOperationException(
                        "ModuleSpace.getStaticDispatcher() not supported by gwt-test-utils");

            }
        };

    }

    private ModuleSpaceHost createModuleSpaceHost(CompilationState compilationState,
                                                  ModuleDef moduleDef) {
        try {
            ModuleSpaceHost moduleSpaceHost = new GwtTestModuleSpaceHost(GwtTreeLogger.get(),
                    compilationState, moduleDef, null, ARTIFACT_ACCEPTOR, REBIND_CACHE);
            ModuleSpace moduleSpace = createModuleSpace(moduleSpaceHost);
            moduleSpaceHost.onModuleReady(moduleSpace);

            return moduleSpaceHost;
        } catch (UnableToCompleteException e) {
            throw new GwtTestConfigurationException("Error while creating global ModuleSpaceHost :", e);
        }
    }

    private ModuleSpaceHost getModuleSpaceHost() {
        WithProperties withProperties = GwtTestDataHolder.get().getCurrentWithProperties();
        String serializedProperties = serialize(withProperties);

        ModuleSpaceHost moduleSpaceHost = moduleSpaceHosts.get(serializedProperties);

        if (moduleSpaceHost == null) {
            moduleSpaceHost = createModuleSpaceHost(compilationState, moduleDef);
            moduleSpaceHosts.put(serializedProperties, moduleSpaceHost);
        }

        return moduleSpaceHost;
    }

    private TreeMap propertiesToTreeMap(WithProperties withProperties) {
        TreeMap treeMap = new TreeMap();
        for (Property property : withProperties.value()) {
            treeMap.put(property.name(), property.value());
        }

        return treeMap;
    }

    private String[] replaceOrderedPropertyValues(BindingProperty[] orderedProperties,
                                                  String[] orderedOriginalValues, WithProperties withProperties) {

        Map propertiesOverrides = propertiesToTreeMap(withProperties);

        String[] result = new String[orderedProperties.length];
        for (int i = 0; i < orderedProperties.length; i++) {
            if (propertiesOverrides.containsKey(orderedProperties[i].getName())) {
                result[i] = propertiesOverrides.get(orderedProperties[i].getName());
            } else {
                result[i] = orderedOriginalValues[i];
            }
        }
        return result;
    }

    private String serialize(WithProperties withProperties) {
        return withProperties != null ? propertiesToTreeMap(withProperties).toString() : "";
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy