瀏覽代碼

Don't generate a set of changed property names (#10954)

Change-Id: I4417fe43e41c84b8223debe59f5ff663bbf5f5de
tags/7.0.2
Leif Åstrand 11 年之前
父節點
當前提交
1b23c7c608

+ 5
- 91
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

+ 174
- 7
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 + ".");
}
}
}
}

Loading…
取消
儲存