From 0985dac7be6384d05c91d8ce91b41cdcf33226ab Mon Sep 17 00:00:00 2001 From: =?utf8?q?Leif=20=C3=85strand?= Date: Mon, 24 Sep 2012 13:55:44 +0300 Subject: [PATCH] Remove WidgetMapGenerator and subclasses (#9720) --- .../CustomWidgetMapGenerator.java | 96 ---- .../EagerWidgetMapGenerator.java | 41 -- .../LazyWidgetMapGenerator.java | 35 -- .../widgetsetutils/WidgetMapGenerator.java | 434 ------------------ 4 files changed, 606 deletions(-) delete mode 100644 client-compiler/src/com/vaadin/server/widgetsetutils/CustomWidgetMapGenerator.java delete mode 100644 client-compiler/src/com/vaadin/server/widgetsetutils/EagerWidgetMapGenerator.java delete mode 100644 client-compiler/src/com/vaadin/server/widgetsetutils/LazyWidgetMapGenerator.java delete mode 100644 client-compiler/src/com/vaadin/server/widgetsetutils/WidgetMapGenerator.java diff --git a/client-compiler/src/com/vaadin/server/widgetsetutils/CustomWidgetMapGenerator.java b/client-compiler/src/com/vaadin/server/widgetsetutils/CustomWidgetMapGenerator.java deleted file mode 100644 index 250bfbb4a1..0000000000 --- a/client-compiler/src/com/vaadin/server/widgetsetutils/CustomWidgetMapGenerator.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2011 Vaadin Ltd. - * - * 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.vaadin.server.widgetsetutils; - -import java.util.Collection; -import java.util.HashSet; - -import com.vaadin.client.ComponentConnector; -import com.vaadin.client.ServerConnector; -import com.vaadin.shared.ui.Connect; -import com.vaadin.shared.ui.Connect.LoadStyle; - -/** - * An abstract helper class that can be used to easily build a widgetset with - * customized load styles for each components. In three abstract methods one can - * override the default values given in {@link Connect} annotations. - * - * @see WidgetMapGenerator - * - */ -public abstract class CustomWidgetMapGenerator extends WidgetMapGenerator { - - private Collection> eagerPaintables = new HashSet>(); - private Collection> lazyPaintables = new HashSet>(); - private Collection> deferredPaintables = new HashSet>(); - - @Override - protected LoadStyle getLoadStyle(Class connector) { - if (eagerPaintables == null) { - init(); - } - if (eagerPaintables.contains(connector)) { - return LoadStyle.EAGER; - } - if (lazyPaintables.contains(connector)) { - return LoadStyle.LAZY; - } - if (deferredPaintables.contains(connector)) { - return LoadStyle.DEFERRED; - } - return super.getLoadStyle(connector); - } - - private void init() { - Class[] eagerComponents = getEagerComponents(); - if (eagerComponents != null) { - for (Class class1 : eagerComponents) { - eagerPaintables.add(class1); - } - } - Class[] lazyComponents = getEagerComponents(); - if (lazyComponents != null) { - for (Class class1 : lazyComponents) { - lazyPaintables.add(class1); - } - } - Class[] deferredComponents = getEagerComponents(); - if (deferredComponents != null) { - for (Class class1 : deferredComponents) { - deferredPaintables.add(class1); - } - } - } - - /** - * @return an array of components whose load style should be overridden to - * {@link LoadStyle#EAGER} - */ - protected abstract Class[] getEagerComponents(); - - /** - * @return an array of components whose load style should be overridden to - * {@link LoadStyle#LAZY} - */ - protected abstract Class[] getLazyComponents(); - - /** - * @return an array of components whose load style should be overridden to - * {@link LoadStyle#DEFERRED} - */ - protected abstract Class[] getDeferredComponents(); - -} diff --git a/client-compiler/src/com/vaadin/server/widgetsetutils/EagerWidgetMapGenerator.java b/client-compiler/src/com/vaadin/server/widgetsetutils/EagerWidgetMapGenerator.java deleted file mode 100644 index 568dc939e7..0000000000 --- a/client-compiler/src/com/vaadin/server/widgetsetutils/EagerWidgetMapGenerator.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2011 Vaadin Ltd. - * - * 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.vaadin.server.widgetsetutils; - -import com.vaadin.client.ServerConnector; -import com.vaadin.shared.ui.Connect.LoadStyle; - -/** - * WidgetMap generator that builds a widgetset that packs all included widgets - * into a single JavaScript file loaded at application initialization. Initially - * loaded data will be relatively large, but minimal amount of server requests - * will be done. - *

- * This is the default generator in version 6.4 and produces similar type of - * widgetset as in previous versions of Vaadin. To activate "code splitting", - * use the {@link WidgetMapGenerator} instead, that loads most components - * deferred. - * - * @see WidgetMapGenerator - * - */ -public class EagerWidgetMapGenerator extends WidgetMapGenerator { - - @Override - protected LoadStyle getLoadStyle(Class connector) { - return LoadStyle.EAGER; - } -} diff --git a/client-compiler/src/com/vaadin/server/widgetsetutils/LazyWidgetMapGenerator.java b/client-compiler/src/com/vaadin/server/widgetsetutils/LazyWidgetMapGenerator.java deleted file mode 100644 index 9e46b6d9dd..0000000000 --- a/client-compiler/src/com/vaadin/server/widgetsetutils/LazyWidgetMapGenerator.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2011 Vaadin Ltd. - * - * 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.vaadin.server.widgetsetutils; - -import com.vaadin.client.ServerConnector; -import com.vaadin.shared.ui.Connect.LoadStyle; - -/** - * WidgetMap generator that builds a widgetset that optimizes the transferred - * data. Widgets are loaded only when used if the widgetset is built with this - * generator. - * - * @see WidgetMapGenerator - * - */ -public class LazyWidgetMapGenerator extends WidgetMapGenerator { - @Override - protected LoadStyle getLoadStyle(Class connector) { - return LoadStyle.LAZY; - } - -} diff --git a/client-compiler/src/com/vaadin/server/widgetsetutils/WidgetMapGenerator.java b/client-compiler/src/com/vaadin/server/widgetsetutils/WidgetMapGenerator.java deleted file mode 100644 index c1fb6df883..0000000000 --- a/client-compiler/src/com/vaadin/server/widgetsetutils/WidgetMapGenerator.java +++ /dev/null @@ -1,434 +0,0 @@ -/* - * Copyright 2011 Vaadin Ltd. - * - * 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.vaadin.server.widgetsetutils; - -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.Map; -import java.util.TreeSet; - -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.TreeLogger.Type; -import com.google.gwt.core.ext.UnableToCompleteException; -import com.google.gwt.core.ext.typeinfo.JClassType; -import com.google.gwt.core.ext.typeinfo.TypeOracle; -import com.google.gwt.user.rebind.ClassSourceFileComposerFactory; -import com.google.gwt.user.rebind.SourceWriter; -import com.vaadin.client.ServerConnector; -import com.vaadin.client.ui.UnknownComponentConnector; -import com.vaadin.client.ui.ui.UIConnector; -import com.vaadin.server.ClientConnector; -import com.vaadin.shared.Connector; -import com.vaadin.shared.ui.Connect; -import com.vaadin.shared.ui.Connect.LoadStyle; - -/** - * WidgetMapGenerator's are GWT generator to build WidgetMapImpl dynamically - * based on {@link Connect} annotations available in workspace. By modifying the - * generator it is possible to do some fine tuning for the generated widgetset - * (aka client side engine). The components to be included in the client side - * engine can modified be overriding {@link #getUsedConnectors()}. - *

- * The generator also decides how the client side component implementations are - * loaded to the browser. The default generator is - * {@link EagerWidgetMapGenerator} that builds a monolithic client side engine - * that loads all widget implementation on application initialization. This has - * been the only option until Vaadin 6.4. - *

- * This generator uses the loadStyle hints from the {@link Connect} annotations. - * Depending on the {@link LoadStyle} used, the widget may be included in the - * initially loaded JavaScript, loaded when the application has started and - * there is no communication to server or lazy loaded when the implementation is - * absolutely needed. - *

- * The GWT module description file of the widgetset ( - * ...Widgetset.gwt.xml) can be used to define the - * WidgetMapGenarator. An example that defines this generator to be used: - * - *

- * 
- * <generate-with
- *           class="com.vaadin.server.widgetsetutils.MyWidgetMapGenerator">
- *          <when-type-is class="com.vaadin.client.WidgetMap" />
- * </generate-with>
- * 
- * 
- * 
- * - *

- * Vaadin package also includes {@link LazyWidgetMapGenerator}, which is a good - * option if the transferred data should be minimized, and - * {@link CustomWidgetMapGenerator} for easy overriding of loading strategies. - * - */ -public class WidgetMapGenerator extends Generator { - - private static String serverConnectorClassName = ServerConnector.class - .getName(); - - private String packageName; - private String className; - - @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); - packageName = classType.getPackage().getName(); - className = classType.getSimpleSourceName() + "Impl"; - // Generate class source code - generateClass(logger, context); - } catch (Exception e) { - logger.log(TreeLogger.ERROR, "WidgetMap creation failed", e); - } - // return the fully qualifed name of the class generated - return packageName + "." + className; - } - - /** - * Generate source code for WidgetMapImpl - * - * @param logger - * Logger object - * @param context - * Generator context - * @throws UnableToCompleteException - */ - private void generateClass(TreeLogger logger, GeneratorContext context) - throws UnableToCompleteException { - // get print writer that receives the source code - PrintWriter printWriter = null; - printWriter = context.tryCreate(logger, packageName, className); - // print writer if null, source code has ALREADY been generated, - // return (WidgetMap is equal to all permutations atm) - if (printWriter == null) { - return; - } - logger.log(Type.INFO, - "Detecting Vaadin connectors in classpath to generate WidgetMapImpl.java ..."); - Date date = new Date(); - - // init composer, set class properties, create source writer - ClassSourceFileComposerFactory composer = null; - composer = new ClassSourceFileComposerFactory(packageName, className); - composer.addImport("com.google.gwt.core.client.GWT"); - composer.addImport("java.util.HashMap"); - composer.addImport("com.google.gwt.core.client.RunAsyncCallback"); - composer.setSuperclass("com.vaadin.client.WidgetMap"); - SourceWriter sourceWriter = composer.createSourceWriter(context, - printWriter); - - Collection> connectors = getUsedConnectors(context - .getTypeOracle()); - - validateConnectors(logger, connectors); - logConnectors(logger, context, connectors); - - // generator constructor source code - generateImplementationDetector(logger, sourceWriter, connectors); - generateInstantiatorMethod(sourceWriter, connectors); - // close generated class - sourceWriter.outdent(); - sourceWriter.println("}"); - // commit generated class - context.commit(logger, printWriter); - logger.log(Type.INFO, - "Done. (" + (new Date().getTime() - date.getTime()) / 1000 - + "seconds)"); - - } - - private void validateConnectors(TreeLogger logger, - Collection> connectors) { - - Iterator> iter = connectors.iterator(); - while (iter.hasNext()) { - Class connectorClass = iter.next(); - Connect annotation = connectorClass.getAnnotation(Connect.class); - if (!ClientConnector.class.isAssignableFrom(annotation.value())) { - logger.log( - Type.WARN, - "Connector class " - + annotation.value().getName() - + " defined in @Connect annotation is not a subclass of " - + ClientConnector.class.getName() - + ". The component connector " - + connectorClass.getName() - + " will not be included in the widgetset."); - iter.remove(); - } - } - - } - - private void logConnectors(TreeLogger logger, GeneratorContext context, - Collection> connectors) { - logger.log(Type.INFO, - "Widget set will contain implementations for following component connectors: "); - - TreeSet classNames = new TreeSet(); - HashMap loadStyle = new HashMap(); - for (Class connectorClass : connectors) { - String className = connectorClass.getCanonicalName(); - classNames.add(className); - if (getLoadStyle(connectorClass) == LoadStyle.DEFERRED) { - loadStyle.put(className, "DEFERRED"); - } else if (getLoadStyle(connectorClass) == LoadStyle.LAZY) { - loadStyle.put(className, "LAZY"); - } - - } - for (String className : classNames) { - String msg = className; - if (loadStyle.containsKey(className)) { - msg += " (load style: " + loadStyle.get(className) + ")"; - } - logger.log(Type.INFO, "\t" + msg); - } - } - - /** - * This method is protected to allow creation of optimized widgetsets. The - * Widgetset will contain only implementation returned by this function. If - * one knows which widgets are needed for the application, returning only - * them here will significantly optimize the size of the produced JS. - * - * @return a collections of Vaadin components that will be added to - * widgetset - */ - @SuppressWarnings("unchecked") - private Collection> getUsedConnectors( - TypeOracle typeOracle) { - JClassType connectorType = typeOracle.findType(Connector.class - .getName()); - Collection> connectors = new HashSet>(); - for (JClassType jClassType : connectorType.getSubtypes()) { - Connect annotation = jClassType.getAnnotation(Connect.class); - if (annotation != null) { - try { - Class clazz = (Class) Class - .forName(jClassType.getQualifiedSourceName()); - connectors.add(clazz); - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } - } - } - return connectors; - } - - /** - * Returns true if the widget for given component will be lazy loaded by the - * client. The default implementation reads the information from the - * {@link Connect} annotation. - *

- * The method can be overridden to optimize the widget loading mechanism. If - * the Widgetset is wanted to be optimized for a network with a high latency - * or for a one with a very fast throughput, it may be good to return false - * for every component. - * - * @param connector - * @return true iff the widget for given component should be lazy loaded by - * the client side engine - */ - protected LoadStyle getLoadStyle(Class connector) { - Connect annotation = connector.getAnnotation(Connect.class); - return annotation.loadStyle(); - } - - private void generateInstantiatorMethod( - SourceWriter sourceWriter, - Collection> connectorsHavingComponentAnnotation) { - - Collection> deferredWidgets = new LinkedList>(); - - // TODO detect if it would be noticably faster to instantiate with a - // lookup with index than with the hashmap - - sourceWriter.println("public void ensureInstantiator(Class classType) {"); - sourceWriter.println("if(!instmap.containsKey(classType)){"); - boolean first = true; - - ArrayList> lazyLoadedConnectors = new ArrayList>(); - - HashSet> connectorsWithInstantiator = new HashSet>(); - - for (Class class1 : connectorsHavingComponentAnnotation) { - Class clientClass = class1; - if (connectorsWithInstantiator.contains(clientClass)) { - continue; - } - if (clientClass == UIConnector.class) { - // Roots are not instantiated by widgetset - continue; - } - if (!first) { - sourceWriter.print(" else "); - } else { - first = false; - } - sourceWriter.print("if( classType == " + clientClass.getName() - + ".class) {"); - - String instantiator = "new WidgetInstantiator() {\n public " - + serverConnectorClassName - + " get() {\n return GWT.create(" + clientClass.getName() - + ".class );\n}\n}\n"; - - LoadStyle loadStyle = getLoadStyle(class1); - - if (loadStyle != LoadStyle.EAGER) { - sourceWriter - .print("ApplicationConfiguration.startWidgetLoading();\n" - + "GWT.runAsync( \n" - + "new WidgetLoader() { void addInstantiator() {instmap.put(" - + clientClass.getName() - + ".class," - + instantiator + ");}});\n"); - lazyLoadedConnectors.add(class1); - - if (loadStyle == LoadStyle.DEFERRED) { - deferredWidgets.add(class1); - } - - } else { - // widget implementation in initially loaded js script - sourceWriter.print("instmap.put("); - sourceWriter.print(clientClass.getName()); - sourceWriter.print(".class, "); - sourceWriter.print(instantiator); - sourceWriter.print(");"); - } - sourceWriter.print("}"); - connectorsWithInstantiator.add(clientClass); - } - - sourceWriter.println("}"); - - sourceWriter.println("}"); - - sourceWriter.println("public Class[] getDeferredLoadedConnectors() {"); - - sourceWriter.println("return new Class[] {"); - first = true; - for (Class class2 : deferredWidgets) { - if (!first) { - sourceWriter.println(","); - } - first = false; - sourceWriter.print(class2.getName() + ".class"); - } - - sourceWriter.println("};"); - sourceWriter.println("}"); - - // in constructor add a "thread" that lazyly loads lazy loaded widgets - // if communication to server idles - - // TODO an array of lazy loaded widgets - - // TODO an index of last ensured widget in array - - sourceWriter.println("public " + serverConnectorClassName - + " instantiate(Class classType) {"); - sourceWriter.indent(); - sourceWriter.println(serverConnectorClassName - + " p = super.instantiate(classType); if(p!= null) return p;"); - sourceWriter.println("return instmap.get(classType).get();"); - - sourceWriter.outdent(); - sourceWriter.println("}"); - - } - - /** - * - * @param logger - * logger to print messages to - * @param sourceWriter - * Source writer to output source code - * @param paintablesHavingWidgetAnnotation - * @throws UnableToCompleteException - */ - private void generateImplementationDetector( - TreeLogger logger, - SourceWriter sourceWriter, - Collection> paintablesHavingWidgetAnnotation) - throws UnableToCompleteException { - sourceWriter - .println("public Class " - + "getConnectorClassForServerSideClassName(String fullyQualifiedName) {"); - sourceWriter.indent(); - sourceWriter - .println("fullyQualifiedName = fullyQualifiedName.intern();"); - - // Keep track of encountered mappings to detect conflicts - Map, Class> mappings = new HashMap, Class>(); - - for (Class connectorClass : paintablesHavingWidgetAnnotation) { - Class clientConnectorClass = getClientConnectorClass(connectorClass); - - // Check for conflicts - Class prevousMapping = mappings.put( - clientConnectorClass, connectorClass); - if (prevousMapping != null) { - logger.log(Type.ERROR, - "Both " + connectorClass.getName() + " and " - + prevousMapping.getName() - + " have @Connect referring to " - + clientConnectorClass.getName() + "."); - throw new UnableToCompleteException(); - } - - sourceWriter.print("if ( fullyQualifiedName == \""); - sourceWriter.print(clientConnectorClass.getName()); - sourceWriter.print("\" ) { ensureInstantiator(" - + connectorClass.getName() + ".class); return "); - sourceWriter.print(connectorClass.getName()); - sourceWriter.println(".class;}"); - sourceWriter.print("else "); - } - sourceWriter.println("return " - + UnknownComponentConnector.class.getName() + ".class;"); - sourceWriter.outdent(); - sourceWriter.println("}"); - - } - - private static Class getClientConnectorClass( - Class connectorClass) { - Connect annotation = connectorClass.getAnnotation(Connect.class); - return (Class) annotation.value(); - } -} -- 2.39.5