package com.google.gwt.gwtpages.generator.page; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import com.google.gwt.core.client.GWT; import com.google.gwt.core.ext.Generator; 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.core.ext.typeinfo.JParameterizedType; import com.google.gwt.core.ext.typeinfo.TypeOracle; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.gwtpages.client.page.impl.UiBoundPage; import com.google.gwt.gwtpages.generator.page.FieldBindingUtil.ViewBindings; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiTemplate; import com.google.gwt.user.client.ui.Widget; import com.google.gwt.user.rebind.ClassSourceFileComposerFactory; import com.google.gwt.user.rebind.SourceWriter; public class UiBoundPageGenerator extends Generator { @Override public String generate(TreeLogger logger, GeneratorContext context, String typeName) throws UnableToCompleteException { try { TypeOracle typeOracle = context.getTypeOracle(); // get classType and save instance variables JClassType classType = typeOracle.getType(typeName); JClassType superClassType = classType.getSuperclass(); String packageName = classType.getPackage().getName(); JParameterizedType type = null; while (true) { type = superClassType.isParameterized(); if (null == type || type.getTypeArgs().length == 0) { String qualifiedSuperClassName = superClassType + "." + superClassType.getName(); if (qualifiedSuperClassName.equals(UiBoundPage.class .getName())) { logger.log(logger.ERROR, "Class '" + typeName + "' must have it's type defined"); throw new UnableToCompleteException(); } else { superClassType = superClassType.getSuperclass(); } } else { break; } } String newClassName = classType.getSimpleSourceName() + "_Generated"; // Generate class source code generateClass(logger, context, packageName, typeName, newClassName, classType, type.getTypeArgs()[0], typeOracle); return packageName + "." + newClassName; } catch (Exception e) { logger.log(TreeLogger.ERROR, "AsyncPageLoader generation Error", e); throw new RuntimeException("Couldn't generate async page loader", e); } } /** * Generate source code for new class. Class extends <code>HashMap</code>. * * @param logger * Logger object * @param context * Generator context */ protected void generateClass(TreeLogger logger, GeneratorContext context, String packageName, String typeName, String newClassName, JClassType classType, JClassType widgetType, TypeOracle typeOracle) throws UnableToCompleteException { // get print writer that receives the source code PrintWriter printWriter = null; printWriter = context.tryCreate(logger, packageName, newClassName); // print writer if null, source code has ALREADY been generated, if (printWriter == null) return; // init composer, set class properties, create source writer ClassSourceFileComposerFactory composer = null; composer = new ClassSourceFileComposerFactory(packageName, newClassName); composer.addImport(GWT.class.getName()); composer.addImport(List.class.getName()); composer.addImport(ArrayList.class.getName()); composer.addImport(HandlerRegistration.class.getName()); composer.addImport(widgetType.getPackage().getName() + "." + widgetType.getName().replace('$', '.')); composer.addImport(Widget.class.getName()); composer.addImport(UiBinder.class.getName()); composer.addImport(UiTemplate.class.getName()); composer.setSuperclass(typeName); SourceWriter sourceWriter = null; sourceWriter = composer.createSourceWriter(context, printWriter); String templateName = UIBindingUtil.findUiTemplate(classType, logger); String widgetClassName = widgetType.getName().replace('$', '.'); sourceWriter.println("@UiTemplate(\"" + templateName + "\")"); sourceWriter.println("interface _UiBinder extends UiBinder<" + widgetClassName + ", " + newClassName + "> {}"); sourceWriter .println("private static _UiBinder uiBinder = GWT.create(_UiBinder.class);"); sourceWriter.println(); sourceWriter.println("public " + newClassName + "() {"); sourceWriter.indent(); sourceWriter.println("this.widget = uiBinder.createAndBindUi(this);"); ViewBindings bindings = FieldBindingUtil.printHandlerBindings(classType, widgetType, sourceWriter, typeOracle, logger, false); sourceWriter.println("onConstruct(this.widget);"); sourceWriter.println("bindHandlers();"); sourceWriter.outdent(); sourceWriter.println("}"); sourceWriter.println(); sourceWriter.println("public Widget asWidget() {"); sourceWriter.indent(); sourceWriter.println("return this.widget;"); sourceWriter.outdent(); sourceWriter.println("}"); if (bindings.handledEvents.size() > 0) FieldBindingUtil.printHandlerBindingsInnerClass(bindings, classType, sourceWriter, typeOracle, logger, false); // close generated class sourceWriter.outdent(); sourceWriter.println("}"); // commit generated class context.commit(logger, printWriter); } }