Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

WidgetMapGenerator.java 7.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. package com.vaadin.terminal.gwt.rebind;
  2. import java.io.PrintWriter;
  3. import java.util.Collection;
  4. import java.util.Date;
  5. import java.util.Iterator;
  6. import com.google.gwt.core.ext.Generator;
  7. import com.google.gwt.core.ext.GeneratorContext;
  8. import com.google.gwt.core.ext.TreeLogger;
  9. import com.google.gwt.core.ext.UnableToCompleteException;
  10. import com.google.gwt.core.ext.TreeLogger.Type;
  11. import com.google.gwt.core.ext.typeinfo.JClassType;
  12. import com.google.gwt.core.ext.typeinfo.TypeOracle;
  13. import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
  14. import com.google.gwt.user.rebind.SourceWriter;
  15. import com.vaadin.terminal.Paintable;
  16. import com.vaadin.terminal.gwt.client.ui.VView;
  17. import com.vaadin.ui.ClientWidget;
  18. /**
  19. * GWT generator to build WidgetMapImpl dynamically based on
  20. * {@link ClientWidget} annotations available in workspace.
  21. *
  22. */
  23. public class WidgetMapGenerator extends Generator {
  24. private String packageName;
  25. private String className;
  26. @Override
  27. public String generate(TreeLogger logger, GeneratorContext context,
  28. String typeName) throws UnableToCompleteException {
  29. try {
  30. TypeOracle typeOracle = context.getTypeOracle();
  31. // get classType and save instance variables
  32. JClassType classType = typeOracle.getType(typeName);
  33. packageName = classType.getPackage().getName();
  34. className = classType.getSimpleSourceName() + "Impl";
  35. // Generate class source code
  36. generateClass(logger, context);
  37. } catch (Exception e) {
  38. logger.log(TreeLogger.ERROR, "WidgetMap creation failed", e);
  39. }
  40. // return the fully qualifed name of the class generated
  41. return packageName + "." + className;
  42. }
  43. /**
  44. * Generate source code for WidgetMapImpl
  45. *
  46. * @param logger
  47. * Logger object
  48. * @param context
  49. * Generator context
  50. */
  51. private void generateClass(TreeLogger logger, GeneratorContext context) {
  52. // get print writer that receives the source code
  53. PrintWriter printWriter = null;
  54. printWriter = context.tryCreate(logger, packageName, className);
  55. // print writer if null, source code has ALREADY been generated, return
  56. if (printWriter == null) {
  57. return;
  58. }
  59. logger
  60. .log(Type.INFO,
  61. "Detecting vaading components in classpath to generate WidgetMapImpl.java ...");
  62. Date date = new Date();
  63. // init composer, set class properties, create source writer
  64. ClassSourceFileComposerFactory composer = null;
  65. composer = new ClassSourceFileComposerFactory(packageName, className);
  66. composer.setSuperclass("com.vaadin.terminal.gwt.client.WidgetMap");
  67. SourceWriter sourceWriter = composer.createSourceWriter(context,
  68. printWriter);
  69. /*
  70. * TODO we need som sort of mechanims to exclude/include components from
  71. * widgetset. Properties in gwt.xml is one option. Now only possible by
  72. * extending this class, overriding getUsedPaintables() method and
  73. * redefining deferred binding rule.
  74. */
  75. Collection<Class<? extends Paintable>> paintablesHavingWidgetAnnotation = getUsedPaintables();
  76. TypeOracle typeOracle = context.getTypeOracle();
  77. for (Iterator iterator = paintablesHavingWidgetAnnotation.iterator(); iterator
  78. .hasNext();) {
  79. Class<? extends Paintable> class1 = (Class<? extends Paintable>) iterator
  80. .next();
  81. ClientWidget annotation = class1.getAnnotation(ClientWidget.class);
  82. if (typeOracle.findType(annotation.value().getName()) == null) {
  83. // GWT widget not inherited
  84. logger
  85. .log(
  86. Type.WARN,
  87. "Widget implementation for "
  88. + class1.getName()
  89. + " not available for GWT compiler. If this is not "
  90. + "intentional, check your gwt module definition file.");
  91. iterator.remove();
  92. }
  93. }
  94. // generator constructor source code
  95. generateImplementationDetector(sourceWriter,
  96. paintablesHavingWidgetAnnotation);
  97. generateInstantiatorMethod(sourceWriter,
  98. paintablesHavingWidgetAnnotation);
  99. // close generated class
  100. sourceWriter.outdent();
  101. sourceWriter.println("}");
  102. // commit generated class
  103. context.commit(logger, printWriter);
  104. logger.log(Type.INFO, "Done. ("
  105. + (new Date().getTime() - date.getTime()) / 1000 + "seconds)");
  106. }
  107. protected Collection<Class<? extends Paintable>> getUsedPaintables() {
  108. return ClassPathExplorer.getPaintablesHavingWidgetAnnotation();
  109. }
  110. private void generateInstantiatorMethod(
  111. SourceWriter sourceWriter,
  112. Collection<Class<? extends Paintable>> paintablesHavingWidgetAnnotation) {
  113. sourceWriter
  114. .println("public Paintable instantiate(Class<? extends Paintable> classType) {");
  115. sourceWriter.indent();
  116. sourceWriter
  117. .println("Paintable p = super.instantiate(classType); if(p!= null) return p;");
  118. for (Class<? extends Paintable> class1 : paintablesHavingWidgetAnnotation) {
  119. ClientWidget annotation = class1.getAnnotation(ClientWidget.class);
  120. Class<? extends com.vaadin.terminal.gwt.client.Paintable> clientClass = annotation
  121. .value();
  122. if (clientClass == VView.class) {
  123. // VView's are not instantiated by widgetset
  124. continue;
  125. }
  126. sourceWriter.print("if (");
  127. sourceWriter.print(clientClass.getName());
  128. sourceWriter.print(".class == classType) return new ");
  129. sourceWriter.print(clientClass.getName());
  130. sourceWriter.println("();");
  131. sourceWriter.print(" else ");
  132. }
  133. sourceWriter
  134. .println("return new com.vaadin.terminal.gwt.client.ui.VUnknownComponent();");
  135. sourceWriter.println("}");
  136. }
  137. /**
  138. *
  139. * @param sourceWriter
  140. * Source writer to output source code
  141. * @param paintablesHavingWidgetAnnotation
  142. */
  143. private void generateImplementationDetector(
  144. SourceWriter sourceWriter,
  145. Collection<Class<? extends Paintable>> paintablesHavingWidgetAnnotation) {
  146. sourceWriter
  147. .println("public Class<? extends Paintable> getImplementationByServerSideClassName(String fullyQualifiedName) {");
  148. sourceWriter.indent();
  149. sourceWriter
  150. .println("fullyQualifiedName = fullyQualifiedName.intern();");
  151. for (Class<? extends Paintable> class1 : paintablesHavingWidgetAnnotation) {
  152. ClientWidget annotation = class1.getAnnotation(ClientWidget.class);
  153. Class<? extends com.vaadin.terminal.gwt.client.Paintable> clientClass = annotation
  154. .value();
  155. sourceWriter.print("if ( fullyQualifiedName == \"");
  156. sourceWriter.print(class1.getName());
  157. sourceWriter.print("\") return ");
  158. sourceWriter.print(clientClass.getName());
  159. sourceWriter.println(".class;");
  160. sourceWriter.print(" else ");
  161. }
  162. sourceWriter
  163. .println("return com.vaadin.terminal.gwt.client.ui.VUnknownComponent.class;");
  164. sourceWriter.println("}");
  165. }
  166. }