use of com.vaadin.flow.internal.StateNode in project flow by vaadin.
the class AttachExistingElementRpcHandlerTest method handleNode_requestedIdAndAssignedIdAreDifferent.
@Test
public void handleNode_requestedIdAndAssignedIdAreDifferent() {
AttachExistingElementRpcHandler handler = new AttachExistingElementRpcHandler();
int requestedId = 1;
int assignedId = 2;
int index = 3;
JsonObject object = Json.createObject();
object.put(JsonConstants.RPC_ATTACH_REQUESTED_ID, requestedId);
object.put(JsonConstants.RPC_ATTACH_ASSIGNED_ID, assignedId);
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);
StateNode assigned = 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(tree.getNodeById(assignedId)).thenReturn(assigned);
Mockito.when(assigned.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, Mockito.times(0)).insertChild(index, Element.get(assigned));
Mockito.verify(consumer).accept(Element.get(assigned));
}
use of com.vaadin.flow.internal.StateNode in project flow by vaadin.
the class HtmlComponentSmokeTest method testSetter.
private static void testSetter(HtmlComponent instance, Method setter) {
Class<?> propertyType = setter.getParameterTypes()[0];
Method getter = findGetter(setter);
Class<?> getterType = getter.getReturnType();
boolean isOptional = (getterType == Optional.class);
if (isOptional) {
// setFoo(String) + Optional<String> getFoo() is ok
Type gen = getter.getGenericReturnType();
getterType = (Class<?>) ((ParameterizedType) gen).getActualTypeArguments()[0];
}
Assert.assertEquals(setter + " should have the same type as its getter", propertyType, getterType);
Map<Class<?>, Object> specialValueMap = specialTestValues.get(instance.getClass());
Object testValue;
if (specialValueMap != null && specialValueMap.containsKey(propertyType)) {
testValue = specialValueMap.get(propertyType);
} else {
testValue = testValues.get(propertyType);
}
if (testValue == null) {
throw new UnsupportedOperationException("No test value for " + propertyType);
}
StateNode elementNode = instance.getElement().getNode();
try {
// Purge all pending changes
elementNode.collectChanges(c -> {
});
setter.invoke(instance, testValue);
// Might have to add a blacklist for this logic at some point
Assert.assertTrue(setter + " should update the underlying state node", hasPendingChanges(elementNode));
Object getterValue = getter.invoke(instance);
if (isOptional) {
getterValue = ((Optional<?>) getterValue).get();
}
AssertUtils.assertEquals(getter + " should return the set value", testValue, getterValue);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}
use of com.vaadin.flow.internal.StateNode in project flow by vaadin.
the class StreamReceiverHandler method handleRequest.
/**
* Handle reception of incoming stream from the client.
*
* @param session
* The session for the request
* @param request
* The request to handle
* @param response
* The response object to which a response can be written.
* @param streamReceiver
* the receiver containing the destination stream variable
* @param uiId
* id of the targeted ui
* @param securityKey
* security from the request that should match registered stream
* receiver id
* @throws IOException
* if an IO error occurred
*/
public void handleRequest(VaadinSession session, VaadinRequest request, VaadinResponse response, StreamReceiver streamReceiver, String uiId, String securityKey) throws IOException {
StateNode source;
session.lock();
try {
String secKey = streamReceiver.getId();
if (secKey == null || !MessageDigest.isEqual(secKey.getBytes(StandardCharsets.UTF_8), securityKey.getBytes(StandardCharsets.UTF_8))) {
getLogger().warn("Received incoming stream with faulty security key.");
return;
}
UI ui = session.getUIById(Integer.parseInt(uiId));
UI.setCurrent(ui);
source = streamReceiver.getNode();
} finally {
session.unlock();
}
try {
if (isMultipartUpload(request)) {
doHandleMultipartFileUpload(session, request, response, streamReceiver, source);
} else {
// if boundary string does not exist, the posted file is from
// XHR2.post(File)
doHandleXhrFilePost(session, request, response, streamReceiver, source, getContentLength(request));
}
} finally {
UI.setCurrent(null);
}
}
use of com.vaadin.flow.internal.StateNode 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());
}
use of com.vaadin.flow.internal.StateNode 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 succeeded. " + "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");
}
}
Aggregations