summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeif Åstrand <leif@vaadin.com>2012-08-21 12:33:32 +0300
committerLeif Åstrand <leif@vaadin.com>2012-08-22 19:25:31 +0300
commitbcef4d5e716a275f3a3588cd9e50885129d38eb7 (patch)
tree5bc17a54d1e6a804539793e4fa2a79615b263b73
parentd51dcf18b8d7f64f763163c5965ca30b8c33070d (diff)
downloadvaadin-framework-bcef4d5e716a275f3a3588cd9e50885129d38eb7.tar.gz
vaadin-framework-bcef4d5e716a275f3a3588cd9e50885129d38eb7.zip
Use ConnectorBundle for ClientRpc handling (#9371)
-rw-r--r--client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/ConnectorBundleLoaderFactory.java116
-rw-r--r--client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/GeneratedRpcMethodProviderGenerator.java223
-rw-r--r--client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/SerializerGenerator.java6
-rw-r--r--client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/metadata/ClientRpcVisitor.java39
-rw-r--r--client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/metadata/ConnectorBundle.java79
-rw-r--r--client/src/com/vaadin/Vaadin.gwt.xml7
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java11
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/WidgetSet.java21
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/communication/RpcManager.java53
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/communication/RpcMethod.java47
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/metadata/Method.java13
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/metadata/NoDataException.java (renamed from client/src/com/vaadin/terminal/gwt/client/communication/GeneratedRpcMethodProvider.java)21
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/metadata/Property.java2
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/metadata/Type.java4
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/metadata/TypeData.java8
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/metadata/TypeDataStore.java67
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/AbstractComponentConnector.java15
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/AbstractConnector.java17
18 files changed, 371 insertions, 378 deletions
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 e0c88ced66..b6a6e0bff4 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,8 @@ 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.JParameterizedType;
+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;
@@ -34,6 +36,7 @@ import com.vaadin.terminal.gwt.client.ServerConnector;
import com.vaadin.terminal.gwt.client.metadata.ConnectorBundleLoader;
import com.vaadin.terminal.gwt.client.metadata.TypeDataBundle;
import com.vaadin.terminal.gwt.client.metadata.TypeDataStore;
+import com.vaadin.terminal.gwt.widgetsetutils.metadata.ClientRpcVisitor;
import com.vaadin.terminal.gwt.widgetsetutils.metadata.ConnectorBundle;
import com.vaadin.terminal.gwt.widgetsetutils.metadata.ConnectorInitVisitor;
import com.vaadin.terminal.gwt.widgetsetutils.metadata.StateInitVisitor;
@@ -161,6 +164,85 @@ public class ConnectorBundleLoaderFactory extends Generator {
writeIdentifiers(w, bundle);
writeGwtConstructors(w, bundle);
writeReturnTypes(w, bundle);
+ writeInvokers(w, bundle);
+ writeParamTypes(w, bundle);
+ }
+
+ private void writeParamTypes(SourceWriter w, ConnectorBundle bundle) {
+ Map<JClassType, Set<JMethod>> needsParamTypes = bundle
+ .getNeedsParamTypes();
+ for (Entry<JClassType, Set<JMethod>> entry : needsParamTypes.entrySet()) {
+ JClassType type = entry.getKey();
+
+ Set<JMethod> methods = entry.getValue();
+ for (JMethod method : methods) {
+ w.println("store.setParamTypes(");
+ printClassLiteral(w, type);
+ w.print(", \"");
+ w.print(escape(method.getName()));
+ w.println("\", new Type[] {");
+
+ for (JType parameter : method.getParameterTypes()) {
+ ConnectorBundleLoaderFactory.writeTypeCreator(w, parameter);
+ w.print(", ");
+ }
+
+ w.println("});");
+
+ }
+ }
+ }
+
+ private void writeInvokers(SourceWriter w, ConnectorBundle bundle) {
+ Map<JClassType, Set<JMethod>> needsInvoker = bundle.getNeedsInvoker();
+ for (Entry<JClassType, Set<JMethod>> entry : needsInvoker.entrySet()) {
+ JClassType type = entry.getKey();
+
+ Set<JMethod> methods = entry.getValue();
+ for (JMethod method : methods) {
+ w.print("store.setInvoker(");
+ printClassLiteral(w, type);
+ w.print(", \"");
+ w.print(escape(method.getName()));
+ w.println("\", new Invoker() {");
+ w.indent();
+
+ w.println("public Object invoke(Object target, Object[] params) {");
+ w.indent();
+
+ JType returnType = method.getReturnType();
+ boolean hasReturnType = !"void".equals(returnType
+ .getQualifiedSourceName());
+ if (hasReturnType) {
+ w.print("return ");
+ }
+
+ JType[] parameterTypes = method.getParameterTypes();
+
+ w.print("((" + type.getQualifiedSourceName() + ") target)."
+ + method.getName() + "(");
+ for (int i = 0; i < parameterTypes.length; i++) {
+ JType parameterType = parameterTypes[i];
+ if (i != 0) {
+ w.print(", ");
+ }
+ String parameterTypeName = getBoxedTypeName(parameterType);
+ w.print("(" + parameterTypeName + ") params[" + i + "]");
+ }
+ w.println(");");
+
+ if (!hasReturnType) {
+ w.println("return null;");
+ }
+
+ w.outdent();
+ w.println("}");
+
+ w.outdent();
+ w.println("});");
+
+ }
+ }
}
private void writeReturnTypes(SourceWriter w, ConnectorBundle bundle) {
@@ -177,10 +259,9 @@ public class ConnectorBundleLoaderFactory extends Generator {
w.print("store.setReturnType(");
printClassLiteral(w, type);
w.print(", \"");
- w.print(method.getName());
+ w.print(escape(method.getName()));
w.print("\", ");
- GeneratedRpcMethodProviderGenerator.writeTypeCreator(w,
- method.getReturnType());
+ writeTypeCreator(w, method.getReturnType());
w.println(");");
}
}
@@ -299,7 +380,7 @@ public class ConnectorBundleLoaderFactory extends Generator {
throws NotFoundException {
List<TypeVisitor> visitors = Arrays.<TypeVisitor> asList(
new ConnectorInitVisitor(), new StateInitVisitor(),
- new WidgetInitVisitor());
+ new WidgetInitVisitor(), new ClientRpcVisitor());
for (TypeVisitor typeVisitor : visitors) {
typeVisitor.init(oracle);
}
@@ -311,4 +392,31 @@ public class ConnectorBundleLoaderFactory extends Generator {
return annotation.loadStyle();
}
+ public static String getBoxedTypeName(JType type) {
+ if (type.isPrimitive() != null) {
+ // Used boxed types for primitives
+ return type.isPrimitive().getQualifiedBoxedSourceName();
+ } else {
+ return type.getErasedType().getQualifiedSourceName();
+ }
+ }
+
+ public static void writeTypeCreator(SourceWriter sourceWriter, JType type) {
+ String typeName = ConnectorBundleLoaderFactory.getBoxedTypeName(type);
+ sourceWriter.print("new Type(\"" + typeName + "\", ");
+ JParameterizedType parameterized = type.isParameterized();
+ if (parameterized != null) {
+ sourceWriter.print("new Type[] {");
+ JClassType[] typeArgs = parameterized.getTypeArgs();
+ for (JClassType jClassType : typeArgs) {
+ writeTypeCreator(sourceWriter, jClassType);
+ sourceWriter.print(", ");
+ }
+ sourceWriter.print("}");
+ } else {
+ sourceWriter.print("null");
+ }
+ sourceWriter.print(")");
+ }
+
}
diff --git a/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/GeneratedRpcMethodProviderGenerator.java b/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/GeneratedRpcMethodProviderGenerator.java
deleted file mode 100644
index c6cf28db28..0000000000
--- a/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/GeneratedRpcMethodProviderGenerator.java
+++ /dev/null
@@ -1,223 +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.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-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.JParameterizedType;
-import com.google.gwt.core.ext.typeinfo.JType;
-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.shared.communication.ClientRpc;
-import com.vaadin.terminal.gwt.client.communication.GeneratedRpcMethodProvider;
-import com.vaadin.terminal.gwt.client.communication.RpcManager;
-import com.vaadin.terminal.gwt.client.communication.RpcMethod;
-
-/**
- * GWT generator that creates an implementation for {@link RpcManager} on the
- * client side classes for executing RPC calls received from the the server.
- *
- * @since 7.0
- */
-public class GeneratedRpcMethodProviderGenerator extends Generator {
-
- @Override
- public String generate(TreeLogger logger, GeneratorContext context,
- String typeName) throws UnableToCompleteException {
-
- String packageName = null;
- String className = null;
- try {
- TypeOracle typeOracle = context.getTypeOracle();
-
- // get classType and save instance variables
- JClassType classType = typeOracle.getType(typeName);
- packageName = classType.getPackage().getName();
- className = classType.getSimpleSourceName() + "Impl";
- // Generate class source code for SerializerMapImpl
- generateClass(logger, context, packageName, className);
- } catch (Exception e) {
- logger.log(TreeLogger.ERROR,
- "SerializerMapGenerator creation failed", e);
- }
- // return the fully qualifed name of the class generated
- return packageName + "." + className;
- }
-
- /**
- * Generate source code for RpcManagerImpl
- *
- * @param logger
- * Logger object
- * @param context
- * Generator context
- * @param packageName
- * package name for the class to generate
- * @param className
- * class name for the class to generate
- */
- private void generateClass(TreeLogger logger, GeneratorContext context,
- String packageName, String className) {
- // 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;
- }
- logger.log(Type.INFO,
- "Detecting server to client RPC interface types...");
- Date date = new Date();
- TypeOracle typeOracle = context.getTypeOracle();
- JClassType serverToClientRpcType = typeOracle.findType(ClientRpc.class
- .getName());
- JClassType[] rpcInterfaceSubtypes = serverToClientRpcType.getSubtypes();
-
- // init composer, set class properties, create source writer
- ClassSourceFileComposerFactory composer = null;
- composer = new ClassSourceFileComposerFactory(packageName, className);
- composer.addImport("com.google.gwt.core.client.GWT");
- composer.addImport(RpcMethod.class.getName());
- composer.addImport(ClientRpc.class.getName());
- composer.addImport(com.vaadin.terminal.gwt.client.metadata.Type.class
- .getName());
- composer.addImplementedInterface(GeneratedRpcMethodProvider.class
- .getName());
- SourceWriter sourceWriter = composer.createSourceWriter(context,
- printWriter);
- sourceWriter.indent();
-
- List<JMethod> rpcMethods = new ArrayList<JMethod>();
-
- sourceWriter
- .println("public java.util.Collection<RpcMethod> getGeneratedRpcMethods() {");
- sourceWriter.indent();
-
- sourceWriter
- .println("java.util.ArrayList<RpcMethod> list = new java.util.ArrayList<RpcMethod>();");
-
- // iterate over RPC interfaces and create helper methods for each
- // interface
- for (JClassType type : rpcInterfaceSubtypes) {
- if (null == type.isInterface()) {
- // only interested in interfaces here, not implementations
- continue;
- }
-
- // loop over the methods of the interface and its superinterfaces
- // methods
- for (JClassType currentType : type.getFlattenedSupertypeHierarchy()) {
- for (JMethod method : currentType.getMethods()) {
-
- // RpcMethod(String interfaceName, String methodName,
- // Type... parameterTypes)
- sourceWriter.print("list.add(new RpcMethod(\""
- + type.getQualifiedSourceName() + "\", \""
- + method.getName() + "\"");
- JType[] parameterTypes = method.getParameterTypes();
- for (JType parameter : parameterTypes) {
- sourceWriter.print(", ");
- writeTypeCreator(sourceWriter, parameter);
- }
- sourceWriter.println(") {");
- sourceWriter.indent();
-
- sourceWriter
- .println("public void applyInvocation(ClientRpc target, Object... parameters) {");
- sourceWriter.indent();
-
- sourceWriter.print("((" + type.getQualifiedSourceName()
- + ")target)." + method.getName() + "(");
- for (int i = 0; i < parameterTypes.length; i++) {
- JType parameterType = parameterTypes[i];
- if (i != 0) {
- sourceWriter.print(", ");
- }
- String parameterTypeName = getBoxedTypeName(parameterType);
- sourceWriter.print("(" + parameterTypeName
- + ") parameters[" + i + "]");
- }
- sourceWriter.println(");");
-
- sourceWriter.outdent();
- sourceWriter.println("}");
-
- sourceWriter.outdent();
- sourceWriter.println("});");
- }
- }
- }
-
- sourceWriter.println("return list;");
-
- sourceWriter.outdent();
- sourceWriter.println("}");
- 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)");
-
- }
-
- public static void writeTypeCreator(SourceWriter sourceWriter, JType type) {
- String typeName = getBoxedTypeName(type);
- sourceWriter.print("new Type(\"" + typeName + "\", ");
- JParameterizedType parameterized = type.isParameterized();
- if (parameterized != null) {
- sourceWriter.print("new Type[] {");
- JClassType[] typeArgs = parameterized.getTypeArgs();
- for (JClassType jClassType : typeArgs) {
- writeTypeCreator(sourceWriter, jClassType);
- sourceWriter.print(", ");
- }
- sourceWriter.print("}");
- } else {
- sourceWriter.print("null");
- }
- sourceWriter.print(")");
- }
-
- public static String getBoxedTypeName(JType type) {
- if (type.isPrimitive() != null) {
- // Used boxed types for primitives
- return type.isPrimitive().getQualifiedBoxedSourceName();
- } else {
- return type.getErasedType().getQualifiedSourceName();
- }
- }
-
- private String getInvokeMethodName(JClassType type) {
- return "invoke" + type.getQualifiedSourceName().replaceAll("\\.", "_");
- }
-}
diff --git a/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/SerializerGenerator.java b/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/SerializerGenerator.java
index c7cc7bf7cb..83e1c17881 100644
--- a/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/SerializerGenerator.java
+++ b/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/SerializerGenerator.java
@@ -256,10 +256,10 @@ public class SerializerGenerator extends Generator {
JType componentType = type.getComponentType();
sourceWriter.print("value[i] = ("
- + GeneratedRpcMethodProviderGenerator
+ + ConnectorBundleLoaderFactory
.getBoxedTypeName(componentType) + ") "
+ JsonDecoder.class.getName() + ".decodeValue(");
- GeneratedRpcMethodProviderGenerator.writeTypeCreator(sourceWriter,
+ ConnectorBundleLoaderFactory.writeTypeCreator(sourceWriter,
componentType);
sourceWriter.print(", jsonArray.get(i), null, connection)");
@@ -320,7 +320,7 @@ public class SerializerGenerator extends Generator {
// connection));
sourceWriter.print("target." + setterName + "((" + fieldType + ") "
+ JsonDecoder.class.getName() + ".decodeValue(");
- GeneratedRpcMethodProviderGenerator.writeTypeCreator(sourceWriter,
+ ConnectorBundleLoaderFactory.writeTypeCreator(sourceWriter,
setterParameterType);
sourceWriter.println(", " + jsonFieldName
+ ", referenceValue, connection));");
diff --git a/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/metadata/ClientRpcVisitor.java b/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/metadata/ClientRpcVisitor.java
new file mode 100644
index 0000000000..2f628b76cb
--- /dev/null
+++ b/client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/metadata/ClientRpcVisitor.java
@@ -0,0 +1,39 @@
+/*
+ * 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.metadata;
+
+import java.util.Set;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.core.ext.typeinfo.JMethod;
+
+public class ClientRpcVisitor extends TypeVisitor {
+ @Override
+ public void visitClientRpc(TreeLogger logger, JClassType type,
+ ConnectorBundle bundle) {
+ Set<? extends JClassType> hierarchy = type
+ .getFlattenedSupertypeHierarchy();
+ for (JClassType subType : hierarchy) {
+ JMethod[] methods = subType.getMethods();
+ for (JMethod method : methods) {
+ bundle.setNeedsInvoker(type, method);
+ bundle.setNeedsParamTypes(type, method);
+ }
+ }
+ }
+}
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 26e293351c..3302fbc4fa 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
@@ -36,6 +36,8 @@ public class ConnectorBundle {
private final Map<JClassType, Set<JMethod>> needsReturnType = new HashMap<JClassType, Set<JMethod>>();
private final Collection<TypeVisitor> visitors;
+ private final Map<JClassType, Set<JMethod>> needsInvoker = new HashMap<JClassType, Set<JMethod>>();
+ private final Map<JClassType, Set<JMethod>> needsParamTypes = new HashMap<JClassType, Set<JMethod>>();
private ConnectorBundle(String name, ConnectorBundle previousBundle,
Collection<TypeVisitor> visitors) {
@@ -71,18 +73,12 @@ public class ConnectorBundle {
public void setIdentifier(JClassType type, String identifier) {
if (!hasIdentifier(type, identifier)) {
ensureVisited(type);
- Set<String> set = identifiers.get(type);
- if (set == null) {
- set = new HashSet<String>();
- identifiers.put(type, set);
- }
- set.add(identifier);
+ addMapping(identifiers, type, identifier);
}
}
private boolean hasIdentifier(JClassType type, String identifier) {
- if (identifiers.containsKey(type)
- && identifiers.get(type).contains(identifier)) {
+ if (hasMapping(identifiers, type, identifier)) {
return true;
} else {
return previousBundle != null
@@ -142,10 +138,13 @@ public class ConnectorBundle {
if (isTypeVisited(type)) {
continue;
}
+
+ // Mark as visited before visiting to avoid adding to queue again
+ visitedTypes.add(type);
+
for (TypeVisitor typeVisitor : visitors) {
invokeVisitor(logger, type, typeVisitor);
}
- visitedTypes.add(type);
}
}
@@ -171,18 +170,12 @@ public class ConnectorBundle {
public void setNeedsReturnType(JClassType type, JMethod method) {
if (!isNeedsReturnType(type, method)) {
ensureVisited(type);
- Set<JMethod> set = needsReturnType.get(type);
- if (set == null) {
- set = new HashSet<JMethod>();
- needsReturnType.put(type, set);
- }
- set.add(method);
+ addMapping(needsReturnType, type, method);
}
}
private boolean isNeedsReturnType(JClassType type, JMethod method) {
- if (needsReturnType.containsKey(type)
- && needsReturnType.get(type).contains(method)) {
+ if (hasMapping(needsReturnType, type, method)) {
return true;
} else {
return previousBundle != null
@@ -223,4 +216,56 @@ public class ConnectorBundle {
}
}
+ public void setNeedsInvoker(JClassType type, JMethod method) {
+ if (!isNeedsInvoker(type, method)) {
+ ensureVisited(type);
+ addMapping(needsInvoker, type, method);
+ }
+ }
+
+ private <K, V> void addMapping(Map<K, Set<V>> map, K key, V value) {
+ Set<V> set = map.get(key);
+ if (set == null) {
+ set = new HashSet<V>();
+ map.put(key, set);
+ }
+ set.add(value);
+ }
+
+ private <K, V> boolean hasMapping(Map<K, Set<V>> map, K key, V value) {
+ return map.containsKey(key) && map.get(key).contains(value);
+ }
+
+ private boolean isNeedsInvoker(JClassType type, JMethod method) {
+ if (hasMapping(needsInvoker, type, method)) {
+ return true;
+ } else {
+ return previousBundle != null
+ && previousBundle.isNeedsInvoker(type, method);
+ }
+ }
+
+ public Map<JClassType, Set<JMethod>> getNeedsInvoker() {
+ return Collections.unmodifiableMap(needsInvoker);
+ }
+
+ public void setNeedsParamTypes(JClassType type, JMethod method) {
+ if (!isNeedsParamTypes(type, method)) {
+ ensureVisited(type);
+ addMapping(needsParamTypes, type, method);
+ }
+ }
+
+ private boolean isNeedsParamTypes(JClassType type, JMethod method) {
+ if (hasMapping(needsParamTypes, type, method)) {
+ return true;
+ } else {
+ return previousBundle != null
+ && previousBundle.isNeedsParamTypes(type, method);
+ }
+ }
+
+ public Map<JClassType, Set<JMethod>> getNeedsParamTypes() {
+ return Collections.unmodifiableMap(needsParamTypes);
+ }
} \ No newline at end of file
diff --git a/client/src/com/vaadin/Vaadin.gwt.xml b/client/src/com/vaadin/Vaadin.gwt.xml
index 4bac60b472..e25c812e5b 100644
--- a/client/src/com/vaadin/Vaadin.gwt.xml
+++ b/client/src/com/vaadin/Vaadin.gwt.xml
@@ -54,13 +54,6 @@
<when-type-assignable
class="com.vaadin.terminal.gwt.client.communication.RpcProxy.RpcProxyCreator" />
</generate-with>
-
- <!-- Generate client side RPC manager for server to client RPC -->
- <generate-with
- class="com.vaadin.terminal.gwt.widgetsetutils.GeneratedRpcMethodProviderGenerator">
- <when-type-assignable
- class="com.vaadin.terminal.gwt.client.communication.GeneratedRpcMethodProvider" />
- </generate-with>
<generate-with class="com.vaadin.terminal.gwt.widgetsetutils.ConnectorBundleLoaderFactory">
<when-type-assignable class="com.vaadin.terminal.gwt.client.metadata.ConnectorBundleLoader" />
diff --git a/client/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java b/client/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java
index 8f6697288c..8bb4f37324 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java
@@ -33,6 +33,7 @@ import com.google.gwt.user.client.Window;
import com.vaadin.shared.ApplicationConstants;
import com.vaadin.terminal.gwt.client.metadata.BundleLoadCallback;
import com.vaadin.terminal.gwt.client.metadata.ConnectorBundleLoader;
+import com.vaadin.terminal.gwt.client.metadata.NoDataException;
import com.vaadin.terminal.gwt.client.metadata.TypeData;
import com.vaadin.terminal.gwt.client.ui.UnknownComponentConnector;
@@ -398,8 +399,14 @@ public class ApplicationConfiguration implements EntryPoint {
Integer currentTag = Integer.valueOf(tag);
while (type == null && currentTag != null) {
String serverSideClassNameForTag = getServerSideClassNameForTag(currentTag);
- type = (Class<? extends ServerConnector>) TypeData
- .getClass(serverSideClassNameForTag);
+ if (TypeData.hasIdentifier(serverSideClassNameForTag)) {
+ try {
+ type = (Class<? extends ServerConnector>) TypeData
+ .getClass(serverSideClassNameForTag);
+ } catch (NoDataException e) {
+ throw new RuntimeException(e);
+ }
+ }
currentTag = getParentTag(currentTag.intValue());
}
if (type == null) {
diff --git a/client/src/com/vaadin/terminal/gwt/client/WidgetSet.java b/client/src/com/vaadin/terminal/gwt/client/WidgetSet.java
index 776436f5f0..8245371161 100644
--- a/client/src/com/vaadin/terminal/gwt/client/WidgetSet.java
+++ b/client/src/com/vaadin/terminal/gwt/client/WidgetSet.java
@@ -20,6 +20,7 @@ import com.google.gwt.core.client.GWT;
import com.vaadin.terminal.gwt.client.communication.HasJavaScriptConnectorHelper;
import com.vaadin.terminal.gwt.client.metadata.BundleLoadCallback;
import com.vaadin.terminal.gwt.client.metadata.ConnectorBundleLoader;
+import com.vaadin.terminal.gwt.client.metadata.NoDataException;
import com.vaadin.terminal.gwt.client.metadata.TypeData;
import com.vaadin.terminal.gwt.client.ui.UnknownComponentConnector;
@@ -60,13 +61,21 @@ public class WidgetSet {
/*
* let the auto generated code instantiate this type
*/
- ServerConnector connector = (ServerConnector) TypeData.getType(
- classType).createInstance();
- if (connector instanceof HasJavaScriptConnectorHelper) {
- ((HasJavaScriptConnectorHelper) connector)
- .getJavascriptConnectorHelper().setTag(tag);
+ try {
+ ServerConnector connector = (ServerConnector) TypeData.getType(
+ classType).createInstance();
+ if (connector instanceof HasJavaScriptConnectorHelper) {
+ ((HasJavaScriptConnectorHelper) connector)
+ .getJavascriptConnectorHelper().setTag(tag);
+ }
+ return connector;
+ } catch (NoDataException e) {
+ throw new IllegalStateException(
+ "There is no information about "
+ + classType
+ + ". Did you remember to compile the right widgetset?",
+ e);
}
- return connector;
}
}
diff --git a/client/src/com/vaadin/terminal/gwt/client/communication/RpcManager.java b/client/src/com/vaadin/terminal/gwt/client/communication/RpcManager.java
index 537cc34185..45939eb54e 100644
--- a/client/src/com/vaadin/terminal/gwt/client/communication/RpcManager.java
+++ b/client/src/com/vaadin/terminal/gwt/client/communication/RpcManager.java
@@ -17,10 +17,7 @@
package com.vaadin.terminal.gwt.client.communication;
import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import com.google.gwt.core.client.GWT;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONString;
import com.vaadin.shared.communication.ClientRpc;
@@ -29,6 +26,8 @@ import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.ConnectorMap;
import com.vaadin.terminal.gwt.client.ServerConnector;
import com.vaadin.terminal.gwt.client.VConsole;
+import com.vaadin.terminal.gwt.client.metadata.Method;
+import com.vaadin.terminal.gwt.client.metadata.NoDataException;
import com.vaadin.terminal.gwt.client.metadata.Type;
/**
@@ -42,19 +41,6 @@ import com.vaadin.terminal.gwt.client.metadata.Type;
*/
public class RpcManager {
- private final Map<String, RpcMethod> methodMap = new HashMap<String, RpcMethod>();
-
- public RpcManager() {
- GeneratedRpcMethodProvider provider = GWT
- .create(GeneratedRpcMethodProvider.class);
- Collection<RpcMethod> methods = provider.getGeneratedRpcMethods();
- for (RpcMethod rpcMethod : methods) {
- methodMap.put(
- rpcMethod.getInterfaceName() + "."
- + rpcMethod.getMethodName(), rpcMethod);
- }
- }
-
/**
* Perform server to client RPC invocation.
*
@@ -63,24 +49,25 @@ public class RpcManager {
*/
public void applyInvocation(MethodInvocation invocation,
ServerConnector connector) {
- String signature = getSignature(invocation);
+ Method method = getMethod(invocation);
- RpcMethod rpcMethod = getRpcMethod(signature);
Collection<ClientRpc> implementations = connector
.getRpcImplementations(invocation.getInterfaceName());
- for (ClientRpc clientRpc : implementations) {
- rpcMethod.applyInvocation(clientRpc, invocation.getParameters());
+ try {
+ for (ClientRpc clientRpc : implementations) {
+ method.invoke(clientRpc, invocation.getParameters());
+ }
+ } catch (NoDataException e) {
+ throw new IllegalStateException("There is no information about "
+ + method.getSignature()
+ + ". Did you remember to compile the right widgetset?", e);
}
}
- private RpcMethod getRpcMethod(String signature) {
- RpcMethod rpcMethod = methodMap.get(signature);
- if (rpcMethod == null) {
- throw new IllegalStateException("There is no information about "
- + signature
- + ". Did you remember to compile the right widgetset?");
- }
- return rpcMethod;
+ private Method getMethod(MethodInvocation invocation) {
+ Type type = new Type(invocation.getInterfaceName(), null);
+ Method method = type.getMethod(invocation.getMethodName());
+ return method;
}
private static String getSignature(MethodInvocation invocation) {
@@ -88,7 +75,15 @@ public class RpcManager {
}
public Type[] getParameterTypes(MethodInvocation invocation) {
- return getRpcMethod(getSignature(invocation)).getParameterTypes();
+ Method method = getMethod(invocation);
+ Type[] parameterTypes = method.getParameterTypes();
+ if (parameterTypes == null) {
+ throw new IllegalStateException("There is no information about "
+ + method.getSignature()
+ + ". Did you remember to compile the right widgetset?");
+
+ }
+ return parameterTypes;
}
public void parseAndApplyInvocation(JSONArray rpcCall,
diff --git a/client/src/com/vaadin/terminal/gwt/client/communication/RpcMethod.java b/client/src/com/vaadin/terminal/gwt/client/communication/RpcMethod.java
deleted file mode 100644
index 1759fbb97f..0000000000
--- a/client/src/com/vaadin/terminal/gwt/client/communication/RpcMethod.java
+++ /dev/null
@@ -1,47 +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;
-
-import com.vaadin.shared.communication.ClientRpc;
-import com.vaadin.terminal.gwt.client.metadata.Type;
-
-public abstract class RpcMethod {
- private String interfaceName;
- private String methodName;
- private Type[] parameterTypes;
-
- public RpcMethod(String interfaceName, String methodName,
- Type... parameterTypes) {
- this.interfaceName = interfaceName;
- this.methodName = methodName;
- this.parameterTypes = parameterTypes;
- }
-
- public String getInterfaceName() {
- return interfaceName;
- }
-
- public String getMethodName() {
- return methodName;
- }
-
- public Type[] getParameterTypes() {
- return parameterTypes;
- }
-
- public abstract void applyInvocation(ClientRpc target, Object... parameters);
-
-}
diff --git a/client/src/com/vaadin/terminal/gwt/client/metadata/Method.java b/client/src/com/vaadin/terminal/gwt/client/metadata/Method.java
index f164bc4bcf..588e736da3 100644
--- a/client/src/com/vaadin/terminal/gwt/client/metadata/Method.java
+++ b/client/src/com/vaadin/terminal/gwt/client/metadata/Method.java
@@ -22,11 +22,11 @@ public class Method {
return name;
}
- public Type getReturnType() {
+ public Type getReturnType() throws NoDataException {
return TypeDataStore.getReturnType(this);
}
- public void invoke(Object target, Object... params) {
+ public void invoke(Object target, Object... params) throws NoDataException {
TypeDataStore.getInvoker(this).invoke(target, params);
}
@@ -47,8 +47,17 @@ public class Method {
}
@Override
+ public String toString() {
+ return getSignature();
+ }
+
+ @Override
public int hashCode() {
return getSignature().hashCode();
}
+ public Type[] getParameterTypes() {
+ return TypeDataStore.getParamTypes(this);
+ }
+
}
diff --git a/client/src/com/vaadin/terminal/gwt/client/communication/GeneratedRpcMethodProvider.java b/client/src/com/vaadin/terminal/gwt/client/metadata/NoDataException.java
index e865dbc1b1..717b92edaf 100644
--- a/client/src/com/vaadin/terminal/gwt/client/communication/GeneratedRpcMethodProvider.java
+++ b/client/src/com/vaadin/terminal/gwt/client/metadata/NoDataException.java
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright 2011 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
@@ -13,20 +13,13 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
-package com.vaadin.terminal.gwt.client.communication;
-import java.util.Collection;
+package com.vaadin.terminal.gwt.client.metadata;
-/**
- * Provides runtime data about client side RPC calls received from the server to
- * the client-side code.
- *
- * A GWT generator is used to create an implementation of this class at
- * run-time.
- *
- * @since 7.0
- */
-public interface GeneratedRpcMethodProvider {
+public class NoDataException extends Exception {
+
+ public NoDataException(String message) {
+ super(message);
+ }
- public Collection<RpcMethod> getGeneratedRpcMethods();
}
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 5f2b1ffb41..30d864a43f 100644
--- a/client/src/com/vaadin/terminal/gwt/client/metadata/Property.java
+++ b/client/src/com/vaadin/terminal/gwt/client/metadata/Property.java
@@ -13,7 +13,7 @@ public class Property {
this.name = name;
}
- public Object getValue(Object bean) {
+ public Object getValue(Object bean) throws NoDataException {
return TypeDataStore.getGetter(this).invoke(bean, null);
}
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 4fab296441..dfd504983c 100644
--- a/client/src/com/vaadin/terminal/gwt/client/metadata/Type.java
+++ b/client/src/com/vaadin/terminal/gwt/client/metadata/Type.java
@@ -25,7 +25,7 @@ public class Type {
return parameterTypes;
}
- public Object createInstance() {
+ public Object createInstance() throws NoDataException {
Invoker invoker = TypeDataStore.getConstructor(this);
return invoker.invoke(null, null);
}
@@ -40,7 +40,7 @@ public class Type {
public String getSignature() {
String string = name;
- if (parameterTypes != null) {
+ if (parameterTypes != null && parameterTypes.length != 0) {
string += '<';
for (int i = 0; i < parameterTypes.length; i++) {
if (i != 0) {
diff --git a/client/src/com/vaadin/terminal/gwt/client/metadata/TypeData.java b/client/src/com/vaadin/terminal/gwt/client/metadata/TypeData.java
index 6ee0b4ede0..ec2a8f191c 100644
--- a/client/src/com/vaadin/terminal/gwt/client/metadata/TypeData.java
+++ b/client/src/com/vaadin/terminal/gwt/client/metadata/TypeData.java
@@ -10,11 +10,11 @@ public class TypeData {
return TypeDataStore.getType(type);
}
- public static Type getType(String identifier) {
- return TypeDataStore.getType(getClass(identifier));
+ public static Class<?> getClass(String identifier) throws NoDataException {
+ return TypeDataStore.getClass(identifier);
}
- public static Class<?> getClass(String identifier) {
- return TypeDataStore.getClass(identifier);
+ public static boolean hasIdentifier(String identifier) {
+ return TypeDataStore.hasIdentifier(identifier);
}
}
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 4b224721e6..4b99250465 100644
--- a/client/src/com/vaadin/terminal/gwt/client/metadata/TypeDataStore.java
+++ b/client/src/com/vaadin/terminal/gwt/client/metadata/TypeDataStore.java
@@ -14,6 +14,7 @@ public class TypeDataStore {
private final Map<Method, Type> returnTypes = new HashMap<Method, Type>();
private final Map<Method, Invoker> invokers = new HashMap<Method, Invoker>();
+ private final Map<Method, Type[]> paramTypes = new HashMap<Method, Type[]>();
private final Map<Property, Invoker> getters = new HashMap<Property, Invoker>();
private final Map<Property, String> delegateToWidget = new HashMap<Property, String>();
@@ -26,28 +27,55 @@ public class TypeDataStore {
identifiers.put(identifier, type);
}
- public static Class<?> getClass(String identifier) {
- return get().identifiers.get(identifier);
+ public static Class<?> getClass(String identifier) throws NoDataException {
+ Class<?> class1 = get().identifiers.get(identifier);
+ if (class1 == null) {
+ throw new NoDataException("There is not class for identifier "
+ + identifier);
+ }
+ return class1;
}
public static Type getType(Class<?> clazz) {
return new Type(clazz);
}
- public static Type getReturnType(Method method) {
- return get().returnTypes.get(method);
+ public static Type getReturnType(Method method) throws NoDataException {
+ Type type = get().returnTypes.get(method);
+ if (type == null) {
+ throw new NoDataException("There is return type for "
+ + method.getSignature());
+ }
+ return type;
}
- public static Invoker getInvoker(Method method) {
- return get().invokers.get(method);
+ public static Invoker getInvoker(Method method) throws NoDataException {
+ Invoker invoker = get().invokers.get(method);
+ if (invoker == null) {
+ throw new NoDataException("There is invoker for "
+ + method.getSignature());
+ }
+ return invoker;
}
- public static Invoker getConstructor(Type type) {
- return get().invokers.get(new Method(type, CONSTRUCTOR_NAME));
+ public static Invoker getConstructor(Type type) throws NoDataException {
+ Invoker invoker = get().invokers
+ .get(new Method(type, CONSTRUCTOR_NAME));
+ if (invoker == null) {
+ throw new NoDataException("There is constructor for "
+ + type.getSignature());
+ }
+ return invoker;
}
- public static Invoker getGetter(Property property) {
- return get().getters.get(property);
+ public static Invoker getGetter(Property property) throws NoDataException {
+ Invoker getter = get().getters.get(property);
+ if (getter == null) {
+ throw new NoDataException("There is getter for "
+ + property.getSignature());
+ }
+
+ return getter;
}
public static String getDelegateToWidget(Property property) {
@@ -59,6 +87,23 @@ public class TypeDataStore {
}
public void setConstructor(Class<?> type, Invoker constructor) {
- invokers.put(new Method(getType(type), CONSTRUCTOR_NAME), constructor);
+ setInvoker(type, CONSTRUCTOR_NAME, constructor);
+ }
+
+ public void setInvoker(Class<?> type, String methodName, Invoker invoker) {
+ invokers.put(new Method(getType(type), methodName), invoker);
+ }
+
+ public static Type[] getParamTypes(Method method) {
+ return get().paramTypes.get(method);
+ }
+
+ public void setParamTypes(Class<?> type, String methodName,
+ Type[] paramTypes) {
+ this.paramTypes.put(new Method(getType(type), methodName), paramTypes);
+ }
+
+ public static boolean hasIdentifier(String identifier) {
+ return get().identifiers.containsKey(identifier);
}
}
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 4f14ee550b..faded22260 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,7 @@ 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.NoDataException;
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;
@@ -80,9 +81,17 @@ public abstract class AbstractComponentConnector extends AbstractConnector
*/
protected Widget createWidget() {
Type type = TypeData.getType(getClass());
- Type widgetType = type.getMethod("getWidget").getReturnType();
- Object instance = widgetType.createInstance();
- return (Widget) instance;
+ try {
+ Type widgetType = type.getMethod("getWidget").getReturnType();
+ Object instance = widgetType.createInstance();
+ return (Widget) instance;
+ } catch (NoDataException e) {
+ throw new IllegalStateException(
+ "There is no information about the widget for "
+ + Util.getSimpleName(this)
+ + ". Did you remember to compile the right widgetset?",
+ e);
+ }
}
/**
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 9efa7bad0d..b861ade0bf 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,7 @@ 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.NoDataException;
import com.vaadin.terminal.gwt.client.metadata.Type;
import com.vaadin.terminal.gwt.client.metadata.TypeData;
@@ -268,9 +269,19 @@ public abstract class AbstractConnector implements ServerConnector,
*/
protected SharedState createState() {
Type connectorType = TypeData.getType(getClass());
- Type stateType = connectorType.getMethod("getState").getReturnType();
- Object stateInstance = stateType.createInstance();
- return (SharedState) stateInstance;
+ try {
+ Type stateType = connectorType.getMethod("getState")
+ .getReturnType();
+ Object stateInstance = stateType.createInstance();
+ return (SharedState) stateInstance;
+ } catch (NoDataException e) {
+ throw new IllegalStateException(
+ "There is no information about the state for "
+ + Util.getSimpleName(this)
+ + ". Did you remember to compile the right widgetset?",
+ e);
+ }
+
}
@Override