Search in sources :

Example 1 with ReturnChannelRegistration

use of com.vaadin.flow.internal.nodefeature.ReturnChannelRegistration in project flow by vaadin.

the class UidlWriter method encodeExecuteJavaScript.

private static JsonArray encodeExecuteJavaScript(PendingJavaScriptInvocation invocation) {
    List<Object> parametersList = invocation.getInvocation().getParameters();
    Stream<Object> parameters = parametersList.stream();
    String expression = invocation.getInvocation().getExpression();
    if (invocation.isSubscribed()) {
        StateNode owner = invocation.getOwner();
        List<ReturnChannelRegistration> channels = new ArrayList<>();
        ReturnChannelRegistration successChannel = createReturnValueChannel(owner, channels, invocation::complete);
        ReturnChannelRegistration errorChannel = createReturnValueChannel(owner, channels, invocation::completeExceptionally);
        // Inject both channels as new parameters
        parameters = Stream.concat(parameters, Stream.of(successChannel, errorChannel));
        int successIndex = parametersList.size();
        int errorIndex = successIndex + 1;
        /*
             * Run the original expression wrapped in a function to capture any
             * return statement. Pass the return value through Promise.resolve
             * which resolves regular values immediately and waits for thenable
             * values. Call either of the handlers once the promise completes.
             * If the expression throws synchronously, run the error handler.
             */
        // @formatter:off
        expression = "try{" + "Promise.resolve((function(){" + expression + "})()).then($" + successIndex + ",function(error){$" + errorIndex + "(''+error)})" + "}catch(error){" + "$" + errorIndex + "(''+error)" + "}";
    // @formatter:on
    }
    // [argument1, argument2, ..., script]
    return Stream.concat(parameters.map(JsonCodec::encodeWithTypeInfo), Stream.of(Json.create(expression))).collect(JsonUtils.asArray());
}
Also used : JsonCodec(com.vaadin.flow.internal.JsonCodec) ReturnChannelRegistration(com.vaadin.flow.internal.nodefeature.ReturnChannelRegistration) StateNode(com.vaadin.flow.internal.StateNode) ArrayList(java.util.ArrayList) JsonObject(elemental.json.JsonObject)

Example 2 with ReturnChannelRegistration

use of com.vaadin.flow.internal.nodefeature.ReturnChannelRegistration in project flow by vaadin.

the class ReturnChannelHandlerTest method happyPath_everythingWorks.

@Test
public void happyPath_everythingWorks() {
    ReturnChannelRegistration registration = registerUiChannel();
    handleMessage(registration);
    Assert.assertSame("Handler should have been invoked with the given arguments.", args, observedArguments.get());
}
Also used : ReturnChannelRegistration(com.vaadin.flow.internal.nodefeature.ReturnChannelRegistration) Test(org.junit.Test)

Example 3 with ReturnChannelRegistration

use of com.vaadin.flow.internal.nodefeature.ReturnChannelRegistration in project flow by vaadin.

the class ReturnChannelHandlerTest method disabledElement_registrationAlwaysAllowed_invocationProcessed.

@Test
public void disabledElement_registrationAlwaysAllowed_invocationProcessed() {
    ReturnChannelRegistration registration = registerUiChannel();
    registration.setDisabledUpdateMode(DisabledUpdateMode.ALWAYS);
    ui.setEnabled(false);
    handleMessage(registration);
    Assert.assertNotNull("Channel handler should be called", observedArguments.get());
}
Also used : ReturnChannelRegistration(com.vaadin.flow.internal.nodefeature.ReturnChannelRegistration) Test(org.junit.Test)

Example 4 with ReturnChannelRegistration

use of com.vaadin.flow.internal.nodefeature.ReturnChannelRegistration in project flow by vaadin.

the class ReturnChannelHandler method handleNode.

@Override
protected Optional<Runnable> handleNode(StateNode node, JsonObject invocationJson) {
    int channelId = (int) invocationJson.getNumber(JsonConstants.RPC_CHANNEL);
    JsonArray arguments = invocationJson.getArray(JsonConstants.RPC_CHANNEL_ARGUMENTS);
    if (!node.hasFeature(ReturnChannelMap.class)) {
        getLogger().warn("Node has no return channels: {}", invocationJson);
        return Optional.empty();
    }
    ReturnChannelRegistration channel = node.getFeatureIfInitialized(ReturnChannelMap.class).map(map -> map.get(channelId)).orElse(null);
    if (channel == null) {
        getLogger().warn("Return channel not found: {}", invocationJson);
        return Optional.empty();
    }
    if (!node.isEnabled() && channel.getDisabledUpdateMode() != DisabledUpdateMode.ALWAYS) {
        getLogger().warn("Ignoring update for disabled return channel: {}", invocationJson);
        return Optional.empty();
    }
    channel.invoke(arguments);
    return Optional.empty();
}
Also used : JsonArray(elemental.json.JsonArray) ReturnChannelMap(com.vaadin.flow.internal.nodefeature.ReturnChannelMap) AbstractRpcInvocationHandler(com.vaadin.flow.server.communication.rpc.AbstractRpcInvocationHandler) DisabledUpdateMode(com.vaadin.flow.dom.DisabledUpdateMode) Logger(org.slf4j.Logger) StateNode(com.vaadin.flow.internal.StateNode) JsonConstants(com.vaadin.flow.shared.JsonConstants) LoggerFactory(org.slf4j.LoggerFactory) ReturnChannelRegistration(com.vaadin.flow.internal.nodefeature.ReturnChannelRegistration) Optional(java.util.Optional) JsonArray(elemental.json.JsonArray) JsonObject(elemental.json.JsonObject) ReturnChannelRegistration(com.vaadin.flow.internal.nodefeature.ReturnChannelRegistration) ReturnChannelMap(com.vaadin.flow.internal.nodefeature.ReturnChannelMap)

Example 5 with ReturnChannelRegistration

use of com.vaadin.flow.internal.nodefeature.ReturnChannelRegistration in project flow by vaadin.

the class UidlWriter method createReturnValueChannel.

private static ReturnChannelRegistration createReturnValueChannel(StateNode owner, List<ReturnChannelRegistration> registrations, SerializableConsumer<JsonValue> action) {
    ReturnChannelRegistration channel = owner.getFeature(ReturnChannelMap.class).registerChannel(arguments -> {
        registrations.forEach(ReturnChannelRegistration::remove);
        action.accept(arguments.get(0));
    });
    registrations.add(channel);
    return channel;
}
Also used : ReturnChannelRegistration(com.vaadin.flow.internal.nodefeature.ReturnChannelRegistration) ReturnChannelMap(com.vaadin.flow.internal.nodefeature.ReturnChannelMap)

Aggregations

ReturnChannelRegistration (com.vaadin.flow.internal.nodefeature.ReturnChannelRegistration)7 Test (org.junit.Test)4 StateNode (com.vaadin.flow.internal.StateNode)2 ReturnChannelMap (com.vaadin.flow.internal.nodefeature.ReturnChannelMap)2 JsonObject (elemental.json.JsonObject)2 DisabledUpdateMode (com.vaadin.flow.dom.DisabledUpdateMode)1 JsonCodec (com.vaadin.flow.internal.JsonCodec)1 AbstractRpcInvocationHandler (com.vaadin.flow.server.communication.rpc.AbstractRpcInvocationHandler)1 JsonConstants (com.vaadin.flow.shared.JsonConstants)1 JsonArray (elemental.json.JsonArray)1 ArrayList (java.util.ArrayList)1 Optional (java.util.Optional)1 Logger (org.slf4j.Logger)1 LoggerFactory (org.slf4j.LoggerFactory)1