Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add RPC support for composite components #4298

Merged
merged 3 commits into from
Jun 28, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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