com.gwtplatform.mvp.rebind.ApplicationControllerGenerator Maven / Gradle / Ivy
/**
* 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("}");
}
}