From bcef4d5e716a275f3a3588cd9e50885129d38eb7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Leif=20=C3=85strand?= Date: Tue, 21 Aug 2012 12:33:32 +0300 Subject: [PATCH] Use ConnectorBundle for ClientRpc handling (#9371) --- .../ConnectorBundleLoaderFactory.java | 116 ++++++++- .../GeneratedRpcMethodProviderGenerator.java | 223 ------------------ .../widgetsetutils/SerializerGenerator.java | 6 +- .../metadata/ClientRpcVisitor.java | 39 +++ .../metadata/ConnectorBundle.java | 79 +++++-- client/src/com/vaadin/Vaadin.gwt.xml | 7 - .../gwt/client/ApplicationConfiguration.java | 11 +- .../vaadin/terminal/gwt/client/WidgetSet.java | 21 +- .../gwt/client/communication/RpcManager.java | 53 ++--- .../gwt/client/communication/RpcMethod.java | 47 ---- .../terminal/gwt/client/metadata/Method.java | 13 +- .../NoDataException.java} | 21 +- .../gwt/client/metadata/Property.java | 2 +- .../terminal/gwt/client/metadata/Type.java | 4 +- .../gwt/client/metadata/TypeData.java | 8 +- .../gwt/client/metadata/TypeDataStore.java | 67 +++++- .../client/ui/AbstractComponentConnector.java | 15 +- .../gwt/client/ui/AbstractConnector.java | 17 +- 18 files changed, 371 insertions(+), 378 deletions(-) delete mode 100644 client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/GeneratedRpcMethodProviderGenerator.java create mode 100644 client-compiler/src/com/vaadin/terminal/gwt/widgetsetutils/metadata/ClientRpcVisitor.java delete mode 100644 client/src/com/vaadin/terminal/gwt/client/communication/RpcMethod.java rename client/src/com/vaadin/terminal/gwt/client/{communication/GeneratedRpcMethodProvider.java => metadata/NoDataException.java} (59%) 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> needsParamTypes = bundle + .getNeedsParamTypes(); + for (Entry> entry : needsParamTypes.entrySet()) { + JClassType type = entry.getKey(); + + Set 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> needsInvoker = bundle.getNeedsInvoker(); + for (Entry> entry : needsInvoker.entrySet()) { + JClassType type = entry.getKey(); + + Set 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 visitors = Arrays. 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 rpcMethods = new ArrayList(); - - sourceWriter - .println("public java.util.Collection getGeneratedRpcMethods() {"); - sourceWriter.indent(); - - sourceWriter - .println("java.util.ArrayList list = new java.util.ArrayList();"); - - // 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 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> needsReturnType = new HashMap>(); private final Collection visitors; + private final Map> needsInvoker = new HashMap>(); + private final Map> needsParamTypes = new HashMap>(); private ConnectorBundle(String name, ConnectorBundle previousBundle, Collection visitors) { @@ -71,18 +73,12 @@ public class ConnectorBundle { public void setIdentifier(JClassType type, String identifier) { if (!hasIdentifier(type, identifier)) { ensureVisited(type); - Set set = identifiers.get(type); - if (set == null) { - set = new HashSet(); - 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 set = needsReturnType.get(type); - if (set == null) { - set = new HashSet(); - 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 void addMapping(Map> map, K key, V value) { + Set set = map.get(key); + if (set == null) { + set = new HashSet(); + map.put(key, set); + } + set.add(value); + } + + private boolean hasMapping(Map> 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> 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> 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 @@ - - - - - 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) TypeData - .getClass(serverSideClassNameForTag); + if (TypeData.hasIdentifier(serverSideClassNameForTag)) { + try { + type = (Class) 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 methodMap = new HashMap(); - - public RpcManager() { - GeneratedRpcMethodProvider provider = GWT - .create(GeneratedRpcMethodProvider.class); - Collection 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 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); } @@ -46,9 +46,18 @@ 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 similarity index 59% rename from client/src/com/vaadin/terminal/gwt/client/communication/GeneratedRpcMethodProvider.java rename to 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 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 returnTypes = new HashMap(); private final Map invokers = new HashMap(); + private final Map paramTypes = new HashMap(); private final Map getters = new HashMap(); private final Map delegateToWidget = new HashMap(); @@ -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 -- 2.39.5