diff options
10 files changed, 163 insertions, 90 deletions
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<JClassType, JType> presentationTypes = bundle + .getPresentationTypes(); + for (Entry<JClassType, JType> 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<Property> properties = bundle.getNeedsProperty(); @@ -1236,7 +1252,7 @@ public class ConnectorBundleLoaderFactory extends Generator { throws NotFoundException { List<TypeVisitor> visitors = Arrays.<TypeVisitor> 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<JType> hasSerializeSupport = new HashSet<JType>(); private final Set<JType> needsSerializeSupport = new HashSet<JType>(); private final Map<JType, GeneratedSerializer> serializers = new HashMap<JType, GeneratedSerializer>(); + private final Map<JClassType, JType> presentationTypes = new HashMap<JClassType, JType>(); private final Set<JClassType> needsSuperClass = new HashSet<JClassType>(); private final Set<JClassType> needsGwtConstructor = new HashSet<JClassType>(); @@ -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<JClassType, JType> 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. + * <ul> + * <li>Stores the return type of the overridden + * {@link AbstractRendererConnector#getRenderer() getRenderer} method to enable + * automatic creation of an instance of the proper renderer type. + * <li>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. + * </ul> + * + * @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<JsArrayString> delegateToWidgetProperties = FastStringMap .create(); + private final FastStringMap<Type> 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<T> extends private Renderer<T> 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. * <p> @@ -109,14 +122,11 @@ public abstract class AbstractRendererConnector<T> 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<T> 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<String> { public TextRenderer getRenderer() { return (TextRenderer) super.getRenderer(); } - - @Override - public Class<String> 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<String> 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<int[]> public IntArrayRenderer getRenderer() { return (IntArrayRenderer) super.getRenderer(); } - - @Override - public Class<int[]> 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 @@ -68,11 +68,6 @@ public class RowAwareRendererConnector extends AbstractRendererConnector<Void> { } @Override - protected Class<Void> getType() { - return Void.class; - } - - @Override protected Renderer<Void> createRenderer() { // cannot use the default createRenderer as RowAwareRenderer needs a // reference to its connector - it has no "real" no-argument constructor |