public abstract class AbstractClientConnector implements ClientConnector,
MethodEventSource {
/**
- * A map from client to server RPC interface class to the RPC call manager
- * that handles incoming RPC calls for that interface.
+ * A map from client to server RPC interface class name to the RPC call
+ * manager that handles incoming RPC calls for that interface.
*/
- private Map<Class<?>, RpcManager> rpcManagerMap = new HashMap<Class<?>, RpcManager>();
+ private Map<String, RpcManager> rpcManagerMap = new HashMap<String, RpcManager>();
/**
* A map from server to client RPC interface class to the RPC proxy that
* RPC interface class for which the implementation should be
* registered
*/
- protected <T> void registerRpc(T implementation, Class<T> rpcInterfaceType) {
- rpcManagerMap.put(rpcInterfaceType, new ServerRpcManager<T>(
+ protected <T extends ServerRpc> void registerRpc(T implementation,
+ Class<T> rpcInterfaceType) {
+ rpcManagerMap.put(rpcInterfaceType.getName(), new ServerRpcManager<T>(
implementation, rpcInterfaceType));
}
requestRepaint();
}
- /**
- * @see RpcTarget#getRpcManager(Class)
- *
- * @param rpcInterface
- * RPC interface for which a call was made
- * @return RPC Manager handling calls for the interface
- *
- * @since 7.0
- */
@Override
- public RpcManager getRpcManager(Class<?> rpcInterface) {
- return rpcManagerMap.get(rpcInterface);
+ public RpcManager getRpcManager(String rpcInterfaceName) {
+ return rpcManagerMap.get(rpcInterfaceName);
}
@Override
import com.vaadin.shared.Version;
import com.vaadin.shared.communication.LegacyChangeVariablesInvocation;
import com.vaadin.shared.communication.MethodInvocation;
+import com.vaadin.shared.communication.ServerRpc;
import com.vaadin.shared.communication.SharedState;
import com.vaadin.shared.communication.UidlValue;
import com.vaadin.shared.ui.ui.UIConstants;
final ClientConnector connector = getConnector(uI,
invocation.getConnectorId());
- if (connector == null) {
- getLogger().log(
- Level.WARNING,
- "RPC call to " + invocation.getInterfaceName()
- + "." + invocation.getMethodName()
- + " received for connector "
- + invocation.getConnectorId()
- + " but no such connector could be found");
- continue;
- }
-
if (!enabledConnectors.contains(connector)) {
if (invocation instanceof LegacyChangeVariablesInvocation) {
MethodInvocation invocation = parseInvocation(invocationJson,
previousInvocation, connectorTracker);
if (invocation != null) {
- // Can be null iff the invocation was a legacy invocation and it
- // was merged with the previous one
+ // Can be null if the invocation was a legacy invocation and it
+ // was merged with the previous one or if the invocation was
+ // rejected because of an error.
invocations.add(invocation);
previousInvocation = invocation;
}
String interfaceName = invocationJson.getString(1);
String methodName = invocationJson.getString(2);
+ if (connectorTracker.getConnector(connectorId) == null) {
+ getLogger().log(
+ Level.WARNING,
+ "RPC call to " + interfaceName + "." + methodName
+ + " received for connector " + connectorId
+ + " but no such connector could be found");
+ return null;
+ }
+
JSONArray parametersJson = invocationJson.getJSONArray(3);
if (LegacyChangeVariablesInvocation.isLegacyVariableChange(
String connectorId, String interfaceName, String methodName,
JSONArray parametersJson, ConnectorTracker connectorTracker)
throws JSONException {
+ ClientConnector connector = connectorTracker.getConnector(connectorId);
+
+ RpcManager rpcManager = connector.getRpcManager(interfaceName);
+ if (!(rpcManager instanceof ServerRpcManager)) {
+ /*
+ * Security: Don't even decode the json parameters if no RpcManager
+ * corresponding to the received method invocation has been
+ * registered.
+ */
+ getLogger().warning(
+ "Ignoring RPC call to " + interfaceName + "." + methodName
+ + " in connector " + connector.getClass().getName()
+ + "(" + connectorId
+ + ") as no RPC implementation is regsitered");
+ return null;
+ }
+
+ // Use interface from RpcManager instead of loading the class based on
+ // the string name to avoid problems with OSGi
+ Class<? extends ServerRpc> rpcInterface = ((ServerRpcManager<?>) rpcManager)
+ .getRpcInterface();
+
ServerRpcMethodInvocation invocation = new ServerRpcMethodInvocation(
- connectorId, interfaceName, methodName, parametersJson.length());
+ connectorId, rpcInterface, methodName, parametersJson.length());
Object[] parameters = new Object[parametersJson.length()];
Type[] declaredRpcMethodParameterTypes = invocation.getMethod()
package com.vaadin.server;
import com.vaadin.shared.JavaScriptExtensionState;
+import com.vaadin.shared.communication.ServerRpc;
import com.vaadin.ui.JavaScriptFunction;
/**
this);
@Override
- protected <T> void registerRpc(T implementation, Class<T> rpcInterfaceType) {
+ protected <T extends ServerRpc> void registerRpc(T implementation,
+ Class<T> rpcInterfaceType) {
super.registerRpc(implementation, rpcInterfaceType);
callbackHelper.registerRpc(rpcInterfaceType);
}
* @since 7.0.0
*
*/
-public interface ClientConnector extends Connector, RpcTarget {
+public interface ClientConnector extends Connector {
/**
* Returns the list of pending server to client RPC calls and clears the
* list.
*/
public boolean handleConnectorRequest(VaadinRequest request,
VaadinResponse response, String path) throws IOException;
+
+ /**
+ * Returns the RPC manager instance to use when receiving calls for an RPC
+ * interface.
+ *
+ * @param rpcInterfaceName
+ * name of the interface for which the call was made
+ * @return RpcManager or null if none found for the interface
+ */
+ public RpcManager getRpcManager(String rpcInterfaceName);
}
}
@Override
- public RpcManager getRpcManager(Class<?> rpcInterface) {
+ public RpcManager getRpcManager(String interfaceName) {
// TODO Use rpc for drag'n'drop
return null;
}
+++ /dev/null
-/*
- * 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.server;
-
-import java.io.Serializable;
-
-/**
- * Marker interface for server side classes that can receive RPC calls.
- *
- * This plays a role similar to that of {@link VariableOwner}.
- *
- * @since 7.0
- */
-public interface RpcTarget extends Serializable {
- /**
- * Returns the RPC manager instance to use when receiving calls for an RPC
- * interface.
- *
- * @param rpcInterface
- * interface for which the call was made
- * @return RpcManager or null if none found for the interface
- */
- public RpcManager getRpcManager(Class<?> rpcInterface);
-}
import java.util.logging.Logger;
import com.vaadin.shared.Connector;
+import com.vaadin.shared.communication.ServerRpc;
/**
* Server side RPC manager that handles RPC calls coming from the client.
*
* @since 7.0
*/
-public class ServerRpcManager<T> implements RpcManager {
+public class ServerRpcManager<T extends ServerRpc> implements RpcManager {
private final T implementation;
private final Class<T> rpcInterface;
* method invocation to perform
* @throws RpcInvocationException
*/
- public static void applyInvocation(RpcTarget target,
+ public static void applyInvocation(ClientConnector target,
ServerRpcMethodInvocation invocation) throws RpcInvocationException {
- RpcManager manager = target.getRpcManager(invocation
- .getInterfaceClass());
+ RpcManager manager = target
+ .getRpcManager(invocation.getInterfaceName());
if (manager != null) {
manager.applyInvocation(invocation);
} else {
private final Method method;
- private Class<? extends ServerRpc> interfaceClass;
+ private final Class<? extends ServerRpc> interfaceClass;
- public ServerRpcMethodInvocation(String connectorId, String interfaceName,
- String methodName, int parameterCount) {
- super(connectorId, interfaceName, methodName);
+ public ServerRpcMethodInvocation(String connectorId,
+ Class<? extends ServerRpc> interfaceClass, String methodName,
+ int parameterCount) {
+ super(connectorId, interfaceClass.getName(), methodName);
+
+ assert ServerRpc.class.isAssignableFrom(interfaceClass);
+ this.interfaceClass = interfaceClass;
- interfaceClass = findClass();
method = findInvocationMethod(interfaceClass, methodName,
parameterCount);
}
- private Class<? extends ServerRpc> findClass() {
- try {
- Class<?> rpcInterface = Class.forName(getInterfaceName());
- if (!ServerRpc.class.isAssignableFrom(rpcInterface)) {
- throw new IllegalArgumentException("The interface "
- + getInterfaceName() + "is not a server RPC interface.");
- }
- return (Class<? extends ServerRpc>) rpcInterface;
- } catch (ClassNotFoundException e) {
- throw new IllegalArgumentException("The server RPC interface "
- + getInterfaceName() + " could not be found", e);
- } finally {
-
- }
- }
-
public Class<? extends ServerRpc> getInterfaceClass() {
return interfaceClass;
}
package com.vaadin.ui;
import com.vaadin.server.JavaScriptCallbackHelper;
+import com.vaadin.shared.communication.ServerRpc;
import com.vaadin.shared.ui.JavaScriptComponentState;
/**
this);
@Override
- protected <T> void registerRpc(T implementation, Class<T> rpcInterfaceType) {
+ protected <T extends ServerRpc> void registerRpc(T implementation,
+ Class<T> rpcInterfaceType) {
super.registerRpc(implementation, rpcInterfaceType);
callbackHelper.registerRpc(rpcInterfaceType);
}