Browse Source

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
tags/7.4.0.beta1
Johannes Dahlström 10 years ago
parent
commit
59cdaeddf3

+ 18
- 2
client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java View File

import com.vaadin.server.widgetsetutils.metadata.GeneratedSerializer; import com.vaadin.server.widgetsetutils.metadata.GeneratedSerializer;
import com.vaadin.server.widgetsetutils.metadata.OnStateChangeVisitor; import com.vaadin.server.widgetsetutils.metadata.OnStateChangeVisitor;
import com.vaadin.server.widgetsetutils.metadata.Property; 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.ServerRpcVisitor;
import com.vaadin.server.widgetsetutils.metadata.StateInitVisitor; import com.vaadin.server.widgetsetutils.metadata.StateInitVisitor;
import com.vaadin.server.widgetsetutils.metadata.TypeVisitor; import com.vaadin.server.widgetsetutils.metadata.TypeVisitor;
// this after the JS property data has been initialized // this after the JS property data has been initialized
writePropertyTypes(logger, w, bundle); writePropertyTypes(logger, w, bundle);
writeSerializers(logger, w, bundle); writeSerializers(logger, w, bundle);
writePresentationTypes(w, bundle);
writeDelegateToWidget(logger, w, bundle); writeDelegateToWidget(logger, w, bundle);
writeOnStateChangeHandlers(logger, w, bundle); writeOnStateChangeHandlers(logger, w, bundle);
} }
} }
} }


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, private void writePropertyTypes(TreeLogger logger, SplittingSourceWriter w,
ConnectorBundle bundle) { ConnectorBundle bundle) {
Set<Property> properties = bundle.getNeedsProperty(); Set<Property> properties = bundle.getNeedsProperty();
throws NotFoundException { throws NotFoundException {
List<TypeVisitor> visitors = Arrays.<TypeVisitor> asList( List<TypeVisitor> visitors = Arrays.<TypeVisitor> asList(
new ConnectorInitVisitor(), new StateInitVisitor(), new ConnectorInitVisitor(), new StateInitVisitor(),
new WidgetInitVisitor(), new RendererInitVisitor(),
new WidgetInitVisitor(), new RendererVisitor(),
new ClientRpcVisitor(), new ServerRpcVisitor(), new ClientRpcVisitor(), new ServerRpcVisitor(),
new OnStateChangeVisitor()); new OnStateChangeVisitor());
for (TypeVisitor typeVisitor : visitors) { for (TypeVisitor typeVisitor : visitors) {

+ 20
- 0
client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java View File

private final Set<JType> hasSerializeSupport = new HashSet<JType>(); private final Set<JType> hasSerializeSupport = new HashSet<JType>();
private final Set<JType> needsSerializeSupport = new HashSet<JType>(); private final Set<JType> needsSerializeSupport = new HashSet<JType>();
private final Map<JType, GeneratedSerializer> serializers = new HashMap<JType, GeneratedSerializer>(); 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> needsSuperClass = new HashSet<JClassType>();
private final Set<JClassType> needsGwtConstructor = new HashSet<JClassType>(); private final Set<JClassType> needsGwtConstructor = new HashSet<JClassType>();
return Collections.unmodifiableMap(serializers); 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) { private void setNeedsSuperclass(JClassType typeAsClass) {
if (!isNeedsSuperClass(typeAsClass)) { if (!isNeedsSuperClass(typeAsClass)) {
needsSuperClass.add(typeAsClass); needsSuperClass.add(typeAsClass);

+ 0
- 63
client-compiler/src/com/vaadin/server/widgetsetutils/metadata/RendererInitVisitor.java View File

/*
* 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);
}
}
}
}

+ 99
- 0
client-compiler/src/com/vaadin/server/widgetsetutils/metadata/RendererVisitor.java View File

/*
* 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());
}
}

+ 11
- 0
client/src/com/vaadin/client/metadata/TypeDataStore.java View File

.create(); .create();
private final FastStringMap<JsArrayString> delegateToWidgetProperties = FastStringMap private final FastStringMap<JsArrayString> delegateToWidgetProperties = FastStringMap
.create(); .create();
private final FastStringMap<Type> presentationTypes = FastStringMap
.create();


/** /**
* Maps connector class -> state property name -> hander method data * Maps connector class -> state property name -> hander method data
return get().delegateToWidgetProperties.get(type.getBaseTypeName()); 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, public void setDelegateToWidget(Class<?> clazz, String propertyName,
String delegateValue) { String delegateValue) {
Type type = getType(clazz); Type type = getType(clazz);
typeProperties.push(propertyName); 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) { public void setReturnType(Class<?> type, String methodName, Type returnType) {
returnTypes.put(new Method(getType(type), methodName).getLookupKey(), returnTypes.put(new Method(getType(type), methodName).getLookupKey(),
returnType); returnType);

+ 15
- 5
client/src/com/vaadin/client/ui/grid/renderers/AbstractRendererConnector.java View File

import com.vaadin.client.metadata.NoDataException; import com.vaadin.client.metadata.NoDataException;
import com.vaadin.client.metadata.Type; import com.vaadin.client.metadata.Type;
import com.vaadin.client.metadata.TypeData; 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.GridConnector;
import com.vaadin.client.ui.grid.Renderer; import com.vaadin.client.ui.grid.Renderer;




private Renderer<T> renderer = null; 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. * Returns the renderer associated with this renderer connector.
* <p> * <p>
*/ */
public T decode(JSONValue value) { public T decode(JSONValue value) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
T decodedValue = (T) JsonDecoder.decodeValue(new Type(getType()),
value, null, getConnection());
T decodedValue = (T) JsonDecoder.decodeValue(presentationType, value,
null, getConnection());
return decodedValue; return decodedValue;
} }


// TODO generate data type
protected abstract Class<T> getType();

@Override @Override
@Deprecated @Deprecated
protected void extend(ServerConnector target) { protected void extend(ServerConnector target) {

+ 0
- 5
client/src/com/vaadin/client/ui/grid/renderers/TextRendererConnector.java View File

public TextRenderer getRenderer() { public TextRenderer getRenderer() {
return (TextRenderer) super.getRenderer(); return (TextRenderer) super.getRenderer();
} }

@Override
public Class<String> getType() {
return String.class;
}
} }

+ 0
- 5
client/src/com/vaadin/client/ui/grid/renderers/UnsafeHtmlRendererConnector.java View File

public UnsafeHtmlRenderer getRenderer() { public UnsafeHtmlRenderer getRenderer() {
return (UnsafeHtmlRenderer) super.getRenderer(); return (UnsafeHtmlRenderer) super.getRenderer();
} }

@Override
public Class<String> getType() {
return String.class;
}
} }

+ 0
- 5
uitest/src/com/vaadin/tests/widgetset/client/grid/IntArrayRendererConnector.java View File

public IntArrayRenderer getRenderer() { public IntArrayRenderer getRenderer() {
return (IntArrayRenderer) super.getRenderer(); return (IntArrayRenderer) super.getRenderer();
} }

@Override
public Class<int[]> getType() {
return int[].class;
}
} }

+ 0
- 5
uitest/src/com/vaadin/tests/widgetset/client/grid/RowAwareRendererConnector.java View File

} }
} }


@Override
protected Class<Void> getType() {
return Void.class;
}

@Override @Override
protected Renderer<Void> createRenderer() { protected Renderer<Void> createRenderer() {
// cannot use the default createRenderer as RowAwareRenderer needs a // cannot use the default createRenderer as RowAwareRenderer needs a

Loading…
Cancel
Save