diff options
author | vandeti <tvanderwee@gmail.com> | 2015-04-04 14:55:00 +0200 |
---|---|---|
committer | Vaadin Code Review <review@vaadin.com> | 2015-05-28 12:43:59 +0000 |
commit | fdd6a9d9d00fbb0e94c96226744deab563b1cd63 (patch) | |
tree | fee7f9715385723347acca0057b0f8690fb601a9 | |
parent | 3b7ddf8aa06379a09ff534ae1a89977164937b89 (diff) | |
download | vaadin-framework-fdd6a9d9d00fbb0e94c96226744deab563b1cd63.tar.gz vaadin-framework-fdd6a9d9d00fbb0e94c96226744deab563b1cd63.zip |
Less restrictive RPC interface detection in registerRpc (#10945)
Change-Id: I664740523b35b64b0fd0c4fdc21597a2245537cd
-rw-r--r-- | server/src/com/vaadin/server/AbstractClientConnector.java | 40 | ||||
-rw-r--r-- | server/tests/src/com/vaadin/server/AbstractClientConnectorTest.java | 112 |
2 files changed, 141 insertions, 11 deletions
diff --git a/server/src/com/vaadin/server/AbstractClientConnector.java b/server/src/com/vaadin/server/AbstractClientConnector.java index 87b61c9623..0655b482ed 100644 --- a/server/src/com/vaadin/server/AbstractClientConnector.java +++ b/server/src/com/vaadin/server/AbstractClientConnector.java @@ -180,22 +180,40 @@ public abstract class AbstractClientConnector implements ClientConnector, * RPC interface implementation. Also used to deduce the type. */ protected <T extends ServerRpc> void registerRpc(T implementation) { + // Search upwards until an interface is found. It must be found as T + // extends ServerRpc Class<?> cls = implementation.getClass(); - Class<?>[] interfaces = cls.getInterfaces(); - while (interfaces.length == 0) { - // Search upwards until an interface is found. It must be found as T - // extends ServerRpc + Class<ServerRpc> serverRpcClass = getServerRpcInterface(cls); + + while (cls != null && serverRpcClass == null) { cls = cls.getSuperclass(); - interfaces = cls.getInterfaces(); + serverRpcClass = getServerRpcInterface(cls); } - if (interfaces.length != 1 - || !(ServerRpc.class.isAssignableFrom(interfaces[0]))) { + + if (serverRpcClass == null) { throw new RuntimeException( - "Use registerRpc(T implementation, Class<T> rpcInterfaceType) if the Rpc implementation implements more than one interface"); + "No interface T extends ServerRpc found in the class hierarchy."); + } + + registerRpc(implementation, serverRpcClass); + } + + @SuppressWarnings("unchecked") + private Class<ServerRpc> getServerRpcInterface(Class<?> implementationClass) { + Class<ServerRpc> serverRpcClass = null; + if (implementationClass != null) { + for (Class<?> candidateInterface : implementationClass + .getInterfaces()) { + if (ServerRpc.class.isAssignableFrom(candidateInterface)) { + if (serverRpcClass != null) { + throw new RuntimeException( + "Use registerRpc(T implementation, Class<T> rpcInterfaceType) if the Rpc implementation implements more than one interface"); + } + serverRpcClass = (Class<ServerRpc>) candidateInterface; + } + } } - @SuppressWarnings("unchecked") - Class<T> type = (Class<T>) interfaces[0]; - registerRpc(implementation, type); + return serverRpcClass; } /** diff --git a/server/tests/src/com/vaadin/server/AbstractClientConnectorTest.java b/server/tests/src/com/vaadin/server/AbstractClientConnectorTest.java new file mode 100644 index 0000000000..96ca82a0b3 --- /dev/null +++ b/server/tests/src/com/vaadin/server/AbstractClientConnectorTest.java @@ -0,0 +1,112 @@ +/* + * Copyright 2000-2014 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 static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; + +import com.vaadin.shared.MouseEventDetails; +import com.vaadin.shared.communication.FieldRpc.BlurServerRpc; +import com.vaadin.shared.ui.ClickRpc; + +/** + * We test that AbstractClientConnector has a suitable isThis method which is + * needed to correctly perform an equals check between a proxy and it's + * underlying instance. + * + * @author Vaadin Ltd + */ +public class AbstractClientConnectorTest { + + @Test + public void registerRPCMultiInterfaceTest() { + AbstractClientConnector mock = mock(AbstractClientConnector.class); + MultiServerRpcMock implementation = new MultiServerRpcMock(); + Mockito.doCallRealMethod().when(mock).registerRpc(implementation); + try { + mock.registerRpc(implementation); + Assert.fail("expected exception"); + } catch (Exception expected) { + Assert.assertEquals( + expected.getMessage(), + "Use registerRpc(T implementation, Class<T> rpcInterfaceType) if the Rpc implementation implements more than one interface"); + } + } + + @Test + public void registerRPCInterfaceTest() { + AbstractClientConnector mock = mock(AbstractClientConnector.class); + ServerRpcMock implementation = new ServerRpcMock(); + Mockito.doCallRealMethod().when(mock).registerRpc(implementation); + mock.registerRpc(implementation); + verify(mock, times(1)).registerRpc(implementation, ClickRpc.class); + } + + @Test + public void registerRPCInterfaceLastTest() { + AbstractClientConnector mock = mock(AbstractClientConnector.class); + ServerRpcLastMock implementation = new ServerRpcLastMock(); + Mockito.doCallRealMethod().when(mock).registerRpc(implementation); + mock.registerRpc(implementation); + verify(mock, times(1)).registerRpc(implementation, ClickRpc.class); + } + + private class ServerRpcLastMock implements Comparable<ServerRpcLastMock>, + ClickRpc { + private static final long serialVersionUID = -2822356895755286180L; + + @Override + public void click(MouseEventDetails mouseDetails) { + } + + @Override + public int compareTo(ServerRpcLastMock o) { + return 0; + } + + } + + private class ServerRpcMock implements ClickRpc { + private static final long serialVersionUID = 2822356895755286180L; + + @Override + public void click(MouseEventDetails mouseDetails) { + } + + } + + private class MultiServerRpcMock implements ClickRpc, BlurServerRpc { + + private static final long serialVersionUID = -7611999715560330373L; + + @Override + public void blur() { + + } + + @Override + public void click(MouseEventDetails mouseDetails) { + + } + + } + +} |