Skip to content

Commit

Permalink
Add RPC support for composite components (#4298)
Browse files Browse the repository at this point in the history
* Add RPC support for composite components

* Support composite of composite

* Split method search in hierarchy
  • Loading branch information
heruan authored and gilberto-torrezan committed Jul 11, 2018
1 parent 5649b4f commit 2edefaf
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

import com.vaadin.flow.component.ClientCallable;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.Composite;
import com.vaadin.flow.component.polymertemplate.EventHandler;
import com.vaadin.flow.component.polymertemplate.PolymerTemplate;
import com.vaadin.flow.dom.DisabledUpdateMode;
Expand Down Expand Up @@ -123,6 +124,23 @@ public Optional<Runnable> handleNode(StateNode node,
static void invokeMethod(Component instance, Class<?> clazz,
String methodName, JsonArray args) {
assert instance != null;
Optional<Method> method = findMethod(instance, clazz, methodName);
if (method.isPresent()) {
invokeMethod(instance, method.get(), args);
} else if (instance instanceof Composite) {
Component compositeContent = ((Composite<?>) instance).getContent();
invokeMethod(compositeContent, compositeContent.getClass(),
methodName, args);
} else {
String msg = String.format("Neither class '%s' "
+ "nor its super classes declare event handler method '%s'",
instance.getClass().getName(), methodName);
throw new IllegalStateException(msg);
}
}

private static Optional<Method> findMethod(Component instance,
Class<?> clazz, String methodName) {
List<Method> methods = Stream.of(clazz.getDeclaredMethods())
.filter(method -> methodName.equals(method.getName()))
.filter(method -> method.isAnnotationPresent(EventHandler.class)
Expand All @@ -134,14 +152,11 @@ static void invokeMethod(Component instance, Class<?> clazz,
instance.getClass().getName(), methodName);
throw new IllegalStateException(msg);
} else if (methods.size() == 1) {
invokeMethod(instance, methods.get(0), args);
return Optional.of(methods.get(0));
} else if (!Component.class.equals(clazz)) {
invokeMethod(instance, clazz.getSuperclass(), methodName, args);
return findMethod(instance, clazz.getSuperclass(), methodName);
} else {
String msg = String.format("Neither class '%s' "
+ "nor its super classes declare event handler method '%s'",
instance.getClass().getName(), methodName);
throw new IllegalStateException(msg);
return Optional.empty();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.vaadin.flow.server.communication.rpc;

import net.jcip.annotations.NotThreadSafe;
import org.jsoup.nodes.Element;
import org.junit.After;
import org.junit.Assert;
Expand All @@ -24,6 +25,7 @@

import com.vaadin.flow.component.ClientCallable;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.Composite;
import com.vaadin.flow.component.EventData;
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.UI;
Expand All @@ -40,7 +42,6 @@
import elemental.json.JsonArray;
import elemental.json.JsonObject;
import elemental.json.JsonValue;
import net.jcip.annotations.NotThreadSafe;

@NotThreadSafe
public class PublishedServerEventHandlerRpcHandlerTest {
Expand All @@ -53,7 +54,7 @@ public static class ComponentWithMethod

private boolean isInvoked;

ComponentWithMethod() {
public ComponentWithMethod() {
super((clazz, tag, service) -> new TemplateData("",
new Element("a")));
}
Expand Down Expand Up @@ -189,6 +190,14 @@ public void operation() {
}
}

public static class CompositeOfComponentWithMethod
extends Composite<ComponentWithMethod> {
}

public static class CompositeOfComposite
extends Composite<CompositeOfComponentWithMethod> {
}

@Before
public void setUp() {
Assert.assertNull(System.getSecurityManager());
Expand Down Expand Up @@ -217,6 +226,26 @@ public void methodIsInvoked() {
Assert.assertTrue(component.isInvoked);
}

@Test
public void methodIsInvokedOnCompositeContent() {
CompositeOfComponentWithMethod composite = new CompositeOfComponentWithMethod();
ComponentWithMethod component = composite.getContent();
PublishedServerEventHandlerRpcHandler.invokeMethod(composite,
composite.getClass(), "method", Json.createArray());

Assert.assertTrue(component.isInvoked);
}

@Test
public void methodIsInvokectOnCompositeOfComposite() {
CompositeOfComposite composite = new CompositeOfComposite();
ComponentWithMethod component = composite.getContent().getContent();
PublishedServerEventHandlerRpcHandler.invokeMethod(composite,
composite.getClass(), "method", Json.createArray());

Assert.assertTrue(component.isInvoked);
}

@Test
public void methodWithDecoderParameters_convertableValues_methodIsInvoked() {
JsonArray params = Json.createArray();
Expand Down

0 comments on commit 2edefaf

Please sign in to comment.