diff options
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); } } |