summaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorLeif Åstrand <leif@vaadin.com>2013-02-20 16:22:20 +0200
committerVaadin Code Review <review@vaadin.com>2013-02-25 16:27:14 +0000
commit1b23c7c608c36dc97b32113eb212cd2629525f9e (patch)
tree9ac0e3a7d4082475cf384cfc0cb16c58fffde284 /client
parentb89719f3856be6bad0c04c40db46965083db8ef4 (diff)
downloadvaadin-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.java96
-rw-r--r--client/src/com/vaadin/client/communication/StateChangeEvent.java181
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 + ".");
+ }
+ }
}
}