summaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorLeif Åstrand <leif@vaadin.com>2012-08-22 17:07:22 +0300
committerLeif Åstrand <leif@vaadin.com>2012-08-22 19:25:32 +0300
commit02878bd07a38dc69fe415c7f60238817d2a7c434 (patch)
treeebae730a5108dca70be31039ebc6b30884436fa7 /client
parente345e1820aa0e0fe551cca86d6d28b906beb8937 (diff)
downloadvaadin-framework-02878bd07a38dc69fe415c7f60238817d2a7c434.tar.gz
vaadin-framework-02878bd07a38dc69fe415c7f60238817d2a7c434.zip
Use ConnectorBundle for JSON encoding and decoding (#9371)
Diffstat (limited to 'client')
-rw-r--r--client/src/com/vaadin/Vaadin.gwt.xml8
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java8
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/communication/JsonDecoder.java48
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/communication/JsonEncoder.java34
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/communication/SerializerMap.java44
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/communication/Type.java52
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/metadata/Invoker.java2
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/metadata/Property.java27
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/metadata/Type.java14
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/metadata/TypeDataStore.java69
10 files changed, 171 insertions, 135 deletions
diff --git a/client/src/com/vaadin/Vaadin.gwt.xml b/client/src/com/vaadin/Vaadin.gwt.xml
index fe9643232e..44357b24a0 100644
--- a/client/src/com/vaadin/Vaadin.gwt.xml
+++ b/client/src/com/vaadin/Vaadin.gwt.xml
@@ -23,14 +23,6 @@
<when-type-is class="com.google.gwt.core.client.impl.SchedulerImpl" />
</replace-with>
- <!-- Generators for serializators for classes used in communication between
- server and client -->
- <generate-with
- class="com.vaadin.terminal.gwt.widgetsetutils.SerializerMapGenerator">
- <when-type-is
- class="com.vaadin.terminal.gwt.client.communication.SerializerMap" />
- </generate-with>
-
<replace-with class="com.vaadin.terminal.gwt.client.VDebugConsole">
<when-type-is class="com.vaadin.terminal.gwt.client.Console" />
</replace-with>
diff --git a/client/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/client/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
index 9b58eb1295..7e1c505fe9 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
@@ -65,7 +65,6 @@ import com.vaadin.terminal.gwt.client.communication.HasJavaScriptConnectorHelper
import com.vaadin.terminal.gwt.client.communication.JsonDecoder;
import com.vaadin.terminal.gwt.client.communication.JsonEncoder;
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;
@@ -106,8 +105,6 @@ public class ApplicationConnection {
public static final char VAR_ESCAPE_CHARACTER = '\u001b';
- private static SerializerMap serializerMap;
-
/**
* A string that, if found in a non-JSON response to a UIDL request, will
* cause the browser to refresh the page. If followed by a colon, optional
@@ -215,7 +212,6 @@ public class ApplicationConnection {
rpcManager = GWT.create(RpcManager.class);
layoutManager = GWT.create(LayoutManager.class);
layoutManager.setConnection(this);
- serializerMap = GWT.create(SerializerMap.class);
}
public void init(WidgetSet widgetSet, ApplicationConfiguration cnf) {
@@ -2577,8 +2573,4 @@ public class ApplicationConnection {
LayoutManager getLayoutManager() {
return layoutManager;
}
-
- public SerializerMap getSerializerMap() {
- return serializerMap;
- }
}
diff --git a/client/src/com/vaadin/terminal/gwt/client/communication/JsonDecoder.java b/client/src/com/vaadin/terminal/gwt/client/communication/JsonDecoder.java
index ef5090ec18..a98d08c368 100644
--- a/client/src/com/vaadin/terminal/gwt/client/communication/JsonDecoder.java
+++ b/client/src/com/vaadin/terminal/gwt/client/communication/JsonDecoder.java
@@ -31,6 +31,8 @@ import com.google.gwt.json.client.JSONValue;
import com.vaadin.shared.Connector;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.ConnectorMap;
+import com.vaadin.terminal.gwt.client.metadata.NoDataException;
+import com.vaadin.terminal.gwt.client.metadata.Property;
import com.vaadin.terminal.gwt.client.metadata.Type;
/**
@@ -106,18 +108,42 @@ public class JsonDecoder {
private static Object decodeObject(Type type, JSONValue jsonValue,
Object target, ApplicationConnection connection) {
- JSONSerializer<Object> serializer = connection.getSerializerMap()
- .getSerializer(type.getBaseTypeName());
- // TODO handle case with no serializer found
- // Currently getSerializer throws exception if not found
-
- if (target != null && serializer instanceof DiffJSONSerializer<?>) {
- DiffJSONSerializer<Object> diffSerializer = (DiffJSONSerializer<Object>) serializer;
- diffSerializer.update(target, type, jsonValue, connection);
- return target;
+ JSONSerializer<Object> serializer = (JSONSerializer<Object>) type
+ .findSerializer();
+ if (serializer != null) {
+ if (target != null && serializer instanceof DiffJSONSerializer<?>) {
+ DiffJSONSerializer<Object> diffSerializer = (DiffJSONSerializer<Object>) serializer;
+ diffSerializer.update(target, type, jsonValue, connection);
+ return target;
+ } else {
+ Object object = serializer.deserialize(type, jsonValue,
+ connection);
+ return object;
+ }
} else {
- Object object = serializer.deserialize(type, jsonValue, connection);
- return object;
+ try {
+ Collection<Property> properties = type.getProperties();
+ if (target == null) {
+ target = type.createInstance();
+ }
+ JSONObject jsonObject = jsonValue.isObject();
+
+ for (Property property : properties) {
+ JSONValue encodedPropertyValue = jsonObject.get(property
+ .getName());
+ if (encodedPropertyValue == null) {
+ continue;
+ }
+ Object propertyReference = property.getValue(target);
+ Object decodedValue = decodeValue(property.getType(),
+ encodedPropertyValue, propertyReference, connection);
+ property.setValue(target, decodedValue);
+ }
+ return target;
+ } catch (NoDataException e) {
+ throw new RuntimeException("Can not deserialize "
+ + type.getSignature(), e);
+ }
}
}
diff --git a/client/src/com/vaadin/terminal/gwt/client/communication/JsonEncoder.java b/client/src/com/vaadin/terminal/gwt/client/communication/JsonEncoder.java
index 3730cad4c3..9b28da8b34 100644
--- a/client/src/com/vaadin/terminal/gwt/client/communication/JsonEncoder.java
+++ b/client/src/com/vaadin/terminal/gwt/client/communication/JsonEncoder.java
@@ -33,6 +33,9 @@ import com.vaadin.shared.Connector;
import com.vaadin.shared.JsonConstants;
import com.vaadin.shared.communication.UidlValue;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.metadata.NoDataException;
+import com.vaadin.terminal.gwt.client.metadata.Property;
+import com.vaadin.terminal.gwt.client.metadata.Type;
/**
* Encoder for converting RPC parameters and other values to JSON for transfer
@@ -99,12 +102,33 @@ public class JsonEncoder {
} else {
// Try to find a generated serializer object, class name is the
// type
- transportType = value.getClass().getName();
- JSONSerializer serializer = connection.getSerializerMap()
- .getSerializer(transportType);
+ Type type = new Type(value.getClass());
+
+ JSONSerializer<Object> serializer = (JSONSerializer<Object>) type
+ .findSerializer();
+ if (serializer != null) {
+ return serializer.serialize(value, connection);
+ } else {
+ try {
+ Collection<Property> properties = type.getProperties();
+
+ JSONObject jsonObject = new JSONObject();
+ for (Property property : properties) {
+ Object propertyValue = property.getValue(value);
+ JSONValue encodedPropertyValue = encode(
+ propertyValue, restrictToInternalTypes,
+ connection);
+ jsonObject.put(property.getName(),
+ encodedPropertyValue);
+ }
+ return jsonObject;
+
+ } catch (NoDataException e) {
+ throw new RuntimeException("Can not encode "
+ + type.getSignature(), e);
+ }
+ }
- // TODO handle case with no serializer found
- return serializer.serialize(value, connection);
}
}
}
diff --git a/client/src/com/vaadin/terminal/gwt/client/communication/SerializerMap.java b/client/src/com/vaadin/terminal/gwt/client/communication/SerializerMap.java
deleted file mode 100644
index 77df4c7b08..0000000000
--- a/client/src/com/vaadin/terminal/gwt/client/communication/SerializerMap.java
+++ /dev/null
@@ -1,44 +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.communication;
-
-/**
- * Provide a mapping from a type (communicated between the server and the
- * client) and a {@link JSONSerializer} instance.
- *
- * An implementation of this class is created at GWT compilation time by
- * SerializerMapGenerator, so this interface can be instantiated with
- * GWT.create().
- *
- * @since 7.0
- */
-public interface SerializerMap {
-
- /**
- * Returns a serializer instance for a given type.
- *
- * @param type
- * type communicated on between the server and the client
- * (currently fully qualified class name)
- * @return serializer instance, not null
- * @throws RuntimeException
- * if no serializer is found
- */
- // TODO better error handling in javadoc and in generator
- public JSONSerializer getSerializer(String type);
-
-}
diff --git a/client/src/com/vaadin/terminal/gwt/client/communication/Type.java b/client/src/com/vaadin/terminal/gwt/client/communication/Type.java
deleted file mode 100644
index ff93234a1d..0000000000
--- a/client/src/com/vaadin/terminal/gwt/client/communication/Type.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.communication;
-
-public class Type {
- private final String baseTypeName;
- private final Type[] parameterTypes;
-
- public Type(String baseTypeName, Type[] parameterTypes) {
- this.baseTypeName = baseTypeName;
- this.parameterTypes = parameterTypes;
- }
-
- public String getBaseTypeName() {
- return baseTypeName;
- }
-
- public Type[] getParameterTypes() {
- return parameterTypes;
- }
-
- @Override
- public String toString() {
- String string = baseTypeName;
- if (parameterTypes != null) {
- string += '<';
- for (int i = 0; i < parameterTypes.length; i++) {
- if (i != 0) {
- string += ',';
- }
- string += parameterTypes[i].toString();
- }
- string += '>';
- }
-
- return string;
- }
-
-}
diff --git a/client/src/com/vaadin/terminal/gwt/client/metadata/Invoker.java b/client/src/com/vaadin/terminal/gwt/client/metadata/Invoker.java
index 5f6a839da6..33e8776429 100644
--- a/client/src/com/vaadin/terminal/gwt/client/metadata/Invoker.java
+++ b/client/src/com/vaadin/terminal/gwt/client/metadata/Invoker.java
@@ -5,5 +5,5 @@
package com.vaadin.terminal.gwt.client.metadata;
public interface Invoker {
- public Object invoke(Object target, Object[] params);
+ public Object invoke(Object target, Object... params);
}
diff --git a/client/src/com/vaadin/terminal/gwt/client/metadata/Property.java b/client/src/com/vaadin/terminal/gwt/client/metadata/Property.java
index 30d864a43f..082d032e64 100644
--- a/client/src/com/vaadin/terminal/gwt/client/metadata/Property.java
+++ b/client/src/com/vaadin/terminal/gwt/client/metadata/Property.java
@@ -5,16 +5,20 @@
package com.vaadin.terminal.gwt.client.metadata;
public class Property {
- private final Type type;
+ private final Type bean;
private final String name;
- public Property(Type type, String name) {
- this.type = type;
+ public Property(Type bean, String name) {
+ this.bean = bean;
this.name = name;
}
public Object getValue(Object bean) throws NoDataException {
- return TypeDataStore.getGetter(this).invoke(bean, null);
+ return TypeDataStore.getGetter(this).invoke(bean);
+ }
+
+ public void setValue(Object bean, Object value) throws NoDataException {
+ TypeDataStore.getSetter(this).invoke(bean, value);
}
public String getDelegateToWidgetMethod() {
@@ -29,8 +33,12 @@ public class Property {
}
}
+ public Type getType() throws NoDataException {
+ return TypeDataStore.getType(this);
+ }
+
public String getSignature() {
- return type.toString() + "." + name;
+ return bean.toString() + "." + name;
}
@Override
@@ -50,4 +58,13 @@ public class Property {
return getSignature().hashCode();
}
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public String toString() {
+ return getSignature();
+ }
+
}
diff --git a/client/src/com/vaadin/terminal/gwt/client/metadata/Type.java b/client/src/com/vaadin/terminal/gwt/client/metadata/Type.java
index 2dc5182845..d869cc2599 100644
--- a/client/src/com/vaadin/terminal/gwt/client/metadata/Type.java
+++ b/client/src/com/vaadin/terminal/gwt/client/metadata/Type.java
@@ -3,6 +3,10 @@
*/
package com.vaadin.terminal.gwt.client.metadata;
+import java.util.Collection;
+
+import com.vaadin.terminal.gwt.client.communication.JSONSerializer;
+
public class Type {
private final String name;
private final Type[] parameterTypes;
@@ -27,13 +31,17 @@ public class Type {
public Object createInstance() throws NoDataException {
Invoker invoker = TypeDataStore.getConstructor(this);
- return invoker.invoke(null, null);
+ return invoker.invoke(null);
}
public Method getMethod(String name) {
return new Method(this, name);
}
+ public Collection<Property> getProperties() throws NoDataException {
+ return TypeDataStore.getProperties(this);
+ }
+
public Property getProperty(String propertyName) {
return new Property(this, propertyName);
}
@@ -82,4 +90,8 @@ public class Type {
.createProxy(invokationHandler);
}
+ public JSONSerializer<?> findSerializer() {
+ return TypeDataStore.findSerializer(this);
+ }
+
}
diff --git a/client/src/com/vaadin/terminal/gwt/client/metadata/TypeDataStore.java b/client/src/com/vaadin/terminal/gwt/client/metadata/TypeDataStore.java
index f056e46d2d..55740f69da 100644
--- a/client/src/com/vaadin/terminal/gwt/client/metadata/TypeDataStore.java
+++ b/client/src/com/vaadin/terminal/gwt/client/metadata/TypeDataStore.java
@@ -4,17 +4,23 @@
package com.vaadin.terminal.gwt.client.metadata;
+import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+import com.vaadin.terminal.gwt.client.communication.JSONSerializer;
+
public class TypeDataStore {
private static final String CONSTRUCTOR_NAME = "!new";
private final Map<String, Class<?>> identifiers = new HashMap<String, Class<?>>();
+ private final Map<Type, Invoker> serializerFactories = new HashMap<Type, Invoker>();
private final Map<Type, ProxyHandler> proxyHandlers = new HashMap<Type, ProxyHandler>();
+ private final Map<Type, Collection<Property>> properties = new HashMap<Type, Collection<Property>>();
private final Set<Method> delayedMethods = new HashSet<Method>();
private final Set<Method> lastonlyMethods = new HashSet<Method>();
@@ -23,6 +29,8 @@ public class TypeDataStore {
private final Map<Method, Invoker> invokers = new HashMap<Method, Invoker>();
private final Map<Method, Type[]> paramTypes = new HashMap<Method, Type[]>();
+ private final Map<Property, Type> propertyTypes = new HashMap<Property, Type>();
+ private final Map<Property, Invoker> setters = new HashMap<Property, Invoker>();
private final Map<Property, Invoker> getters = new HashMap<Property, Invoker>();
private final Map<Property, String> delegateToWidget = new HashMap<Property, String>();
@@ -85,6 +93,10 @@ public class TypeDataStore {
return getter;
}
+ public void setGetter(Class<?> clazz, String propertyName, Invoker invoker) {
+ getters.put(new Property(getType(clazz), propertyName), invoker);
+ }
+
public static String getDelegateToWidget(Property property) {
return get().delegateToWidget.get(property);
}
@@ -148,4 +160,61 @@ public class TypeDataStore {
public void setLastonly(Class<?> clazz, String methodName) {
lastonlyMethods.add(getType(clazz).getMethod(methodName));
}
+
+ public static Collection<Property> getProperties(Type type)
+ throws NoDataException {
+ Collection<Property> properties = get().properties.get(type);
+ if (properties == null) {
+ throw new NoDataException("No property list for "
+ + type.getSignature());
+ }
+ return properties;
+ }
+
+ public void setProperties(Class<?> clazz, String[] propertyNames) {
+ Set<Property> properties = new HashSet<Property>();
+ Type type = getType(clazz);
+ for (String name : propertyNames) {
+ properties.add(new Property(type, name));
+ }
+ this.properties.put(type, Collections.unmodifiableSet(properties));
+ }
+
+ public static Type getType(Property property) throws NoDataException {
+ Type type = get().propertyTypes.get(property);
+ if (type == null) {
+ throw new NoDataException("No return type for "
+ + property.getSignature());
+ }
+ return type;
+ }
+
+ public void setPropertyType(Class<?> clazz, String propertName, Type type) {
+ propertyTypes.put(new Property(getType(clazz), propertName), type);
+ }
+
+ public static Invoker getSetter(Property property) throws NoDataException {
+ Invoker setter = get().setters.get(property);
+ if (setter == null) {
+ throw new NoDataException("No setter for "
+ + property.getSignature());
+ }
+ return setter;
+ }
+
+ public void setSetter(Class<?> clazz, String propertyName, Invoker setter) {
+ setters.put(new Property(getType(clazz), propertyName), setter);
+ }
+
+ public void setSerializerFactory(Class<?> clazz, Invoker factory) {
+ serializerFactories.put(getType(clazz), factory);
+ }
+
+ public static JSONSerializer<?> findSerializer(Type type) {
+ Invoker factoryCreator = get().serializerFactories.get(type);
+ if (factoryCreator == null) {
+ return null;
+ }
+ return (JSONSerializer<?>) factoryCreator.invoke(null);
+ }
}