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.Pages; 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 EventBoundPresenterPageGenerator 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); String packageName = classType.getPackage().getName(); JClassType viewClass = null; // see if the view class is referenced as the class type JClassType superClassType = classType; while (superClassType != null) { JParameterizedType type = classType.isParameterized(); if (null == type || type.getTypeArgs().length == 0) { superClassType = superClassType.getSuperclass(); } else { viewClass = type.getTypeArgs()[0].isClassOrInterface(); } } // look for an inner class with the name of View superClassType = classType; while (superClassType != null) { for (JClassType type : superClassType.getNestedTypes()) { JClassType _interface = type.isInterface(); if (null != _interface && _interface.getName().endsWith("View")) { viewClass = _interface; break; } else if (null != _interface && _interface.getName().endsWith("Display")) { viewClass = _interface; break; } } if (null != viewClass) break; } String newClassName = classType.getSimpleSourceName() + "_Generated"; // Generate class source code generateClass(logger, context, packageName, typeName, newClassName, classType, viewClass, 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 viewInterfaceType, 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(Pages.class.getName()); composer.addImport(List.class.getName()); composer.addImport(ArrayList.class.getName()); composer.addImport(HandlerRegistration.class.getName()); 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); sourceWriter.println(); sourceWriter.println("public void init(Pages settings) {"); sourceWriter.indent(); ViewBindings bindings = FieldBindingUtil.printHandlerBindings( classType, viewInterfaceType, sourceWriter, typeOracle, logger, true); sourceWriter.println("bindHandlers();"); sourceWriter.println("onConstruct((" + viewInterfaceType.getQualifiedSourceName() + ") getView());"); sourceWriter.println("super.init(settings);"); sourceWriter.outdent(); sourceWriter.println("}"); sourceWriter.println(); sourceWriter.println("public Widget asWidget() {"); sourceWriter.indent(); sourceWriter.println("return (Widget) getView();"); sourceWriter.outdent(); sourceWriter.println("}"); if (bindings.handledEvents.size() > 0) FieldBindingUtil.printHandlerBindingsInnerClass(bindings, classType, sourceWriter, typeOracle, logger, true); // close generated class sourceWriter.outdent(); sourceWriter.println("}"); // commit generated class context.commit(logger, printWriter); } }