From a34ddd875812ca2c3d1006555a33b72a4e438da3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Leif=20=C3=85strand?= Date: Fri, 17 Aug 2012 19:22:16 +0300 Subject: [PATCH] Use ConnectorBundle for creating state and widget (#9371) --- ...ctConnectorClassBasedFactoryGenerator.java | 157 ------------------ .../ConnectorBundleLoaderFactory.java | 47 +++++- .../ConnectorStateFactoryGenerator.java | 41 ----- .../ConnectorWidgetFactoryGenerator.java | 41 ----- .../metadata/ConnectorBundle.java | 66 +++++++- .../metadata/ConnectorInitVisitor.java | 16 +- .../metadata/StateInitVisitor.java | 25 +++ .../widgetsetutils/metadata/TypeVisitor.java | 51 +++++- .../metadata/WidgetInitVisitor.java | 25 +++ client/src/com/vaadin/Vaadin.gwt.xml | 12 -- .../gwt/client/ApplicationConnection.java | 5 + .../metadata/ConnectorBundleLoader.java | 4 +- .../client/ui/AbstractComponentConnector.java | 7 +- .../gwt/client/ui/AbstractConnector.java | 7 +- .../client/ui/ConnectorClassBasedFactory.java | 52 ------ .../gwt/client/ui/ConnectorStateFactory.java | 43 ----- .../gwt/client/ui/ConnectorWidgetFactory.java | 55 ------ 17 files changed, 216 insertions(+), 438 deletions(-) delete mode 100644 client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/AbstractConnectorClassBasedFactoryGenerator.java delete mode 100644 client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/ConnectorStateFactoryGenerator.java delete mode 100644 client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/ConnectorWidgetFactoryGenerator.java create mode 100644 client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/metadata/StateInitVisitor.java create mode 100644 client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/metadata/WidgetInitVisitor.java delete mode 100644 client/src/com/vaadin/terminal/gwt/client/ui/ConnectorClassBasedFactory.java delete mode 100644 client/src/com/vaadin/terminal/gwt/client/ui/ConnectorStateFactory.java delete mode 100644 client/src/com/vaadin/terminal/gwt/client/ui/ConnectorWidgetFactory.java diff --git a/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/AbstractConnectorClassBasedFactoryGenerator.java b/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/AbstractConnectorClassBasedFactoryGenerator.java deleted file mode 100644 index 78579b7e54..0000000000 --- a/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/AbstractConnectorClassBasedFactoryGenerator.java +++ /dev/null @@ -1,157 +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.terminal.gwt.widgetsetutils; - -import java.io.PrintWriter; -import java.util.Date; - -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.TreeLogger.Type; -import com.google.gwt.core.ext.UnableToCompleteException; -import com.google.gwt.core.ext.typeinfo.JClassType; -import com.google.gwt.core.ext.typeinfo.JMethod; -import com.google.gwt.core.ext.typeinfo.JType; -import com.google.gwt.core.ext.typeinfo.NotFoundException; -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.terminal.gwt.client.ServerConnector; -import com.vaadin.terminal.gwt.client.ui.ConnectorClassBasedFactory; -import com.vaadin.terminal.gwt.client.ui.ConnectorClassBasedFactory.Creator; - -/** - * GWT generator that creates a lookup method for - * {@link ConnectorClassBasedFactory} instances. - * - * @since 7.0 - */ -public abstract class AbstractConnectorClassBasedFactoryGenerator extends - Generator { - - @Override - public String generate(TreeLogger logger, GeneratorContext context, - String typeName) throws UnableToCompleteException { - - try { - // get classType and save instance variables - return generateConnectorClassBasedFactory(typeName, logger, context); - } catch (Exception e) { - logger.log(TreeLogger.ERROR, typeName + " creation failed", e); - throw new UnableToCompleteException(); - } - } - - private String generateConnectorClassBasedFactory(String typeName, - TreeLogger logger, GeneratorContext context) - throws NotFoundException { - TypeOracle typeOracle = context.getTypeOracle(); - - JClassType classType = typeOracle.getType(typeName); - String superName = classType.getSimpleSourceName(); - String packageName = classType.getPackage().getName(); - String className = superName + "Impl"; - - // 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 - if (printWriter == null) { - return packageName + "." + className; - } - - Date date = new Date(); - - // init composer, set class properties, create source writer - ClassSourceFileComposerFactory composer = null; - composer = new ClassSourceFileComposerFactory(packageName, className); - composer.addImport(GWT.class.getName()); - composer.addImport(Creator.class.getCanonicalName()); - composer.setSuperclass(superName); - - SourceWriter sourceWriter = composer.createSourceWriter(context, - printWriter); - sourceWriter.indent(); - - // public ConnectorStateFactoryImpl() { - sourceWriter.println("public " + className + "() {"); - sourceWriter.indent(); - - JClassType serverConnectorType = typeOracle.getType(getConnectorType() - .getCanonicalName()); - for (JClassType connector : serverConnectorType.getSubtypes()) { - // addCreator(TextAreaConnector.class, new Creator() { - if (connector.isInterface() != null || connector.isAbstract()) { - continue; - } - - JClassType targetType = getTargetType(connector); - if (targetType.isAbstract()) { - continue; - } - - sourceWriter.println("addCreator(" - + connector.getQualifiedSourceName() - + ".class, new Creator<" - + targetType.getQualifiedSourceName() + ">() {"); - // public SharedState create() { - sourceWriter.println("public " - + targetType.getQualifiedSourceName() + " create() {"); - // return GWT.create(TextAreaState.class); - sourceWriter.println("return GWT.create(" - + targetType.getQualifiedSourceName() + ".class);"); - // } - sourceWriter.println("}"); - // }); - sourceWriter.println("});"); - } - - // End of constructor - sourceWriter.outdent(); - sourceWriter.println("}"); - - // 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)"); - return packageName + "." + className; - - } - - protected abstract Class getConnectorType(); - - protected abstract JClassType getTargetType(JClassType connectorType); - - protected JClassType getGetterReturnType(JClassType connector, - String getterName) { - try { - JMethod getMethod = connector.getMethod(getterName, new JType[] {}); - return (JClassType) getMethod.getReturnType(); - } catch (NotFoundException e) { - return getGetterReturnType(connector.getSuperclass(), getterName); - } - - } - -} diff --git a/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/ConnectorBundleLoaderFactory.java b/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/ConnectorBundleLoaderFactory.java index cb967dff86..893bebfd0d 100644 --- a/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/ConnectorBundleLoaderFactory.java +++ b/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/ConnectorBundleLoaderFactory.java @@ -22,6 +22,7 @@ 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.JMethod; import com.google.gwt.core.ext.typeinfo.NotFoundException; import com.google.gwt.core.ext.typeinfo.TypeOracle; import com.google.gwt.user.rebind.ClassSourceFileComposerFactory; @@ -36,7 +37,9 @@ import com.vaadin.terminal.gwt.client.metadata.TypeDataBundle; import com.vaadin.terminal.gwt.client.metadata.TypeDataStore; import com.vaadin.terminal.gwt.widgetsetutils.metadata.ConnectorBundle; import com.vaadin.terminal.gwt.widgetsetutils.metadata.ConnectorInitVisitor; +import com.vaadin.terminal.gwt.widgetsetutils.metadata.StateInitVisitor; import com.vaadin.terminal.gwt.widgetsetutils.metadata.TypeVisitor; +import com.vaadin.terminal.gwt.widgetsetutils.metadata.WidgetInitVisitor; public class ConnectorBundleLoaderFactory extends Generator { @@ -158,6 +161,30 @@ public class ConnectorBundleLoaderFactory extends Generator { private void printBundleData(SourceWriter w, ConnectorBundle bundle) { writeIdentifiers(w, bundle); writeGwtConstructors(w, bundle); + writeReturnTypes(w, bundle); + } + + private void writeReturnTypes(SourceWriter w, ConnectorBundle bundle) { + Map> methodReturnTypes = bundle + .getMethodReturnTypes(); + for (Entry> entry : methodReturnTypes + .entrySet()) { + JClassType type = entry.getKey(); + + Set methods = entry.getValue(); + for (JMethod method : methods) { + // setReturnType(Class type, String methodName, Type + // returnType) + w.print("store.setReturnType("); + printClassLiteral(w, type); + w.print(", \""); + w.print(method.getName()); + w.print("\", "); + GeneratedRpcMethodProviderGenerator.writeTypeCreator(w, + method.getReturnType()); + w.println(");"); + } + } } private void writeGwtConstructors(SourceWriter w, ConnectorBundle bundle) { @@ -206,7 +233,8 @@ public class ConnectorBundleLoaderFactory extends Generator { } private List buildBundles(TreeLogger logger, - TypeOracle typeOracle) throws NotFoundException { + TypeOracle typeOracle) throws NotFoundException, + UnableToCompleteException { Map> connectorsByLoadStyle = new HashMap>(); for (LoadStyle loadStyle : LoadStyle.values()) { @@ -234,18 +262,18 @@ public class ConnectorBundleLoaderFactory extends Generator { ConnectorBundleLoader.EAGER_BUNDLE_NAME, null); // Eager connectors and all RPC interfaces are loaded by default - eagerBundle.visitTypes(connectorsByLoadStyle.get(LoadStyle.EAGER), - visitors); - eagerBundle.visitSubTypes( + eagerBundle.visitTypes(logger, + connectorsByLoadStyle.get(LoadStyle.EAGER), visitors); + eagerBundle.visitSubTypes(logger, typeOracle.getType(ClientRpc.class.getName()), visitors); - eagerBundle.visitSubTypes( + eagerBundle.visitSubTypes(logger, typeOracle.getType(ServerRpc.class.getName()), visitors); bundles.add(eagerBundle); ConnectorBundle deferredBundle = new ConnectorBundle( ConnectorBundleLoader.DEFERRED_BUNDLE_NAME, eagerBundle); - deferredBundle.visitTypes( + deferredBundle.visitTypes(logger, connectorsByLoadStyle.get(LoadStyle.DEFERRED), visitors); bundles.add(deferredBundle); @@ -254,7 +282,7 @@ public class ConnectorBundleLoaderFactory extends Generator { for (JClassType type : lazy) { ConnectorBundle bundle = new ConnectorBundle(type.getName(), deferredBundle); - bundle.visitTypes(Collections.singleton(type), visitors); + bundle.visitTypes(logger, Collections.singleton(type), visitors); bundles.add(bundle); } @@ -264,8 +292,9 @@ public class ConnectorBundleLoaderFactory extends Generator { private Collection getVisitors(TypeOracle oracle) throws NotFoundException { - List visitors = Arrays - . asList(new ConnectorInitVisitor()); + List visitors = Arrays. asList( + new ConnectorInitVisitor(), new StateInitVisitor(), + new WidgetInitVisitor()); for (TypeVisitor typeVisitor : visitors) { typeVisitor.init(oracle); } diff --git a/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/ConnectorStateFactoryGenerator.java b/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/ConnectorStateFactoryGenerator.java deleted file mode 100644 index 136ea3360e..0000000000 --- a/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/ConnectorStateFactoryGenerator.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.terminal.gwt.widgetsetutils; - -import com.google.gwt.core.ext.typeinfo.JClassType; -import com.vaadin.terminal.gwt.client.ServerConnector; - -/** - * GWT generator that creates a SharedState class for a given Connector class, - * based on the return type of getState() - * - * @since 7.0 - */ -public class ConnectorStateFactoryGenerator extends - AbstractConnectorClassBasedFactoryGenerator { - - @Override - protected JClassType getTargetType(JClassType connectorType) { - return getGetterReturnType(connectorType, "getState"); - } - - @Override - protected Class getConnectorType() { - return ServerConnector.class; - } - -} diff --git a/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/ConnectorWidgetFactoryGenerator.java b/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/ConnectorWidgetFactoryGenerator.java deleted file mode 100644 index 32693369f2..0000000000 --- a/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/ConnectorWidgetFactoryGenerator.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.terminal.gwt.widgetsetutils; - -import com.google.gwt.core.ext.typeinfo.JClassType; -import com.vaadin.terminal.gwt.client.ComponentConnector; -import com.vaadin.terminal.gwt.client.ServerConnector; - -/** - * GWT generator that creates a Widget class for a given Connector class, based - * on the return type of getWidget() - * - * @since 7.0 - */ -public class ConnectorWidgetFactoryGenerator extends - AbstractConnectorClassBasedFactoryGenerator { - @Override - protected JClassType getTargetType(JClassType connectorType) { - return getGetterReturnType(connectorType, "getWidget"); - } - - @Override - protected Class getConnectorType() { - return ComponentConnector.class; - } - -} \ No newline at end of file diff --git a/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/metadata/ConnectorBundle.java b/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/metadata/ConnectorBundle.java index 3155ab4474..f734b77101 100644 --- a/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/metadata/ConnectorBundle.java +++ b/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/metadata/ConnectorBundle.java @@ -12,7 +12,12 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; +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.JMethod; +import com.google.gwt.core.ext.typeinfo.NotFoundException; public class ConnectorBundle { private final String name; @@ -22,6 +27,9 @@ public class ConnectorBundle { private final Map> identifiers = new HashMap>(); private final Set visitedTypes = new HashSet(); private final Set visitQueue = new HashSet(); + private final Map> needsReturnType = new HashMap>(); + + private boolean visiting = false; public ConnectorBundle(String name, ConnectorBundle previousBundle) { this.name = name; @@ -30,6 +38,9 @@ public class ConnectorBundle { public void setNeedsGwtConstructor(JClassType type) { if (!needsGwtConstructor(type)) { + if (!isTypeVisited(type)) { + visitQueue.add(type); + } needsGwtConstructor.add(type); } } @@ -45,6 +56,9 @@ public class ConnectorBundle { public void setIdentifier(JClassType type, String identifier) { if (!hasIdentifier(type, identifier)) { + if (!isTypeVisited(type)) { + visitQueue.add(type); + } Set set = identifiers.get(type); if (set == null) { set = new HashSet(); @@ -80,37 +94,71 @@ public class ConnectorBundle { return Collections.unmodifiableSet(needsGwtConstructor); } - public void visitTypes(Collection types, - Collection visitors) { + public void visitTypes(TreeLogger logger, Collection types, + Collection visitors) throws UnableToCompleteException { for (JClassType type : types) { if (!isTypeVisited(type)) { visitQueue.add(type); } } - visitQueue(visitors); + visitQueue(logger, visitors); } private boolean isTypeVisited(JClassType type) { if (visitedTypes.contains(type)) { return true; } else { - return previousBundle != null - && previousBundle.isTypeVisited(type); + return previousBundle != null && previousBundle.isTypeVisited(type); } } - private void visitQueue(Collection visitors) { + private void visitQueue(TreeLogger logger, Collection visitors) + throws UnableToCompleteException { while (!visitQueue.isEmpty()) { JClassType type = visitQueue.iterator().next(); for (TypeVisitor typeVisitor : visitors) { - typeVisitor.visit(type, this); + try { + typeVisitor.visit(type, this); + } catch (NotFoundException e) { + logger.log(Type.ERROR, e.getMessage(), e); + throw new UnableToCompleteException(); + } } visitQueue.remove(type); visitedTypes.add(type); } } - public void visitSubTypes(JClassType type, Collection visitors) { - visitTypes(Arrays.asList(type.getSubtypes()), visitors); + public void visitSubTypes(TreeLogger logger, JClassType type, + Collection visitors) throws UnableToCompleteException { + visitTypes(logger, Arrays.asList(type.getSubtypes()), visitors); + } + + public void setNeedsReturnType(JClassType type, JMethod method) { + if (!isNeedsReturnType(type, method)) { + if (!isTypeVisited(type)) { + visitQueue.add(type); + } + Set set = needsReturnType.get(type); + if (set == null) { + set = new HashSet(); + needsReturnType.put(type, set); + } + set.add(method); + } + } + + private boolean isNeedsReturnType(JClassType type, JMethod method) { + if (needsReturnType.containsKey(type) + && needsReturnType.get(type).contains(method)) { + return true; + } else { + return previousBundle != null + && previousBundle.isNeedsReturnType(type, method); + } + } + + public Map> getMethodReturnTypes() { + return Collections.unmodifiableMap(needsReturnType); } } \ No newline at end of file diff --git a/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/metadata/ConnectorInitVisitor.java b/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/metadata/ConnectorInitVisitor.java index a6e71c70d9..6dd840d612 100644 --- a/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/metadata/ConnectorInitVisitor.java +++ b/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/metadata/ConnectorInitVisitor.java @@ -5,24 +5,14 @@ package com.vaadin.terminal.gwt.widgetsetutils.metadata; import com.google.gwt.core.ext.typeinfo.JClassType; -import com.google.gwt.core.ext.typeinfo.NotFoundException; -import com.google.gwt.core.ext.typeinfo.TypeOracle; import com.vaadin.shared.ui.Connect; -import com.vaadin.terminal.gwt.client.ServerConnector; -public class ConnectorInitVisitor implements TypeVisitor { - - private JClassType serverConnector; - - @Override - public void init(TypeOracle oracle) throws NotFoundException { - serverConnector = oracle.getType(ServerConnector.class.getName()); - } +public class ConnectorInitVisitor extends TypeVisitor { @Override public void visit(JClassType type, ConnectorBundle bundle) { - Connect connectAnnotation = type.getAnnotation(Connect.class); - if (connectAnnotation != null && serverConnector.isAssignableFrom(type)) { + if (isConnectedConnector(type)) { + Connect connectAnnotation = type.getAnnotation(Connect.class); bundle.setIdentifier(type, connectAnnotation.value() .getCanonicalName()); bundle.setNeedsGwtConstructor(type); diff --git a/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/metadata/StateInitVisitor.java b/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/metadata/StateInitVisitor.java new file mode 100644 index 0000000000..b88afdf37a --- /dev/null +++ b/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/metadata/StateInitVisitor.java @@ -0,0 +1,25 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal.gwt.widgetsetutils.metadata; + +import com.google.gwt.core.ext.typeinfo.JClassType; +import com.google.gwt.core.ext.typeinfo.JMethod; +import com.google.gwt.core.ext.typeinfo.JType; +import com.google.gwt.core.ext.typeinfo.NotFoundException; + +public class StateInitVisitor extends TypeVisitor { + @Override + public void visit(JClassType type, ConnectorBundle bundle) + throws NotFoundException { + if (isConnectedConnector(type)) { + JMethod getState = getInheritedMethod(type, "getState"); + bundle.setNeedsReturnType(type, getState); + + JType stateType = getState.getReturnType(); + bundle.setNeedsGwtConstructor(stateType.isClass()); + } + } + +} diff --git a/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/metadata/TypeVisitor.java b/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/metadata/TypeVisitor.java index 6ed791fe86..163eda0675 100644 --- a/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/metadata/TypeVisitor.java +++ b/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/metadata/TypeVisitor.java @@ -5,11 +5,56 @@ package com.vaadin.terminal.gwt.widgetsetutils.metadata; import com.google.gwt.core.ext.typeinfo.JClassType; +import com.google.gwt.core.ext.typeinfo.JMethod; +import com.google.gwt.core.ext.typeinfo.JType; import com.google.gwt.core.ext.typeinfo.NotFoundException; import com.google.gwt.core.ext.typeinfo.TypeOracle; +import com.vaadin.shared.ui.Connect; +import com.vaadin.terminal.gwt.client.ComponentConnector; +import com.vaadin.terminal.gwt.client.ServerConnector; -public interface TypeVisitor { - public void init(TypeOracle oracle) throws NotFoundException; +public abstract class TypeVisitor { + private JClassType serverConnector; + private JClassType componentConnector; - public void visit(JClassType type, ConnectorBundle bundle); + public void init(TypeOracle oracle) throws NotFoundException { + serverConnector = oracle.getType(ServerConnector.class.getName()); + componentConnector = oracle.getType(ComponentConnector.class.getName()); + } + + public abstract void visit(JClassType type, ConnectorBundle bundle) + throws NotFoundException; + + protected boolean isConnectedConnector(JClassType type) { + return serverConnector.isAssignableFrom(type) + && type.isAnnotationPresent(Connect.class); + } + + protected boolean isConnectedComponentConnector(JClassType type) { + return componentConnector.isAssignableFrom(type) + && type.isAnnotationPresent(Connect.class); + } + + protected JMethod getInheritedMethod(JClassType type, String methodName, + JType... params) throws NotFoundException { + + JClassType currentType = type; + while (currentType != null) { + JMethod method = currentType.findMethod(methodName, params); + if (method != null) { + return method; + } + currentType = currentType.getSuperclass(); + } + + JClassType[] interfaces = type.getImplementedInterfaces(); + for (JClassType iface : interfaces) { + JMethod method = iface.findMethod(methodName, params); + if (method != null) { + return method; + } + } + + throw new NotFoundException(methodName + " not found in " + type); + } } diff --git a/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/metadata/WidgetInitVisitor.java b/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/metadata/WidgetInitVisitor.java new file mode 100644 index 0000000000..be6f303c5b --- /dev/null +++ b/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/metadata/WidgetInitVisitor.java @@ -0,0 +1,25 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal.gwt.widgetsetutils.metadata; + +import com.google.gwt.core.ext.typeinfo.JClassType; +import com.google.gwt.core.ext.typeinfo.JMethod; +import com.google.gwt.core.ext.typeinfo.JType; +import com.google.gwt.core.ext.typeinfo.NotFoundException; + +public class WidgetInitVisitor extends TypeVisitor { + + @Override + public void visit(JClassType type, ConnectorBundle bundle) + throws NotFoundException { + if (isConnectedComponentConnector(type)) { + JMethod getWidget = getInheritedMethod(type, "getWidget"); + bundle.setNeedsReturnType(type, getWidget); + + JType widgetType = getWidget.getReturnType(); + bundle.setNeedsGwtConstructor(widgetType.isClass()); + } + } +} diff --git a/client/src/com/vaadin/Vaadin.gwt.xml b/client/src/com/vaadin/Vaadin.gwt.xml index 5a9909a29c..4bac60b472 100644 --- a/client/src/com/vaadin/Vaadin.gwt.xml +++ b/client/src/com/vaadin/Vaadin.gwt.xml @@ -61,18 +61,6 @@ - - - - - - - - diff --git a/client/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/client/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java index 9a14e5434e..8ba8f0afab 100644 --- a/client/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java +++ b/client/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java @@ -68,6 +68,7 @@ import com.vaadin.terminal.gwt.client.communication.RpcManager; import com.vaadin.terminal.gwt.client.communication.SerializerMap; import com.vaadin.terminal.gwt.client.communication.StateChangeEvent; import com.vaadin.terminal.gwt.client.extensions.AbstractExtensionConnector; +import com.vaadin.terminal.gwt.client.metadata.ConnectorBundleLoader; import com.vaadin.terminal.gwt.client.metadata.Type; import com.vaadin.terminal.gwt.client.ui.AbstractComponentConnector; import com.vaadin.terminal.gwt.client.ui.VContextMenu; @@ -240,6 +241,10 @@ public class ApplicationConnection { initializeClientHooks(); + // Assuming Root data is eagerly loaded + ConnectorBundleLoader.get().loadBundle( + ConnectorBundleLoader.EAGER_BUNDLE_NAME, null); + rootConnector.init(cnf.getRootPanelId(), this); showLoadingIndicator(); } diff --git a/client/src/com/vaadin/terminal/gwt/client/metadata/ConnectorBundleLoader.java b/client/src/com/vaadin/terminal/gwt/client/metadata/ConnectorBundleLoader.java index 48a8430312..ab1462efc1 100644 --- a/client/src/com/vaadin/terminal/gwt/client/metadata/ConnectorBundleLoader.java +++ b/client/src/com/vaadin/terminal/gwt/client/metadata/ConnectorBundleLoader.java @@ -67,7 +67,9 @@ public abstract class ConnectorBundleLoader { List callbacks = asyncBlockLoaders.get(packageName) .setLoaded(); for (BundleLoadCallback callback : callbacks) { - callback.loaded(); + if (callback != null) { + callback.loaded(); + } } } diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/AbstractComponentConnector.java b/client/src/com/vaadin/terminal/gwt/client/ui/AbstractComponentConnector.java index 48842e29a0..4f14ee550b 100644 --- a/client/src/com/vaadin/terminal/gwt/client/ui/AbstractComponentConnector.java +++ b/client/src/com/vaadin/terminal/gwt/client/ui/AbstractComponentConnector.java @@ -37,6 +37,8 @@ import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.Util; import com.vaadin.terminal.gwt.client.VConsole; import com.vaadin.terminal.gwt.client.communication.StateChangeEvent; +import com.vaadin.terminal.gwt.client.metadata.Type; +import com.vaadin.terminal.gwt.client.metadata.TypeData; import com.vaadin.terminal.gwt.client.ui.datefield.PopupDateFieldConnector; import com.vaadin.terminal.gwt.client.ui.root.RootConnector; @@ -77,7 +79,10 @@ public abstract class AbstractComponentConnector extends AbstractConnector * @return */ protected Widget createWidget() { - return ConnectorWidgetFactory.createWidget(getClass()); + Type type = TypeData.getType(getClass()); + Type widgetType = type.getMethod("getWidget").getReturnType(); + Object instance = widgetType.createInstance(); + return (Widget) instance; } /** diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/AbstractConnector.java b/client/src/com/vaadin/terminal/gwt/client/ui/AbstractConnector.java index 435fff8a5b..9efa7bad0d 100644 --- a/client/src/com/vaadin/terminal/gwt/client/ui/AbstractConnector.java +++ b/client/src/com/vaadin/terminal/gwt/client/ui/AbstractConnector.java @@ -33,6 +33,8 @@ import com.vaadin.terminal.gwt.client.Util; import com.vaadin.terminal.gwt.client.VConsole; import com.vaadin.terminal.gwt.client.communication.StateChangeEvent; import com.vaadin.terminal.gwt.client.communication.StateChangeEvent.StateChangeHandler; +import com.vaadin.terminal.gwt.client.metadata.Type; +import com.vaadin.terminal.gwt.client.metadata.TypeData; /** * An abstract implementation of Connector. @@ -265,7 +267,10 @@ public abstract class AbstractConnector implements ServerConnector, * @return A new state object */ protected SharedState createState() { - return ConnectorStateFactory.createState(getClass()); + Type connectorType = TypeData.getType(getClass()); + Type stateType = connectorType.getMethod("getState").getReturnType(); + Object stateInstance = stateType.createInstance(); + return (SharedState) stateInstance; } @Override diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/ConnectorClassBasedFactory.java b/client/src/com/vaadin/terminal/gwt/client/ui/ConnectorClassBasedFactory.java deleted file mode 100644 index 698d8e6e61..0000000000 --- a/client/src/com/vaadin/terminal/gwt/client/ui/ConnectorClassBasedFactory.java +++ /dev/null @@ -1,52 +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.terminal.gwt.client.ui; - -import java.util.HashMap; -import java.util.Map; - -import com.vaadin.shared.Connector; - -public abstract class ConnectorClassBasedFactory { - public interface Creator { - public T create(); - } - - private Map, Creator> creators = new HashMap, Creator>(); - - protected void addCreator(Class cls, - Creator creator) { - creators.put(cls, creator); - } - - /** - * Creates a widget using GWT.create for the given connector, based on its - * {@link AbstractComponentConnector#getWidget()} return type. - * - * @param connector - * @return - */ - public T create(Class connector) { - Creator foo = creators.get(connector); - if (foo == null) { - throw new RuntimeException(getClass().getName() - + " could not find a creator for connector of type " - + connector.getName()); - } - return foo.create(); - } - -} diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/ConnectorStateFactory.java b/client/src/com/vaadin/terminal/gwt/client/ui/ConnectorStateFactory.java deleted file mode 100644 index b04daa6910..0000000000 --- a/client/src/com/vaadin/terminal/gwt/client/ui/ConnectorStateFactory.java +++ /dev/null @@ -1,43 +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.terminal.gwt.client.ui; - -import com.google.gwt.core.client.GWT; -import com.vaadin.shared.Connector; -import com.vaadin.shared.communication.SharedState; - -public abstract class ConnectorStateFactory extends - ConnectorClassBasedFactory { - private static ConnectorStateFactory impl = null; - - /** - * Creates a SharedState using GWT.create for the given connector, based on - * its {@link AbstractComponentConnector#getSharedState ()} return type. - * - * @param connector - * @return - */ - public static SharedState createState(Class connector) { - return getImpl().create(connector); - } - - private static ConnectorStateFactory getImpl() { - if (impl == null) { - impl = GWT.create(ConnectorStateFactory.class); - } - return impl; - } -} diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/ConnectorWidgetFactory.java b/client/src/com/vaadin/terminal/gwt/client/ui/ConnectorWidgetFactory.java deleted file mode 100644 index 073e36cabb..0000000000 --- a/client/src/com/vaadin/terminal/gwt/client/ui/ConnectorWidgetFactory.java +++ /dev/null @@ -1,55 +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.terminal.gwt.client.ui; - -import com.google.gwt.core.client.GWT; -import com.google.gwt.user.client.ui.Widget; -import com.vaadin.terminal.gwt.client.ui.textfield.TextFieldConnector; -import com.vaadin.terminal.gwt.client.ui.textfield.VTextField; - -public abstract class ConnectorWidgetFactory extends - ConnectorClassBasedFactory { - private static ConnectorWidgetFactory impl = null; - - // TODO Move to generator - { - addCreator(TextFieldConnector.class, new Creator() { - @Override - public Widget create() { - return GWT.create(VTextField.class); - } - }); - } - - /** - * Creates a widget using GWT.create for the given connector, based on its - * {@link AbstractComponentConnector#getWidget()} return type. - * - * @param connector - * @return - */ - public static Widget createWidget( - Class connector) { - return getImpl().create(connector); - } - - private static ConnectorWidgetFactory getImpl() { - if (impl == null) { - impl = GWT.create(ConnectorWidgetFactory.class); - } - return impl; - } -} -- 2.39.5