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

com.gwtplatform.mvp.rebind.ApplicationControllerGenerator Maven / Gradle / Ivy

There is a newer version: 1.6
Show newest version
/**
 * Copyright 2011 ArcBees 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.gwtplatform.mvp.rebind;

import java.io.PrintWriter;

import com.google.gwt.core.ext.GeneratorContext;
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.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;
import com.gwtplatform.mvp.client.Bootstrapper;
import com.gwtplatform.mvp.client.DelayedBindRegistry;
import com.gwtplatform.mvp.client.annotations.IsTheBootstrapper;
import com.gwtplatform.mvp.client.proxy.PlaceManager;

/**
 * Will generate a {@link com.gwtplatform.mvp.client.ApplicationController}. If the user wants his Generator to be
 * generated by GWTP, this Application controller will make sure that the Ginjector is used to trigger the initial
 * revealCurrentPlace() from the place manager.
 */
public class ApplicationControllerGenerator extends AbstractGenerator {
    private static final String TOO_MANY_BOOTSTRAPPER_FOUND =
            "Too many bootstrapper has been found. Only one bootstrapper annotated with IsTheBoostrapper can be used.";
    private static final String DOES_NOT_EXTEND_BOOTSTRAPPER =
            "The boostrapper provided doesn't implements the interface Bootstrapper.";

    private static final String SUFFIX = "Impl";
    private static final String OVERRIDE = "@Override";
    private static final String INJECT_METHOD = "public void init() {";
    private static final String DELAYED_BIND = "%s.bind(%s.SINGLETON);";
    private static final String PLACEMANAGER_REVEALCURRENTPLACE = "%s.SINGLETON.get%s().revealCurrentPlace();";
    private static final String INIT_BOOSTRAPPER = "%s.SINGLETON.get%s().init();";

    @Override
    public String generate(TreeLogger treeLogger, GeneratorContext generatorContext, String typeName)
            throws UnableToCompleteException {
        setTypeOracle(generatorContext.getTypeOracle());
        setPropertyOracle(generatorContext.getPropertyOracle());
        setTreeLogger(treeLogger);
        setTypeClass(getType(typeName));

        PrintWriter printWriter = tryCreatePrintWriter(generatorContext, SUFFIX);

        if (printWriter == null) {
            return typeName + SUFFIX;
        }

        ClassSourceFileComposerFactory composer = initComposer();
        SourceWriter sourceWriter = composer.createSourceWriter(generatorContext, printWriter);

        JClassType bootstrapper = getBootstrapper();
        String ginjectorName = new GinjectorGenerator(bootstrapper).generate(getTreeLogger(),
                generatorContext, GinjectorGenerator.DEFAULT_FQ_NAME);

        writeInit(sourceWriter, ginjectorName, bootstrapper);

        closeDefinition(sourceWriter);

        return getPackageName() + "." + getClassName();
    }

    private ClassSourceFileComposerFactory initComposer() {
        ClassSourceFileComposerFactory composer = new ClassSourceFileComposerFactory(getPackageName(), getClassName());
        composer.addImport(getTypeClass().getQualifiedSourceName());
        composer.addImplementedInterface(getTypeClass().getName());

        composer.addImport(DelayedBindRegistry.class.getCanonicalName());

        return composer;
    }

    private JClassType getBootstrapper() throws UnableToCompleteException {
        int boostrapperCounter = 0;
        JClassType bootstrapper = null;
        for (JClassType type : getTypeOracle().getTypes()) {
            if (type.isAnnotationPresent(IsTheBootstrapper.class)) {
                bootstrapper = type;
                boostrapperCounter++;

                verifyBoostrapperInterface(bootstrapper);
            }
        }

        verifyThatTheresOnlyOneBootstrapper(boostrapperCounter);

        return bootstrapper;
    }

    private void verifyThatTheresOnlyOneBootstrapper(int boostrapperCounter) throws UnableToCompleteException {
        if (boostrapperCounter > 1) {
            getTreeLogger().log(TreeLogger.ERROR, TOO_MANY_BOOTSTRAPPER_FOUND);
            throw new UnableToCompleteException();
        }
    }

    private void verifyBoostrapperInterface(JClassType bootstrapper) throws UnableToCompleteException {
        JClassType bootstrapperInterface = getType(Bootstrapper.class.getName());

        if (!bootstrapper.isAssignableTo(bootstrapperInterface)) {
            getTreeLogger().log(TreeLogger.ERROR, DOES_NOT_EXTEND_BOOTSTRAPPER);
            throw new UnableToCompleteException();
        }
    }

    private void writeInit(SourceWriter sourceWriter, String generatorName, JClassType bootstrapper) {
        sourceWriter.println(OVERRIDE);
        sourceWriter.println(INJECT_METHOD);
        sourceWriter.indent();

        sourceWriter.println(String.format(DELAYED_BIND, DelayedBindRegistry.class.getSimpleName(), generatorName));
        sourceWriter.println();

        if (bootstrapper == null) {
            sourceWriter.println(String.format(PLACEMANAGER_REVEALCURRENTPLACE, generatorName,
                    PlaceManager.class.getSimpleName()));
        } else {
            sourceWriter.println(String.format(INIT_BOOSTRAPPER, generatorName, bootstrapper.getSimpleSourceName()));
        }

        sourceWriter.outdent();
        sourceWriter.println("}");
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy