From a5f18a266fe8e746a71cd923f61a620cff247a0e Mon Sep 17 00:00:00 2001 From: Leif Åstrand Date: Thu, 3 Dec 2015 13:10:25 +0200 Subject: Check for optimizations when looking for missing updates (#18317) A recently merged patch leaves out information from hierarchyInfo for empty connectors with state changes. This must be taken into account when looking for disappeared connectors that do not cause any hierarchy change to be sent. Change-Id: I9ae7150341a83798141d0a2806ee81cafe7c2f9a --- .../communication/ConnectorHierarchyWriter.java | 7 ++-- server/src/com/vaadin/ui/ConnectorTracker.java | 41 +++++++++++++++++++++- 2 files changed, 45 insertions(+), 3 deletions(-) (limited to 'server/src/com/vaadin') diff --git a/server/src/com/vaadin/server/communication/ConnectorHierarchyWriter.java b/server/src/com/vaadin/server/communication/ConnectorHierarchyWriter.java index fe1cc0770c..16ed9985c4 100644 --- a/server/src/com/vaadin/server/communication/ConnectorHierarchyWriter.java +++ b/server/src/com/vaadin/server/communication/ConnectorHierarchyWriter.java @@ -91,16 +91,19 @@ public class ConnectorHierarchyWriter implements Serializable { } // Dummy assert just for conditionally storing away data that will be // used by the real assert later on - assert storeSentHierarchy(hierarchyInfo); + assert storeSentHierarchy(hierarchyInfo, stateUpdateConnectors); writer.write(JsonUtil.stringify(hierarchyInfo)); } - private boolean storeSentHierarchy(JsonObject hierarchyInfo) { + private boolean storeSentHierarchy(JsonObject hierarchyInfo, + Set stateUpdateConnectors) { VaadinRequest request = VaadinService.getCurrentRequest(); if (request != null) { request.setAttribute(ConnectorHierarchyWriter.class.getName() + ".hierarchyInfo", hierarchyInfo); + request.setAttribute(ConnectorHierarchyWriter.class.getName() + + ".stateUpdateConnectors", stateUpdateConnectors); } // Always true, we're just setting up for another assert diff --git a/server/src/com/vaadin/ui/ConnectorTracker.java b/server/src/com/vaadin/ui/ConnectorTracker.java index a060702319..159bd09c0d 100644 --- a/server/src/com/vaadin/ui/ConnectorTracker.java +++ b/server/src/com/vaadin/ui/ConnectorTracker.java @@ -368,7 +368,34 @@ public class ConnectorTracker implements Serializable { } if (!hierachyInfo.hasKey(firstVisibleParent.getConnectorId())) { - return false; + /* + * No hierarchy change about to be sent, but this might be + * because of an optimization that omits explicit hierarchy + * changes for empty connectors that have state changes. + */ + if (hasVisibleChild(firstVisibleParent)) { + // Not the optimization case if the parent has visible + // children + return false; + } + + attributeName = ConnectorHierarchyWriter.class.getName() + + ".stateUpdateConnectors"; + Object stateUpdateConnectorsObj = request + .getAttribute(attributeName); + if (stateUpdateConnectorsObj instanceof Set) { + Set stateUpdateConnectors = (Set) stateUpdateConnectorsObj; + if (!stateUpdateConnectors.contains(firstVisibleParent + .getConnectorId())) { + // Not the optimization case if the parent is not marked + // as dirty + return false; + } + } else { + getLogger().warning( + "Request attribute " + attributeName + + " is not a Set"); + } } } else { getLogger().warning( @@ -379,6 +406,18 @@ public class ConnectorTracker implements Serializable { return true; } + private static boolean hasVisibleChild(ClientConnector parent) { + Iterator iterator = AbstractClientConnector + .getAllChildrenIterable(parent).iterator(); + while (iterator.hasNext()) { + ClientConnector child = iterator.next(); + if (LegacyCommunicationManager.isConnectorVisibleToClient(child)) { + return true; + } + } + return false; + } + private ClientConnector findFirstVisibleParent(ClientConnector connector) { while (connector != null) { connector = connector.getParent(); -- cgit v1.2.3