summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeif Åstrand <leif@vaadin.com>2015-12-03 13:10:25 +0200
committerLeif Åstrand <leif@vaadin.com>2015-12-03 13:10:25 +0200
commita5f18a266fe8e746a71cd923f61a620cff247a0e (patch)
treeccb3dc2d2239585f8c3f79eb5f131ff61ca9ce86
parent85a1e621e7b64bb16de61b5f511837362a90b352 (diff)
downloadvaadin-framework-a5f18a266fe8e746a71cd923f61a620cff247a0e.tar.gz
vaadin-framework-a5f18a266fe8e746a71cd923f61a620cff247a0e.zip
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
-rw-r--r--server/src/com/vaadin/server/communication/ConnectorHierarchyWriter.java7
-rw-r--r--server/src/com/vaadin/ui/ConnectorTracker.java41
-rw-r--r--uitest/src/com/vaadin/tests/application/MissingHierarchyDetection.java15
3 files changed, 57 insertions, 6 deletions
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<String> 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<? extends ClientConnector> 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();
diff --git a/uitest/src/com/vaadin/tests/application/MissingHierarchyDetection.java b/uitest/src/com/vaadin/tests/application/MissingHierarchyDetection.java
index 3f55e7bd60..508ac818f6 100644
--- a/uitest/src/com/vaadin/tests/application/MissingHierarchyDetection.java
+++ b/uitest/src/com/vaadin/tests/application/MissingHierarchyDetection.java
@@ -27,7 +27,10 @@ import com.vaadin.ui.SelectiveRenderer;
public class MissingHierarchyDetection extends AbstractTestUI {
private boolean isChildRendered = true;
- private BrokenCssLayout layout = new BrokenCssLayout();
+ private BrokenCssLayout brokenLayout = new BrokenCssLayout();
+
+ private CssLayout normalLayout = new CssLayout(new Label(
+ "Normal layout child"));
public class BrokenCssLayout extends CssLayout implements SelectiveRenderer {
public BrokenCssLayout() {
@@ -45,7 +48,8 @@ public class MissingHierarchyDetection extends AbstractTestUI {
@Override
protected void setup(VaadinRequest request) {
- addComponent(layout);
+ addComponent(brokenLayout);
+ addComponent(normalLayout);
addComponent(new Button("Toggle properly", new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
@@ -64,7 +68,12 @@ public class MissingHierarchyDetection extends AbstractTestUI {
private void toggle(boolean properly) {
isChildRendered = !isChildRendered;
if (properly) {
- layout.markAsDirtyRecursive();
+ brokenLayout.markAsDirtyRecursive();
}
+
+ normalLayout.getComponent(0).setVisible(isChildRendered);
+ // Must also have a state change of the layout to trigger special case
+ // related to optimizations
+ normalLayout.setCaption("With child: " + isChildRendered);
}
}