diff options
author | Leif Åstrand <leif@vaadin.com> | 2012-08-28 13:19:13 +0300 |
---|---|---|
committer | Leif Åstrand <leif@vaadin.com> | 2012-08-28 13:19:47 +0300 |
commit | 9995fe0b4f0f77bf6542faef3419ef6aa2a63ed1 (patch) | |
tree | 7ca3c9b5a612a05118bb369d159889c5f24ebaca /client | |
parent | de172c0ecd4c5a8e33114e02cf8e7d4ce5fc2d79 (diff) | |
download | vaadin-framework-9995fe0b4f0f77bf6542faef3419ef6aa2a63ed1.tar.gz vaadin-framework-9995fe0b4f0f77bf6542faef3419ef6aa2a63ed1.zip |
Fire change event for default values in newly created state (#9422)
Diffstat (limited to 'client')
4 files changed, 100 insertions, 19 deletions
diff --git a/client/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/client/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java index 450972ddc6..a984433907 100644 --- a/client/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java +++ b/client/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java @@ -18,6 +18,7 @@ package com.vaadin.terminal.gwt.client; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -74,6 +75,7 @@ import com.vaadin.terminal.gwt.client.metadata.Property; import com.vaadin.terminal.gwt.client.metadata.Type; import com.vaadin.terminal.gwt.client.metadata.TypeData; import com.vaadin.terminal.gwt.client.ui.AbstractComponentConnector; +import com.vaadin.terminal.gwt.client.ui.AbstractConnector; import com.vaadin.terminal.gwt.client.ui.VContextMenu; import com.vaadin.terminal.gwt.client.ui.UI.UIConnector; import com.vaadin.terminal.gwt.client.ui.dd.VDragAndDropManager; @@ -1130,13 +1132,14 @@ public class ApplicationConnection { int startProcessing = updateDuration.elapsedMillis(); // Ensure that all connectors that we are about to update exist - createConnectorsIfNeeded(json); + Set<ServerConnector> createdConnectors = createConnectorsIfNeeded(json); updateDuration.logDuration(" * Creating connectors completed", 10); // Update states, do not fire events - Collection<StateChangeEvent> pendingStateChangeEvents = updateConnectorState(json); + Collection<StateChangeEvent> pendingStateChangeEvents = updateConnectorState( + json, createdConnectors); updateDuration.logDuration( " * Update of connector states completed", 10); @@ -1280,17 +1283,9 @@ public class ApplicationConnection { ServerConnector connector = sce.getConnector(); if (connector instanceof ComponentConnector) { ComponentConnector component = (ComponentConnector) connector; - Type type = TypeData.getType(component.getClass()); - Type stateType; - try { - stateType = type.getMethod("getState") - .getReturnType(); - } catch (NoDataException e) { - throw new RuntimeException( - "Can not find the state type for " - + type.getSignature(), e); - } + Type stateType = AbstractConnector + .getStateType(component); Set<String> changedProperties = sce .getChangedProperties(); @@ -1385,13 +1380,15 @@ public class ApplicationConnection { VConsole.log("* Unregistered " + unregistered + " connectors"); } - private void createConnectorsIfNeeded(ValueMap json) { + private Set<ServerConnector> createConnectorsIfNeeded(ValueMap json) { VConsole.log(" * Creating connectors (if needed)"); if (!json.containsKey("types")) { - return; + return Collections.emptySet(); } + Set<ServerConnector> createdConnectors = new HashSet<ServerConnector>(); + ValueMap types = json.getValueMap("types"); JsArrayString keyArray = types.getKeyArray(); for (int i = 0; i < keyArray.length(); i++) { @@ -1411,7 +1408,8 @@ public class ApplicationConnection { // Connector does not exist so we must create it if (connectorClass != UIConnector.class) { // create, initialize and register the paintable - getConnector(connectorId, connectorType); + connector = getConnector(connectorId, connectorType); + createdConnectors.add(connector); } else { // First UIConnector update. Before this the // UIConnector has been created but not @@ -1421,11 +1419,13 @@ public class ApplicationConnection { uIConnector); uIConnector.doInit(connectorId, ApplicationConnection.this); + createdConnectors.add(uIConnector); } } catch (final Throwable e) { VConsole.error(e); } } + return createdConnectors; } private void updateVaadin6StyleConnectors(ValueMap json) { @@ -1480,12 +1480,15 @@ public class ApplicationConnection { } private Collection<StateChangeEvent> updateConnectorState( - ValueMap json) { + ValueMap json, Set<ServerConnector> newConnectors) { ArrayList<StateChangeEvent> events = new ArrayList<StateChangeEvent>(); VConsole.log(" * Updating connector states"); if (!json.containsKey("state")) { return events; } + HashSet<ServerConnector> remainingNewConnectors = new HashSet<ServerConnector>( + newConnectors); + // set states for all paintables mentioned in "state" ValueMap states = json.getValueMap("state"); JsArrayString keyArray = states.getKeyArray(); @@ -1514,6 +1517,16 @@ public class ApplicationConnection { Set<String> changedProperties = new HashSet<String>(); addJsonFields(stateJson, changedProperties, ""); + if (newConnectors.contains(connector)) { + remainingNewConnectors.remove(connector); + // Fire events for properties using the default + // value for newly created connectors + addAllStateFields( + AbstractConnector + .getStateType(connector), + changedProperties, ""); + } + StateChangeEvent event = new StateChangeEvent( connector, changedProperties); @@ -1524,10 +1537,59 @@ public class ApplicationConnection { } } + // Fire events for properties using the default value for newly + // created connectors even if there were no state changes + for (ServerConnector connector : remainingNewConnectors) { + Set<String> changedProperties = new HashSet<String>(); + addAllStateFields( + AbstractConnector.getStateType(connector), + changedProperties, ""); + + StateChangeEvent event = new StateChangeEvent(connector, + changedProperties); + + events.add(event); + + } + return events; } /** + * Recursively adds the names of all properties in the provided + * state type. + * + * @param type + * the type to process + * @param foundProperties + * a set of all currently added properties + * @param context + * the base name of the current object + */ + private void addAllStateFields(Type type, + Set<String> foundProperties, String context) { + try { + Collection<Property> properties = type.getProperties(); + for (Property property : properties) { + String propertyName = context + property.getName(); + foundProperties.add(propertyName); + + Type propertyType = property.getType(); + if (propertyType.hasProperties()) { + addAllStateFields(propertyType, foundProperties, + propertyName + "."); + } + } + } catch (NoDataException e) { + throw new IllegalStateException( + "No property info for " + + type + + ". Did you remember to compile the right widgetset?", + e); + } + } + + /** * Recursively adds the names of all fields in all objects in the * provided json object. * diff --git a/client/src/com/vaadin/terminal/gwt/client/metadata/Type.java b/client/src/com/vaadin/terminal/gwt/client/metadata/Type.java index d869cc2599..d019ff27e0 100644 --- a/client/src/com/vaadin/terminal/gwt/client/metadata/Type.java +++ b/client/src/com/vaadin/terminal/gwt/client/metadata/Type.java @@ -94,4 +94,8 @@ public class Type { return TypeDataStore.findSerializer(this); } + public boolean hasProperties() { + return TypeDataStore.hasProperties(this); + } + } diff --git a/client/src/com/vaadin/terminal/gwt/client/metadata/TypeDataStore.java b/client/src/com/vaadin/terminal/gwt/client/metadata/TypeDataStore.java index 9c19410c88..0fc8f3b3bf 100644 --- a/client/src/com/vaadin/terminal/gwt/client/metadata/TypeDataStore.java +++ b/client/src/com/vaadin/terminal/gwt/client/metadata/TypeDataStore.java @@ -223,4 +223,8 @@ public class TypeDataStore { } return (JSONSerializer<?>) factoryCreator.invoke(null); } + + public static boolean hasProperties(Type type) { + return get().properties.containsKey(type); + } } diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/AbstractConnector.java b/client/src/com/vaadin/terminal/gwt/client/ui/AbstractConnector.java index b861ade0bf..3a50f0a91e 100644 --- a/client/src/com/vaadin/terminal/gwt/client/ui/AbstractConnector.java +++ b/client/src/com/vaadin/terminal/gwt/client/ui/AbstractConnector.java @@ -268,10 +268,8 @@ public abstract class AbstractConnector implements ServerConnector, * @return A new state object */ protected SharedState createState() { - Type connectorType = TypeData.getType(getClass()); try { - Type stateType = connectorType.getMethod("getState") - .getReturnType(); + Type stateType = getStateType(this); Object stateInstance = stateType.createInstance(); return (SharedState) stateInstance; } catch (NoDataException e) { @@ -284,6 +282,19 @@ public abstract class AbstractConnector implements ServerConnector, } + public static Type getStateType(ServerConnector connector) { + try { + return TypeData.getType(connector.getClass()).getMethod("getState") + .getReturnType(); + } catch (NoDataException e) { + throw new IllegalStateException( + "There is no information about the state for " + + Util.getSimpleName(connector) + + ". Did you remember to compile the right widgetset?", + e); + } + } + @Override public ServerConnector getParent() { return parent; |