diff options
author | Leif Åstrand <leif@vaadin.com> | 2013-02-20 16:22:20 +0200 |
---|---|---|
committer | Vaadin Code Review <review@vaadin.com> | 2013-02-25 16:27:14 +0000 |
commit | 1b23c7c608c36dc97b32113eb212cd2629525f9e (patch) | |
tree | 9ac0e3a7d4082475cf384cfc0cb16c58fffde284 /client | |
parent | b89719f3856be6bad0c04c40db46965083db8ef4 (diff) | |
download | vaadin-framework-1b23c7c608c36dc97b32113eb212cd2629525f9e.tar.gz vaadin-framework-1b23c7c608c36dc97b32113eb212cd2629525f9e.zip |
Don't generate a set of changed property names (#10954)
Change-Id: I4417fe43e41c84b8223debe59f5ff663bbf5f5de
Diffstat (limited to 'client')
-rw-r--r-- | client/src/com/vaadin/client/ApplicationConnection.java | 96 | ||||
-rw-r--r-- | client/src/com/vaadin/client/communication/StateChangeEvent.java | 181 |
2 files changed, 179 insertions, 98 deletions
diff --git a/client/src/com/vaadin/client/ApplicationConnection.java b/client/src/com/vaadin/client/ApplicationConnection.java index e669b3ae96..ab3cec2be1 100644 --- a/client/src/com/vaadin/client/ApplicationConnection.java +++ b/client/src/com/vaadin/client/ApplicationConnection.java @@ -153,9 +153,6 @@ public class ApplicationConnection { // will hold the UIDL security key (for XSS protection) once received private String uidlSecurityKey = "init"; - private static final FastStringMap<FastStringSet> allStateFieldsCache = FastStringMap - .create(); - private final HashMap<String, String> resourcesMap = new HashMap<String, String>(); /** @@ -1932,22 +1929,15 @@ public class ApplicationConnection { } Profiler.enter("updateConnectorState create event"); - FastStringSet changedProperties = FastStringSet - .create(); - addJsonFields(stateJson, changedProperties, ""); - if (newConnectors.contains(connector)) { + boolean isNewConnector = remainingNewConnectors + .contains(connector); + if (isNewConnector) { remainingNewConnectors.remove(connector); - // Fire events for properties using the default - // value for newly created connectors - FastStringSet allStateFields = getAllStateFields(AbstractConnector - .getStateType(connector)); - changedProperties.addAll(allStateFields); } StateChangeEvent event = new StateChangeEvent( - connector, changedProperties); - + connector, stateJson, isNewConnector); events.add(event); Profiler.leave("updateConnectorState create event"); @@ -1962,11 +1952,9 @@ 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) { - FastStringSet changedProperties = getAllStateFields(AbstractConnector - .getStateType(connector)); StateChangeEvent event = new StateChangeEvent(connector, - changedProperties); + new JSONObject(), true); events.add(event); @@ -1978,80 +1966,6 @@ public class ApplicationConnection { return events; } - private FastStringSet getAllStateFields(Type type) { - FastStringSet fields; - fields = allStateFieldsCache.get(type.getBaseTypeName()); - if (fields == null) { - Profiler.enter("getAllStateFields create"); - fields = FastStringSet.create(); - addAllStateFields(type, fields, ""); - allStateFieldsCache.put(type.getBaseTypeName(), fields); - Profiler.leave("getAllStateFields create"); - } - return fields; - } - - /** - * 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, - FastStringSet foundProperties, String context) { - try { - JsArrayObject<Property> properties = type - .getPropertiesAsArray(); - int size = properties.size(); - for (int i = 0; i < size; i++) { - Property property = properties.get(i); - 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. - * - * @param json - * the json object to process - * @param fields - * a set of all currently added fields - * @param context - * the base name of the current object - */ - private void addJsonFields(JSONObject json, FastStringSet fields, - String context) { - for (String key : json.keySet()) { - String fieldName = context + key; - fields.add(fieldName); - - JSONObject object = json.get(key).isObject(); - if (object != null) { - addJsonFields(object, fields, fieldName + "."); - } - } - } - /** * Updates the connector hierarchy and returns a list of events that * should be fired after update of the hierarchy and the state is diff --git a/client/src/com/vaadin/client/communication/StateChangeEvent.java b/client/src/com/vaadin/client/communication/StateChangeEvent.java index 35187b03d4..205c69fec8 100644 --- a/client/src/com/vaadin/client/communication/StateChangeEvent.java +++ b/client/src/com/vaadin/client/communication/StateChangeEvent.java @@ -19,10 +19,17 @@ import java.io.Serializable; import java.util.HashSet; import java.util.Set; +import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.event.shared.EventHandler; +import com.google.gwt.json.client.JSONObject; import com.vaadin.client.FastStringSet; +import com.vaadin.client.JsArrayObject; +import com.vaadin.client.Profiler; import com.vaadin.client.ServerConnector; import com.vaadin.client.communication.StateChangeEvent.StateChangeHandler; +import com.vaadin.client.metadata.NoDataException; +import com.vaadin.client.metadata.Property; +import com.vaadin.client.ui.AbstractConnector; public class StateChangeEvent extends AbstractServerConnectorEvent<StateChangeHandler> { @@ -31,14 +38,24 @@ public class StateChangeEvent extends */ public static final Type<StateChangeHandler> TYPE = new Type<StateChangeHandler>(); - private final FastStringSet changedProperties; + /** + * Used to cache a FastStringSet representation of the properties that have + * changed if one is needed. + */ + @Deprecated + private FastStringSet changedProperties; /** * Used to cache a Set representation of the changedProperties if one is * needed. */ + @Deprecated private Set<String> changedPropertiesSet; + private boolean isNewConnector = false; + + private JSONObject stateJson; + @Override public Type<StateChangeHandler> getAssociatedType() { return TYPE; @@ -52,14 +69,16 @@ public class StateChangeEvent extends * @param changedPropertiesSet * a set of names of the changed properties * @deprecated As of 7.0.1, use - * {@link #StateChangeEvent(ServerConnector, FastStringSet)} + * {@link #StateChangeEvent(ServerConnector, JSONObject, boolean)} * instead for improved performance. */ @Deprecated public StateChangeEvent(ServerConnector connector, Set<String> changedPropertiesSet) { setConnector(connector); + // Keep instance around for caching this.changedPropertiesSet = changedPropertiesSet; + changedProperties = FastStringSet.create(); for (String property : changedPropertiesSet) { changedProperties.add(property); @@ -73,13 +92,35 @@ public class StateChangeEvent extends * the event whose state has changed * @param changedProperties * a set of names of the changed properties + * @deprecated As of 7.0.2, use + * {@link #StateChangeEvent(ServerConnector, JSONObject, boolean)} + * instead for improved performance. */ + @Deprecated public StateChangeEvent(ServerConnector connector, FastStringSet changedProperties) { setConnector(connector); this.changedProperties = changedProperties; } + /** + * /** Creates a new state change event. + * + * @param connector + * the event whose state has changed + * @param stateJson + * the JSON representation of the state change + * @param isNewConnector + * <code>true</code> if the state change is for a new connector, + * otherwise <code>false</code> + */ + public StateChangeEvent(ServerConnector connector, JSONObject stateJson, + boolean isNewConnector) { + setConnector(connector); + this.stateJson = stateJson; + this.isNewConnector = isNewConnector; + } + @Override public void dispatch(StateChangeHandler listener) { listener.onStateChanged(this); @@ -108,15 +149,16 @@ public class StateChangeEvent extends * * @return a set of names of the changed properties * - * @deprecated As of 7.0.1, use {@link #getChangedPropertiesFastSet()} or - * {@link #hasPropertyChanged(String)} instead for improved - * performance. + * @deprecated As of 7.0.1, use {@link #hasPropertyChanged(String)} instead + * for improved performance. */ @Deprecated public Set<String> getChangedProperties() { if (changedPropertiesSet == null) { + Profiler.enter("StateChangeEvent.getChangedProperties populate"); changedPropertiesSet = new HashSet<String>(); - changedProperties.addAllTo(changedPropertiesSet); + getChangedPropertiesFastSet().addAllTo(changedPropertiesSet); + Profiler.leave("StateChangeEvent.getChangedProperties populate"); } return changedPropertiesSet; } @@ -126,8 +168,24 @@ public class StateChangeEvent extends * * @return a set of names of the changed properties * + * @deprecated As of 7.0.1, use {@link #hasPropertyChanged(String)} instead + * for improved performance. */ + @Deprecated public FastStringSet getChangedPropertiesFastSet() { + if (changedProperties == null) { + Profiler.enter("StateChangeEvent.getChangedPropertiesFastSet populate"); + changedProperties = FastStringSet.create(); + + addJsonFields(stateJson, changedProperties, ""); + if (isNewConnector) { + addAllStateFields( + AbstractConnector.getStateType(getConnector()), + changedProperties, ""); + } + + Profiler.leave("StateChangeEvent.getChangedPropertiesFastSet populate"); + } return changedProperties; } @@ -140,6 +198,115 @@ public class StateChangeEvent extends * <code>false></code> */ public boolean hasPropertyChanged(String property) { - return changedProperties.contains(property); + if (isNewConnector) { + // Everything has changed for a new connector + return true; + } else if (stateJson != null) { + // Check whether it's in the json object + return isInJson(property, stateJson.getJavaScriptObject()); + } else { + // Legacy cases + if (changedProperties != null) { + // Check legacy stuff + return changedProperties.contains(property); + } else if (changedPropertiesSet != null) { + // Check legacy stuff + return changedPropertiesSet.contains(property); + } else { + throw new IllegalStateException( + "StateChangeEvent should have either stateJson, changedProperties or changePropertiesSet"); + } + } + } + + /** + * Checks whether the given property name (which might contains dots) is + * defined in some JavaScript object. + * + * @param property + * the name of the property, might include dots to reference + * inner objects + * @param target + * the JavaScript object to check + * @return true if the property is defined + */ + private static native final boolean isInJson(String property, + JavaScriptObject target) + /*-{ + var segments = property.split('.'); + while (typeof target == 'object') { + var currentSegment = segments.shift(); + if (!(nextSegment in target)) { + // Abort if segment is not found + return false; + } else if (segments.length == 0) { + // Done if there are no more segments + return true; + } else { + // Else just go deeper + target = target[nextSegment]; + } + } + // Not defined if we reach something that isn't an object + return false; + }-*/; + + /** + * Recursively adds the names of all properties in the provided state type. + * + * @param type + * the type to process + * @param changedProperties + * a set of all currently added properties + * @param context + * the base name of the current object + */ + @Deprecated + private static void addAllStateFields(com.vaadin.client.metadata.Type type, + FastStringSet changedProperties, String context) { + try { + JsArrayObject<Property> properties = type.getPropertiesAsArray(); + int size = properties.size(); + for (int i = 0; i < size; i++) { + Property property = properties.get(i); + String propertyName = context + property.getName(); + changedProperties.add(propertyName); + + com.vaadin.client.metadata.Type propertyType = property + .getType(); + if (propertyType.hasProperties()) { + addAllStateFields(propertyType, changedProperties, + 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. + * + * @param json + * the json object to process + * @param changedProperties + * a set of all currently added fields + * @param context + * the base name of the current object + */ + @Deprecated + private static void addJsonFields(JSONObject json, + FastStringSet changedProperties, String context) { + for (String key : json.keySet()) { + String fieldName = context + key; + changedProperties.add(fieldName); + + JSONObject object = json.get(key).isObject(); + if (object != null) { + addJsonFields(object, changedProperties, fieldName + "."); + } + } } } |