summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLeif Åstrand <leif@vaadin.com>2012-05-31 16:31:26 +0300
committerLeif Åstrand <leif@vaadin.com>2012-06-06 13:33:42 +0300
commitdc7e238f2dc9ec6c9faad5ab6dcfdab8f2eaae46 (patch)
treefc4fb6d63da14d8a756fa42c120f776e64aae8e5 /src
parent6526c870a3b5d8fbb22c8c80cb06fa25ab62ed97 (diff)
downloadvaadin-framework-dc7e238f2dc9ec6c9faad5ab6dcfdab8f2eaae46.tar.gz
vaadin-framework-dc7e238f2dc9ec6c9faad5ab6dcfdab8f2eaae46.zip
Refactor RpcManager to provide info about parameter types (#8879)
This is an intermediate step towards decoding everything received from the server based on its declared type.
Diffstat (limited to 'src')
-rw-r--r--src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml4
-rw-r--r--src/com/vaadin/terminal/gwt/client/communication/GeneratedRpcMethodProvider.java20
-rw-r--r--src/com/vaadin/terminal/gwt/client/communication/RpcManager.java59
-rw-r--r--src/com/vaadin/terminal/gwt/client/communication/RpcMethod.java32
-rw-r--r--src/com/vaadin/terminal/gwt/client/communication/Type.java40
-rw-r--r--src/com/vaadin/terminal/gwt/widgetsetutils/GeneratedRpcMethodProviderGenerator.java (renamed from src/com/vaadin/terminal/gwt/widgetsetutils/RpcManagerGenerator.java)129
6 files changed, 217 insertions, 67 deletions
diff --git a/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml b/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml
index 74dc78d9b8..daa5e9f24d 100644
--- a/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml
+++ b/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml
@@ -63,9 +63,9 @@
<!-- Generate client side RPC manager for server to client RPC -->
<generate-with
- class="com.vaadin.terminal.gwt.widgetsetutils.RpcManagerGenerator">
+ class="com.vaadin.terminal.gwt.widgetsetutils.GeneratedRpcMethodProviderGenerator">
<when-type-assignable
- class="com.vaadin.terminal.gwt.client.communication.RpcManager" />
+ class="com.vaadin.terminal.gwt.client.communication.GeneratedRpcMethodProvider" />
</generate-with>
<generate-with
diff --git a/src/com/vaadin/terminal/gwt/client/communication/GeneratedRpcMethodProvider.java b/src/com/vaadin/terminal/gwt/client/communication/GeneratedRpcMethodProvider.java
new file mode 100644
index 0000000000..c92466084c
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/communication/GeneratedRpcMethodProvider.java
@@ -0,0 +1,20 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.communication;
+
+import java.util.Collection;
+
+/**
+ * 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 Collection<RpcMethod> getGeneratedRpcMethods();
+}
diff --git a/src/com/vaadin/terminal/gwt/client/communication/RpcManager.java b/src/com/vaadin/terminal/gwt/client/communication/RpcManager.java
index 302e6eaa55..1d3447687d 100644
--- a/src/com/vaadin/terminal/gwt/client/communication/RpcManager.java
+++ b/src/com/vaadin/terminal/gwt/client/communication/RpcManager.java
@@ -4,9 +4,13 @@
package com.vaadin.terminal.gwt.client.communication;
-import java.io.Serializable;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import com.google.gwt.core.client.GWT;
import com.vaadin.terminal.gwt.client.ConnectorMap;
+import com.vaadin.terminal.gwt.client.ServerConnector;
/**
* Client side RPC manager that can invoke methods based on RPC calls received
@@ -17,7 +21,21 @@ import com.vaadin.terminal.gwt.client.ConnectorMap;
*
* @since 7.0
*/
-public interface RpcManager extends Serializable {
+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.
*
@@ -28,5 +46,40 @@ public interface RpcManager extends Serializable {
* connectors referenced in parameters
*/
public void applyInvocation(MethodInvocation invocation,
- ConnectorMap connectorMap);
+ ConnectorMap connectorMap) {
+ ServerConnector connector = connectorMap.getConnector(invocation
+ .getConnectorId());
+ String signature = getSignature(invocation);
+ if (connector == null) {
+ throw new IllegalStateException("Target connector ("
+ + invocation.getConnectorId() + ") not found for RCC to "
+ + signature);
+ }
+
+ RpcMethod rpcMethod = getRpcMethod(signature);
+ Collection<ClientRpc> implementations = connector
+ .getRpcImplementations(invocation.getInterfaceName());
+ for (ClientRpc clientRpc : implementations) {
+ rpcMethod.applyInvocation(clientRpc, invocation.getParameters());
+ }
+ }
+
+ 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 static String getSignature(MethodInvocation invocation) {
+ return invocation.getInterfaceName() + "." + invocation.getMethodName();
+ }
+
+ public Type[] getParameterTypes(MethodInvocation invocation) {
+ return getRpcMethod(getSignature(invocation)).getParameterTypes();
+ }
+
}
diff --git a/src/com/vaadin/terminal/gwt/client/communication/RpcMethod.java b/src/com/vaadin/terminal/gwt/client/communication/RpcMethod.java
new file mode 100644
index 0000000000..abdcf73e2c
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/communication/RpcMethod.java
@@ -0,0 +1,32 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.communication;
+
+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/src/com/vaadin/terminal/gwt/client/communication/Type.java b/src/com/vaadin/terminal/gwt/client/communication/Type.java
new file mode 100644
index 0000000000..dc33f760ff
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/communication/Type.java
@@ -0,0 +1,40 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+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/src/com/vaadin/terminal/gwt/widgetsetutils/RpcManagerGenerator.java b/src/com/vaadin/terminal/gwt/widgetsetutils/GeneratedRpcMethodProviderGenerator.java
index 2899061204..f0db4886e4 100644
--- a/src/com/vaadin/terminal/gwt/widgetsetutils/RpcManagerGenerator.java
+++ b/src/com/vaadin/terminal/gwt/widgetsetutils/GeneratedRpcMethodProviderGenerator.java
@@ -16,15 +16,15 @@ 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.terminal.gwt.client.ServerConnector;
-import com.vaadin.terminal.gwt.client.ConnectorMap;
import com.vaadin.terminal.gwt.client.communication.ClientRpc;
-import com.vaadin.terminal.gwt.client.communication.MethodInvocation;
+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
@@ -32,7 +32,7 @@ import com.vaadin.terminal.gwt.client.communication.RpcManager;
*
* @since 7.0
*/
-public class RpcManagerGenerator extends Generator {
+public class GeneratedRpcMethodProviderGenerator extends Generator {
@Override
public String generate(TreeLogger logger, GeneratorContext context,
@@ -90,12 +90,24 @@ public class RpcManagerGenerator extends Generator {
ClassSourceFileComposerFactory composer = null;
composer = new ClassSourceFileComposerFactory(packageName, className);
composer.addImport("com.google.gwt.core.client.GWT");
- composer.addImplementedInterface(RpcManager.class.getName());
+ composer.addImport(RpcMethod.class.getName());
+ composer.addImport(ClientRpc.class.getName());
+ composer.addImport(com.vaadin.terminal.gwt.client.communication.Type.class
+ .getName());
+ composer.addImplementedInterface(GeneratedRpcMethodProvider.class
+ .getName());
SourceWriter sourceWriter = composer.createSourceWriter(context,
printWriter);
sourceWriter.indent();
- List<JClassType> rpcInterfaces = new ArrayList<JClassType>();
+ 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
@@ -104,81 +116,56 @@ public class RpcManagerGenerator extends Generator {
// only interested in interfaces here, not implementations
continue;
}
- rpcInterfaces.add(type);
- // generate method to call methods of an RPC interface
- sourceWriter.println("private void " + getInvokeMethodName(type)
- + "(" + MethodInvocation.class.getName() + " invocation, "
- + ConnectorMap.class.getName() + " connectorMap) {");
- sourceWriter.indent();
// loop over the methods of the interface and its superinterfaces
// methods
for (JClassType currentType : type.getFlattenedSupertypeHierarchy()) {
for (JMethod method : currentType.getMethods()) {
- sourceWriter.println("if (\"" + method.getName()
- + "\".equals(invocation.getMethodName())) {");
- sourceWriter.indent();
- // construct parameter string with appropriate casts
- String paramString = "";
+
+ // RpcMethod(String interfaceName, String methodName,
+ // Type... parameterTypes)
+ sourceWriter.print("list.add(new RpcMethod(\""
+ + type.getQualifiedSourceName() + "\", \""
+ + method.getName() + "\"");
JType[] parameterTypes = method.getParameterTypes();
- for (int i = 0; i < parameterTypes.length; ++i) {
- paramString = paramString + "("
- + parameterTypes[i].getQualifiedSourceName()
- + ") invocation.getParameters()[" + i + "]";
- if (i < parameterTypes.length - 1) {
- paramString = paramString + ", ";
- }
+ for (JType parameter : parameterTypes) {
+ sourceWriter.print(", ");
+ writeTypeCreator(sourceWriter, parameter);
}
+ sourceWriter.println(") {");
+ sourceWriter.indent();
+
sourceWriter
- .println(ServerConnector.class.getName()
- + " connector = connectorMap.getConnector(invocation.getConnectorId());");
- sourceWriter
- .println("for ("
- + ClientRpc.class.getName()
- + " rpcImplementation : connector.getRpcImplementations(\""
- + type.getQualifiedSourceName() + "\")) {");
+ .println("public void applyInvocation(ClientRpc target, Object... parameters) {");
sourceWriter.indent();
- sourceWriter.println("((" + type.getQualifiedSourceName()
- + ") rpcImplementation)." + method.getName() + "("
- + paramString + ");");
+
+ sourceWriter.print("((" + type.getQualifiedSourceName()
+ + ")target)." + method.getName() + "(");
+ for (int i = 0; i < parameterTypes.length; i++) {
+ JType parameterType = parameterTypes[i];
+ if (i != 0) {
+ sourceWriter.print(", ");
+ }
+ sourceWriter.print("("
+ + parameterType.getQualifiedSourceName()
+ + ") parameters[" + i + "]");
+ }
+ sourceWriter.println(");");
+
sourceWriter.outdent();
sourceWriter.println("}");
- sourceWriter.println("return;");
+
sourceWriter.outdent();
- sourceWriter.println("}");
+ sourceWriter.println("});");
}
}
-
- sourceWriter.outdent();
- sourceWriter.println("}");
-
- logger.log(Type.DEBUG,
- "Constructed helper method for server to client RPC for "
- + type.getName());
}
- // generate top-level "switch-case" method to select the correct
- // previously generated method based on the RPC interface
- sourceWriter.println("public void applyInvocation("
- + MethodInvocation.class.getName() + " invocation, "
- + ConnectorMap.class.getName() + " connectorMap) {");
- sourceWriter.indent();
+ sourceWriter.println("return list;");
- for (JClassType type : rpcInterfaces) {
- sourceWriter.println("if (\"" + type.getQualifiedSourceName()
- + "\".equals(invocation.getInterfaceName())) {");
- sourceWriter.indent();
- sourceWriter.println(getInvokeMethodName(type)
- + "(invocation, connectorMap);");
- sourceWriter.println("return;");
- sourceWriter.outdent();
- sourceWriter.println("}");
-
- logger.log(Type.INFO,
- "Configured server to client RPC for " + type.getName());
- }
sourceWriter.outdent();
sourceWriter.println("}");
+ sourceWriter.println();
// close generated class
sourceWriter.outdent();
@@ -191,6 +178,24 @@ public class RpcManagerGenerator extends Generator {
}
+ private void writeTypeCreator(SourceWriter sourceWriter, JType type) {
+ sourceWriter.print("new Type(\""
+ + type.getErasedType().getQualifiedSourceName() + "\", ");
+ 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(")");
+ }
+
private String getInvokeMethodName(JClassType type) {
return "invoke" + type.getQualifiedSourceName().replaceAll("\\.", "_");
}