Search in sources :

Example 6 with StateTree

use of com.vaadin.flow.internal.StateTree in project flow by vaadin.

the class AttachTemplateChildRpcHandler method handleNode.

@Override
protected Optional<Runnable> handleNode(StateNode node, JsonObject invocationJson) {
    assert invocationJson.hasKey(JsonConstants.RPC_ATTACH_REQUESTED_ID);
    assert invocationJson.hasKey(JsonConstants.RPC_ATTACH_ASSIGNED_ID);
    assert invocationJson.hasKey(JsonConstants.RPC_ATTACH_ID);
    int requestedId = (int) invocationJson.getNumber(JsonConstants.RPC_ATTACH_REQUESTED_ID);
    int assignedId = (int) invocationJson.getNumber(JsonConstants.RPC_ATTACH_ASSIGNED_ID);
    StateTree tree = (StateTree) node.getOwner();
    StateNode requestedNode = tree.getNodeById(requestedId);
    StateNode parent = tree.getNodeById(requestedId).getParent();
    JsonValue id = invocationJson.get(JsonConstants.RPC_ATTACH_ID);
    String tag = requestedNode.getFeature(ElementData.class).getTag();
    Logger logger = LoggerFactory.getLogger(AttachTemplateChildRpcHandler.class.getName());
    if (assignedId == -1) {
        logger.error("Attach existing element has failed because " + "the client-side element is not found");
        if (id instanceof JsonNull) {
            throw new IllegalStateException(String.format("The element with the tag name '%s' was " + "not found in the parent with id='%d'", tag, parent.getId()));
        } else {
            throw new IllegalStateException(String.format("The element with the tag name '%s' and id '%s' was " + "not found in the parent with id='%d'", tag, id.asString(), parent.getId()));
        }
    } else if (requestedId != assignedId) {
        logger.error("Attach existing element has failed because " + "the element has been already attached from the server side");
        if (id instanceof JsonNull) {
            throw new IllegalStateException(String.format("The element with the tag name '%s' is already " + "attached to the parent with id='%d'", tag, parent.getId()));
        } else {
            throw new IllegalStateException(String.format("The element with the tag name '%s' and id '%s' is " + "already attached to the parent with id='%d'", tag, id.asString(), parent.getId()));
        }
    } else {
        logger.error("Attach existing element request succeded. " + "But the response about this is unexpected");
        // side should not respond
        throw new IllegalArgumentException("Unexpected successful attachment " + "response is received from the client-side. " + "Client side should not respond if everything is fine");
    }
}
Also used : StateTree(com.vaadin.flow.internal.StateTree) StateNode(com.vaadin.flow.internal.StateNode) JsonValue(elemental.json.JsonValue) ElementData(com.vaadin.flow.internal.nodefeature.ElementData) Logger(org.slf4j.Logger) JsonNull(elemental.json.JsonNull)

Example 7 with StateTree

use of com.vaadin.flow.internal.StateTree in project flow by vaadin.

the class MapSyncRpcHandler method tryConvert.

private Serializable tryConvert(Serializable value, StateNode context) {
    if (value instanceof JsonObject) {
        JsonObject json = (JsonObject) value;
        if (json.hasKey("nodeId")) {
            StateTree tree = (StateTree) context.getOwner();
            double id = json.getNumber("nodeId");
            StateNode stateNode = tree.getNodeById((int) id);
            return tryCopyStateNode(stateNode, json);
        }
    }
    return value;
}
Also used : StateTree(com.vaadin.flow.internal.StateTree) StateNode(com.vaadin.flow.internal.StateNode) JsonObject(elemental.json.JsonObject)

Example 8 with StateTree

use of com.vaadin.flow.internal.StateTree in project flow by vaadin.

the class AttachExistingElementRpcHandlerTest method handleNode_error.

@Test
public void handleNode_error() {
    AttachExistingElementRpcHandler handler = new AttachExistingElementRpcHandler();
    int requestedId = 1;
    JsonObject object = Json.createObject();
    object.put(JsonConstants.RPC_ATTACH_REQUESTED_ID, requestedId);
    object.put(JsonConstants.RPC_ATTACH_ASSIGNED_ID, -1);
    object.put(JsonConstants.RPC_ATTACH_TAG_NAME, "div");
    object.put(JsonConstants.RPC_ATTACH_INDEX, -1);
    StateNode node = Mockito.mock(StateNode.class);
    StateNode requested = Mockito.mock(StateNode.class);
    StateTree tree = Mockito.mock(StateTree.class);
    Mockito.when(node.getOwner()).thenReturn(tree);
    Mockito.when(tree.getNodeById(requestedId)).thenReturn(requested);
    AttachExistingElementFeature feature = new AttachExistingElementFeature(node);
    Node<?> parentNode = Mockito.mock(Node.class);
    ChildElementConsumer consumer = Mockito.mock(ChildElementConsumer.class);
    Element sibling = Mockito.mock(Element.class);
    feature.register(parentNode, sibling, requested, consumer);
    Mockito.when(node.getFeature(AttachExistingElementFeature.class)).thenReturn(feature);
    handler.handleNode(node, object);
    Mockito.verify(consumer).onError(parentNode, "div", sibling);
    assertNodeIsUnregistered(node, requested, feature);
}
Also used : StateTree(com.vaadin.flow.internal.StateTree) ChildElementConsumer(com.vaadin.flow.dom.ChildElementConsumer) Element(com.vaadin.flow.dom.Element) StateNode(com.vaadin.flow.internal.StateNode) JsonObject(elemental.json.JsonObject) AttachExistingElementFeature(com.vaadin.flow.internal.nodefeature.AttachExistingElementFeature) AttachExistingElementRpcHandler(com.vaadin.flow.server.communication.rpc.AttachExistingElementRpcHandler) Test(org.junit.Test)

Example 9 with StateTree

use of com.vaadin.flow.internal.StateTree in project flow by vaadin.

the class AttachExistingElementRpcHandlerTest method handleNode_requestedIdEqualsAssignedId.

@Test
public void handleNode_requestedIdEqualsAssignedId() {
    AttachExistingElementRpcHandler handler = new AttachExistingElementRpcHandler();
    int requestedId = 1;
    int index = 2;
    JsonObject object = Json.createObject();
    object.put(JsonConstants.RPC_ATTACH_REQUESTED_ID, requestedId);
    object.put(JsonConstants.RPC_ATTACH_ASSIGNED_ID, requestedId);
    object.put(JsonConstants.RPC_ATTACH_TAG_NAME, "div");
    object.put(JsonConstants.RPC_ATTACH_INDEX, index);
    StateNode node = Mockito.mock(StateNode.class);
    StateNode requested = Mockito.mock(StateNode.class);
    StateTree tree = Mockito.mock(StateTree.class);
    Mockito.when(node.getOwner()).thenReturn(tree);
    Mockito.when(tree.getNodeById(requestedId)).thenReturn(requested);
    Mockito.when(requested.hasFeature(Mockito.any())).thenReturn(true);
    AttachExistingElementFeature feature = new AttachExistingElementFeature(node);
    Node<?> parentNode = Mockito.mock(Node.class);
    ChildElementConsumer consumer = Mockito.mock(ChildElementConsumer.class);
    Element sibling = Mockito.mock(Element.class);
    feature.register(parentNode, sibling, requested, consumer);
    Mockito.when(node.getFeature(AttachExistingElementFeature.class)).thenReturn(feature);
    handler.handleNode(node, object);
    assertNodeIsUnregistered(node, requested, feature);
    Mockito.verify(parentNode).insertChild(index, Element.get(requested));
    Mockito.verify(consumer).accept(Element.get(requested));
}
Also used : StateTree(com.vaadin.flow.internal.StateTree) ChildElementConsumer(com.vaadin.flow.dom.ChildElementConsumer) Element(com.vaadin.flow.dom.Element) StateNode(com.vaadin.flow.internal.StateNode) JsonObject(elemental.json.JsonObject) AttachExistingElementFeature(com.vaadin.flow.internal.nodefeature.AttachExistingElementFeature) AttachExistingElementRpcHandler(com.vaadin.flow.server.communication.rpc.AttachExistingElementRpcHandler) Test(org.junit.Test)

Example 10 with StateTree

use of com.vaadin.flow.internal.StateTree in project flow by vaadin.

the class UidlWriter method encodeChanges.

/**
 * Encodes the state tree changes of the given UI. The executions registered
 * at
 * {@link StateTree#beforeClientResponse(com.vaadin.flow.internal.StateNode, com.vaadin.flow.function.SerializableConsumer)}
 * at evaluated before the changes are encoded.
 *
 * @param ui
 *            the UI
 * @param stateChanges
 *            a JSON array to put state changes into
 * @param templates
 *            a JSON object to put new template nodes into
 * @see StateTree#runExecutionsBeforeClientResponse()
 */
private void encodeChanges(UI ui, JsonArray stateChanges, JsonObject templates) {
    UIInternals uiInternals = ui.getInternals();
    StateTree stateTree = uiInternals.getStateTree();
    stateTree.runExecutionsBeforeClientResponse();
    Consumer<TemplateNode> templateEncoder = new Consumer<TemplateNode>() {

        @Override
        public void accept(TemplateNode templateNode) {
            // Send to client if it's a new template
            if (!uiInternals.isTemplateSent(templateNode)) {
                uiInternals.setTemplateSent(templateNode);
                templates.put(Integer.toString(templateNode.getId()), templateNode.toJson(this));
            }
        }
    };
    Set<Class<? extends Component>> componentsWithDependencies = new LinkedHashSet<>();
    stateTree.collectChanges(change -> {
        // Ensure new templates are sent to the client
        runIfNewTemplateChange(change, templateEncoder);
        if (attachesComponent(change)) {
            change.getNode().getFeature(ComponentMapping.class).getComponent().ifPresent(component -> addComponentHierarchy(ui, componentsWithDependencies, component));
        }
        // Encode the actual change
        stateChanges.set(stateChanges.length(), change.toJson(uiInternals.getConstantPool()));
    });
    componentsWithDependencies.forEach(uiInternals::addComponentDependencies);
}
Also used : TemplateNode(com.vaadin.flow.template.angular.TemplateNode) LinkedHashSet(java.util.LinkedHashSet) StateTree(com.vaadin.flow.internal.StateTree) Consumer(java.util.function.Consumer) UIInternals(com.vaadin.flow.component.internal.UIInternals) Component(com.vaadin.flow.component.Component)

Aggregations

StateTree (com.vaadin.flow.internal.StateTree)13 StateNode (com.vaadin.flow.internal.StateNode)10 Test (org.junit.Test)7 Element (com.vaadin.flow.dom.Element)5 JsonObject (elemental.json.JsonObject)5 UI (com.vaadin.flow.component.UI)4 ChildElementConsumer (com.vaadin.flow.dom.ChildElementConsumer)4 AttachExistingElementFeature (com.vaadin.flow.internal.nodefeature.AttachExistingElementFeature)4 ElementChildrenList (com.vaadin.flow.internal.nodefeature.ElementChildrenList)4 AttachExistingElementRpcHandler (com.vaadin.flow.server.communication.rpc.AttachExistingElementRpcHandler)3 ElementData (com.vaadin.flow.internal.nodefeature.ElementData)2 JsonValue (elemental.json.JsonValue)2 Component (com.vaadin.flow.component.Component)1 UIInternals (com.vaadin.flow.component.internal.UIInternals)1 StateNodeTest (com.vaadin.flow.internal.StateNodeTest)1 AttachTemplateChildRpcHandler (com.vaadin.flow.server.communication.rpc.AttachTemplateChildRpcHandler)1 TemplateNode (com.vaadin.flow.template.angular.TemplateNode)1 JsonNull (elemental.json.JsonNull)1 LinkedHashSet (java.util.LinkedHashSet)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1