From 5c931588582025e983ef457b503a1d3c2e6d41b2 Mon Sep 17 00:00:00 2001 From: Johannes Dahlström Date: Thu, 10 Jul 2014 16:26:01 +0300 Subject: Generate type data for AbstractRendererConnector.createRenderer (#13334) The declared return type of the most-derived getRenderer method is stored to make the default createRenderer implementation work. This is identical to the way AbstractComponentConnector getWidget and createWidget work. Change-Id: I879e9e6739e366bd81773a1e65195336e0cdac6d --- .../ConnectorBundleLoaderFactory.java | 6 ++- .../widgetsetutils/metadata/ConnectorBundle.java | 6 +++ .../metadata/RendererInitVisitor.java | 63 ++++++++++++++++++++++ 3 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 client-compiler/src/com/vaadin/server/widgetsetutils/metadata/RendererInitVisitor.java (limited to 'client-compiler') diff --git a/client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java b/client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java index 5519dd1aae..e02317be78 100644 --- a/client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java +++ b/client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java @@ -61,6 +61,7 @@ import com.vaadin.server.widgetsetutils.metadata.ConnectorInitVisitor; import com.vaadin.server.widgetsetutils.metadata.GeneratedSerializer; import com.vaadin.server.widgetsetutils.metadata.OnStateChangeVisitor; import com.vaadin.server.widgetsetutils.metadata.Property; +import com.vaadin.server.widgetsetutils.metadata.RendererInitVisitor; import com.vaadin.server.widgetsetutils.metadata.ServerRpcVisitor; import com.vaadin.server.widgetsetutils.metadata.StateInitVisitor; import com.vaadin.server.widgetsetutils.metadata.TypeVisitor; @@ -1235,8 +1236,9 @@ public class ConnectorBundleLoaderFactory extends Generator { throws NotFoundException { List visitors = Arrays. asList( new ConnectorInitVisitor(), new StateInitVisitor(), - new WidgetInitVisitor(), new ClientRpcVisitor(), - new ServerRpcVisitor(), new OnStateChangeVisitor()); + new WidgetInitVisitor(), new RendererInitVisitor(), + new ClientRpcVisitor(), new ServerRpcVisitor(), + new OnStateChangeVisitor()); for (TypeVisitor typeVisitor : visitors) { typeVisitor.init(oracle); } diff --git a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java index 8bbcac4ecb..463bf00027 100644 --- a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java +++ b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java @@ -43,6 +43,7 @@ import com.vaadin.client.ComponentConnector; import com.vaadin.client.ServerConnector; import com.vaadin.client.communication.JSONSerializer; import com.vaadin.client.ui.UnknownComponentConnector; +import com.vaadin.client.ui.grid.renderers.AbstractRendererConnector; import com.vaadin.shared.communication.ClientRpc; import com.vaadin.shared.communication.ServerRpc; import com.vaadin.shared.ui.Connect; @@ -414,6 +415,11 @@ public class ConnectorBundle { return isConnected(type) && isType(type, ComponentConnector.class); } + public static boolean isConnectedRendererConnector(JClassType type) { + return isConnected(type) + && isType(type, AbstractRendererConnector.class); + } + private static boolean isInterfaceType(JClassType type, Class class1) { return type.isInterface() != null && isType(type, class1); } diff --git a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/RendererInitVisitor.java b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/RendererInitVisitor.java new file mode 100644 index 0000000000..ec68f05b8f --- /dev/null +++ b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/RendererInitVisitor.java @@ -0,0 +1,63 @@ +/* + * Copyright 2000-2014 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.metadata; + +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.JMethod; +import com.vaadin.client.ui.grid.renderers.AbstractRendererConnector; + +/** + * Generates type data for renderer connectors. Specifically, stores the return + * type of the overridden {@link AbstractRendererConnector#getRenderer() + * getRenderer} method to enable automatic creation of an instance of the proper + * renderer type. + * + * @see WidgetInitVisitor + * + * @since + * @author Vaadin Ltd + */ +public class RendererInitVisitor extends TypeVisitor { + + @Override + public void visitConnector(TreeLogger logger, JClassType type, + ConnectorBundle bundle) throws UnableToCompleteException { + + if (ConnectorBundle.isConnectedRendererConnector(type)) { + + // The class in which createRenderer is implemented + JClassType createRendererClass = ConnectorBundle + .findInheritedMethod(type, "createRenderer") + .getEnclosingType(); + + JMethod getRenderer = ConnectorBundle.findInheritedMethod(type, + "getRenderer"); + JClassType rendererType = getRenderer.getReturnType().isClass(); + + // Needs GWT constructor if createRenderer is not overridden + if (createRendererClass.getQualifiedSourceName().equals( + AbstractRendererConnector.class.getCanonicalName())) { + + bundle.setNeedsGwtConstructor(rendererType); + + // Also needs renderer type to find the right GWT constructor + bundle.setNeedsReturnType(type, getRenderer); + } + } + } +} -- cgit v1.2.3 From 59cdaeddf36f91b0e08464d7cd2beb3dd110445f Mon Sep 17 00:00:00 2001 From: Johannes Dahlström Date: Thu, 10 Jul 2014 19:28:14 +0300 Subject: Generate type data for AbstractRendererConnector.decode (#13334) The presentation type parameter is stored so that decode works without implementers having to implement a getType method. Change-Id: Ia2b9f977f2bf6ed006379cda5eeb61674dd92ee0 --- .../ConnectorBundleLoaderFactory.java | 20 ++++- .../widgetsetutils/metadata/ConnectorBundle.java | 20 +++++ .../metadata/RendererInitVisitor.java | 63 -------------- .../widgetsetutils/metadata/RendererVisitor.java | 99 ++++++++++++++++++++++ .../com/vaadin/client/metadata/TypeDataStore.java | 11 +++ .../grid/renderers/AbstractRendererConnector.java | 20 +++-- .../ui/grid/renderers/TextRendererConnector.java | 5 -- .../renderers/UnsafeHtmlRendererConnector.java | 5 -- .../client/grid/IntArrayRendererConnector.java | 5 -- .../client/grid/RowAwareRendererConnector.java | 5 -- 10 files changed, 163 insertions(+), 90 deletions(-) delete mode 100644 client-compiler/src/com/vaadin/server/widgetsetutils/metadata/RendererInitVisitor.java create mode 100644 client-compiler/src/com/vaadin/server/widgetsetutils/metadata/RendererVisitor.java (limited to 'client-compiler') diff --git a/client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java b/client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java index e02317be78..ab930310aa 100644 --- a/client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java +++ b/client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java @@ -61,7 +61,7 @@ import com.vaadin.server.widgetsetutils.metadata.ConnectorInitVisitor; import com.vaadin.server.widgetsetutils.metadata.GeneratedSerializer; import com.vaadin.server.widgetsetutils.metadata.OnStateChangeVisitor; import com.vaadin.server.widgetsetutils.metadata.Property; -import com.vaadin.server.widgetsetutils.metadata.RendererInitVisitor; +import com.vaadin.server.widgetsetutils.metadata.RendererVisitor; import com.vaadin.server.widgetsetutils.metadata.ServerRpcVisitor; import com.vaadin.server.widgetsetutils.metadata.StateInitVisitor; import com.vaadin.server.widgetsetutils.metadata.TypeVisitor; @@ -504,6 +504,7 @@ public class ConnectorBundleLoaderFactory extends Generator { // this after the JS property data has been initialized writePropertyTypes(logger, w, bundle); writeSerializers(logger, w, bundle); + writePresentationTypes(w, bundle); writeDelegateToWidget(logger, w, bundle); writeOnStateChangeHandlers(logger, w, bundle); } @@ -680,6 +681,21 @@ public class ConnectorBundleLoaderFactory extends Generator { } } + private void writePresentationTypes(SplittingSourceWriter w, + ConnectorBundle bundle) { + Map presentationTypes = bundle + .getPresentationTypes(); + for (Entry entry : presentationTypes.entrySet()) { + + w.print("store.setPresentationType("); + writeClassLiteral(w, entry.getKey()); + w.print(", "); + writeClassLiteral(w, entry.getValue()); + w.println(");"); + w.splitIfNeeded(); + } + } + private void writePropertyTypes(TreeLogger logger, SplittingSourceWriter w, ConnectorBundle bundle) { Set properties = bundle.getNeedsProperty(); @@ -1236,7 +1252,7 @@ public class ConnectorBundleLoaderFactory extends Generator { throws NotFoundException { List visitors = Arrays. asList( new ConnectorInitVisitor(), new StateInitVisitor(), - new WidgetInitVisitor(), new RendererInitVisitor(), + new WidgetInitVisitor(), new RendererVisitor(), new ClientRpcVisitor(), new ServerRpcVisitor(), new OnStateChangeVisitor()); for (TypeVisitor typeVisitor : visitors) { diff --git a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java index 463bf00027..80456cdf10 100644 --- a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java +++ b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java @@ -59,6 +59,7 @@ public class ConnectorBundle { private final Set hasSerializeSupport = new HashSet(); private final Set needsSerializeSupport = new HashSet(); private final Map serializers = new HashMap(); + private final Map presentationTypes = new HashMap(); private final Set needsSuperClass = new HashSet(); private final Set needsGwtConstructor = new HashSet(); @@ -306,6 +307,25 @@ public class ConnectorBundle { return Collections.unmodifiableMap(serializers); } + public void setPresentationType(JClassType type, JType presentationType) { + if (!hasPresentationType(type)) { + presentationTypes.put(type, presentationType); + } + } + + private boolean hasPresentationType(JClassType type) { + if (presentationTypes.containsKey(type)) { + return true; + } else { + return previousBundle != null + && previousBundle.hasPresentationType(type); + } + } + + public Map getPresentationTypes() { + return Collections.unmodifiableMap(presentationTypes); + } + private void setNeedsSuperclass(JClassType typeAsClass) { if (!isNeedsSuperClass(typeAsClass)) { needsSuperClass.add(typeAsClass); diff --git a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/RendererInitVisitor.java b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/RendererInitVisitor.java deleted file mode 100644 index ec68f05b8f..0000000000 --- a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/RendererInitVisitor.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2000-2014 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.metadata; - -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.JMethod; -import com.vaadin.client.ui.grid.renderers.AbstractRendererConnector; - -/** - * Generates type data for renderer connectors. Specifically, stores the return - * type of the overridden {@link AbstractRendererConnector#getRenderer() - * getRenderer} method to enable automatic creation of an instance of the proper - * renderer type. - * - * @see WidgetInitVisitor - * - * @since - * @author Vaadin Ltd - */ -public class RendererInitVisitor extends TypeVisitor { - - @Override - public void visitConnector(TreeLogger logger, JClassType type, - ConnectorBundle bundle) throws UnableToCompleteException { - - if (ConnectorBundle.isConnectedRendererConnector(type)) { - - // The class in which createRenderer is implemented - JClassType createRendererClass = ConnectorBundle - .findInheritedMethod(type, "createRenderer") - .getEnclosingType(); - - JMethod getRenderer = ConnectorBundle.findInheritedMethod(type, - "getRenderer"); - JClassType rendererType = getRenderer.getReturnType().isClass(); - - // Needs GWT constructor if createRenderer is not overridden - if (createRendererClass.getQualifiedSourceName().equals( - AbstractRendererConnector.class.getCanonicalName())) { - - bundle.setNeedsGwtConstructor(rendererType); - - // Also needs renderer type to find the right GWT constructor - bundle.setNeedsReturnType(type, getRenderer); - } - } - } -} diff --git a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/RendererVisitor.java b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/RendererVisitor.java new file mode 100644 index 0000000000..6c6d6d116c --- /dev/null +++ b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/RendererVisitor.java @@ -0,0 +1,99 @@ +/* + * Copyright 2000-2014 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.metadata; + +import com.google.gwt.core.ext.TreeLogger; +import com.google.gwt.core.ext.TreeLogger.Type; +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.vaadin.client.ui.grid.renderers.AbstractRendererConnector; + +/** + * Generates type data for renderer connectors. + *
    + *
  • Stores the return type of the overridden + * {@link AbstractRendererConnector#getRenderer() getRenderer} method to enable + * automatic creation of an instance of the proper renderer type. + *
  • Stores the presentation type of the connector to enable the + * {@link AbstractRendererConnector#decode(com.google.gwt.json.client.JSONValue) + * decode} method to work without having to implement a "getPresentationType" + * method. + *
+ * + * @see WidgetInitVisitor + * + * @since + * @author Vaadin Ltd + */ +public class RendererVisitor extends TypeVisitor { + + @Override + public void visitConnector(TreeLogger logger, JClassType type, + ConnectorBundle bundle) { + if (ConnectorBundle.isConnectedRendererConnector(type)) { + doRendererType(logger, type, bundle); + doPresentationType(logger, type, bundle); + } + } + + private static void doRendererType(TreeLogger logger, JClassType type, + ConnectorBundle bundle) { + // The class in which createRenderer is implemented + JClassType createRendererClass = ConnectorBundle.findInheritedMethod( + type, "createRenderer").getEnclosingType(); + + // Needs GWT constructor if createRenderer is not overridden + if (createRendererClass.getQualifiedSourceName().equals( + AbstractRendererConnector.class.getCanonicalName())) { + + JMethod getRenderer = ConnectorBundle.findInheritedMethod(type, + "getRenderer"); + JClassType rendererType = getRenderer.getReturnType().isClass(); + + bundle.setNeedsGwtConstructor(rendererType); + + // Also needs renderer type to find the right GWT constructor + bundle.setNeedsReturnType(type, getRenderer); + + logger.log(Type.DEBUG, "Renderer type of " + type + " is " + + rendererType); + } + } + + private void doPresentationType(TreeLogger logger, JClassType type, + ConnectorBundle bundle) { + JType presentationType = getPresentationType(type); + bundle.setPresentationType(type, presentationType); + + logger.log(Type.DEBUG, "Presentation type of " + type + " is " + + presentationType); + } + + private static JType getPresentationType(JClassType type) { + JClassType originalType = type; + while (type != null) { + if (type.getQualifiedBinaryName().equals( + AbstractRendererConnector.class.getName())) { + return type.isParameterized().getTypeArgs()[0]; + } + type = type.getSuperclass(); + } + throw new IllegalArgumentException("The type " + + originalType.getQualifiedSourceName() + " does not extend " + + AbstractRendererConnector.class.getName()); + } +} diff --git a/client/src/com/vaadin/client/metadata/TypeDataStore.java b/client/src/com/vaadin/client/metadata/TypeDataStore.java index 7aa952d0f2..9b1fd7d45c 100644 --- a/client/src/com/vaadin/client/metadata/TypeDataStore.java +++ b/client/src/com/vaadin/client/metadata/TypeDataStore.java @@ -37,6 +37,8 @@ public class TypeDataStore { .create(); private final FastStringMap delegateToWidgetProperties = FastStringMap .create(); + private final FastStringMap presentationTypes = FastStringMap + .create(); /** * Maps connector class -> state property name -> hander method data @@ -135,6 +137,10 @@ public class TypeDataStore { return get().delegateToWidgetProperties.get(type.getBaseTypeName()); } + public static Type getPresentationType(Class type) { + return get().presentationTypes.get(getType(type).getBaseTypeName()); + } + public void setDelegateToWidget(Class clazz, String propertyName, String delegateValue) { Type type = getType(clazz); @@ -150,6 +156,11 @@ public class TypeDataStore { typeProperties.push(propertyName); } + public void setPresentationType(Class type, Class presentationType) { + presentationTypes.put(getType(type).getBaseTypeName(), + getType(presentationType)); + } + public void setReturnType(Class type, String methodName, Type returnType) { returnTypes.put(new Method(getType(type), methodName).getLookupKey(), returnType); diff --git a/client/src/com/vaadin/client/ui/grid/renderers/AbstractRendererConnector.java b/client/src/com/vaadin/client/ui/grid/renderers/AbstractRendererConnector.java index 8a8712372f..cad5af97df 100644 --- a/client/src/com/vaadin/client/ui/grid/renderers/AbstractRendererConnector.java +++ b/client/src/com/vaadin/client/ui/grid/renderers/AbstractRendererConnector.java @@ -23,6 +23,7 @@ import com.vaadin.client.extensions.AbstractExtensionConnector; import com.vaadin.client.metadata.NoDataException; import com.vaadin.client.metadata.Type; import com.vaadin.client.metadata.TypeData; +import com.vaadin.client.metadata.TypeDataStore; import com.vaadin.client.ui.grid.GridConnector; import com.vaadin.client.ui.grid.Renderer; @@ -44,6 +45,18 @@ public abstract class AbstractRendererConnector extends private Renderer renderer = null; + private final Type presentationType = TypeDataStore + .getPresentationType(this.getClass()); + + protected AbstractRendererConnector() { + if (presentationType == null) { + throw new IllegalStateException( + "No presentation type found for " + + Util.getSimpleName(this) + + ". This may be caused by some unspecified problem in widgetset compilation."); + } + } + /** * Returns the renderer associated with this renderer connector. *

@@ -109,14 +122,11 @@ public abstract class AbstractRendererConnector extends */ public T decode(JSONValue value) { @SuppressWarnings("unchecked") - T decodedValue = (T) JsonDecoder.decodeValue(new Type(getType()), - value, null, getConnection()); + T decodedValue = (T) JsonDecoder.decodeValue(presentationType, value, + null, getConnection()); return decodedValue; } - // TODO generate data type - protected abstract Class getType(); - @Override @Deprecated protected void extend(ServerConnector target) { diff --git a/client/src/com/vaadin/client/ui/grid/renderers/TextRendererConnector.java b/client/src/com/vaadin/client/ui/grid/renderers/TextRendererConnector.java index 84b261415b..9ec609ae06 100644 --- a/client/src/com/vaadin/client/ui/grid/renderers/TextRendererConnector.java +++ b/client/src/com/vaadin/client/ui/grid/renderers/TextRendererConnector.java @@ -30,9 +30,4 @@ public class TextRendererConnector extends AbstractRendererConnector { public TextRenderer getRenderer() { return (TextRenderer) super.getRenderer(); } - - @Override - public Class getType() { - return String.class; - } } diff --git a/client/src/com/vaadin/client/ui/grid/renderers/UnsafeHtmlRendererConnector.java b/client/src/com/vaadin/client/ui/grid/renderers/UnsafeHtmlRendererConnector.java index 7d5b9e1c60..1d4a8c0384 100644 --- a/client/src/com/vaadin/client/ui/grid/renderers/UnsafeHtmlRendererConnector.java +++ b/client/src/com/vaadin/client/ui/grid/renderers/UnsafeHtmlRendererConnector.java @@ -40,9 +40,4 @@ public class UnsafeHtmlRendererConnector extends public UnsafeHtmlRenderer getRenderer() { return (UnsafeHtmlRenderer) super.getRenderer(); } - - @Override - public Class getType() { - return String.class; - } } diff --git a/uitest/src/com/vaadin/tests/widgetset/client/grid/IntArrayRendererConnector.java b/uitest/src/com/vaadin/tests/widgetset/client/grid/IntArrayRendererConnector.java index dc424e7606..d6873ac0a5 100644 --- a/uitest/src/com/vaadin/tests/widgetset/client/grid/IntArrayRendererConnector.java +++ b/uitest/src/com/vaadin/tests/widgetset/client/grid/IntArrayRendererConnector.java @@ -43,9 +43,4 @@ public class IntArrayRendererConnector extends AbstractRendererConnector public IntArrayRenderer getRenderer() { return (IntArrayRenderer) super.getRenderer(); } - - @Override - public Class getType() { - return int[].class; - } } diff --git a/uitest/src/com/vaadin/tests/widgetset/client/grid/RowAwareRendererConnector.java b/uitest/src/com/vaadin/tests/widgetset/client/grid/RowAwareRendererConnector.java index 9ee05cb036..3880bacae2 100644 --- a/uitest/src/com/vaadin/tests/widgetset/client/grid/RowAwareRendererConnector.java +++ b/uitest/src/com/vaadin/tests/widgetset/client/grid/RowAwareRendererConnector.java @@ -67,11 +67,6 @@ public class RowAwareRendererConnector extends AbstractRendererConnector { } } - @Override - protected Class getType() { - return Void.class; - } - @Override protected Renderer createRenderer() { // cannot use the default createRenderer as RowAwareRenderer needs a -- cgit v1.2.3