From c011e166e102c95a5ad4848bba7833ce18830a6b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Leif=20=C3=85strand?= Date: Tue, 5 Feb 2013 13:06:07 +0200 Subject: [PATCH] Native collections for ApplicationConnection & StateChangeEvent (#10937) Change-Id: I8dbda413f2148f2a28e3867bffe0bc7ea3c8ff93 --- .../vaadin/client/ApplicationConnection.java | 61 +++++++++++------ .../communication/StateChangeEvent.java | 68 +++++++++++++++++-- .../client/ui/AbstractComponentConnector.java | 8 +-- .../vaadin/client/ui/AbstractConnector.java | 18 ++--- .../client/ui/button/ButtonConnector.java | 7 +- .../AbstractColorPickerConnector.java | 11 ++- .../ColorPickerGradientConnector.java | 9 +-- .../colorpicker/ColorPickerGridConnector.java | 17 ++--- 8 files changed, 132 insertions(+), 67 deletions(-) diff --git a/client/src/com/vaadin/client/ApplicationConnection.java b/client/src/com/vaadin/client/ApplicationConnection.java index b2a9541d80..0171d541ea 100644 --- a/client/src/com/vaadin/client/ApplicationConnection.java +++ b/client/src/com/vaadin/client/ApplicationConnection.java @@ -153,6 +153,9 @@ public class ApplicationConnection { // will hold the UIDL security key (for XSS protection) once received private String uidlSecurityKey = "init"; + private static final FastStringMap allStateFieldsCache = FastStringMap + .create(); + private final HashMap resourcesMap = new HashMap(); /** @@ -1605,9 +1608,11 @@ public class ApplicationConnection { Type stateType = AbstractConnector .getStateType(component); - Set changedProperties = sce - .getChangedProperties(); - for (String propertyName : changedProperties) { + FastStringSet changedProperties = sce + .getChangedPropertiesFastSet(); + JsArrayString dump = changedProperties.dump(); + for (int i = 0; i < dump.length(); i++) { + String propertyName = dump.get(i); Property property = stateType .getProperty(propertyName); String method = property @@ -1670,9 +1675,11 @@ public class ApplicationConnection { private void unregisterRemovedConnectors() { int unregistered = 0; - List currentConnectors = new ArrayList( - connectorMap.getConnectors()); - for (ServerConnector c : currentConnectors) { + JsArrayObject currentConnectors = connectorMap + .getConnectorsAsJsArray(); + int size = currentConnectors.size(); + for (int i = 0; i < size; i++) { + ServerConnector c = currentConnectors.get(i); if (c.getParent() != null) { if (!c.getParent().getChildren().contains(c)) { VConsole.error("ERROR: Connector is connected to a parent but the parent does not contain the connector"); @@ -1856,17 +1863,17 @@ public class ApplicationConnection { .getName(), null), stateJson, state, ApplicationConnection.this); - Set changedProperties = new HashSet(); + FastStringSet changedProperties = FastStringSet + .create(); 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, ""); + FastStringSet allStateFields = getAllStateFields(AbstractConnector + .getStateType(connector)); + changedProperties.addAll(allStateFields); } StateChangeEvent event = new StateChangeEvent( @@ -1882,10 +1889,8 @@ 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 changedProperties = new HashSet(); - addAllStateFields( - AbstractConnector.getStateType(connector), - changedProperties, ""); + FastStringSet changedProperties = getAllStateFields(AbstractConnector + .getStateType(connector)); StateChangeEvent event = new StateChangeEvent(connector, changedProperties); @@ -1897,6 +1902,17 @@ public class ApplicationConnection { return events; } + private FastStringSet getAllStateFields(Type type) { + FastStringSet fields; + fields = allStateFieldsCache.get(type.getBaseTypeName()); + if (fields == null) { + fields = FastStringSet.create(); + addAllStateFields(type, fields, ""); + allStateFieldsCache.put(type.getBaseTypeName(), fields); + } + return fields; + } + /** * Recursively adds the names of all properties in the provided * state type. @@ -1909,7 +1925,7 @@ public class ApplicationConnection { * the base name of the current object */ private void addAllStateFields(Type type, - Set foundProperties, String context) { + FastStringSet foundProperties, String context) { try { JsArrayObject properties = type .getPropertiesAsArray(); @@ -1945,7 +1961,7 @@ public class ApplicationConnection { * @param context * the base name of the current object */ - private void addJsonFields(JSONObject json, Set fields, + private void addJsonFields(JSONObject json, FastStringSet fields, String context) { for (String key : json.keySet()) { String fieldName = context + key; @@ -1978,7 +1994,7 @@ public class ApplicationConnection { return result; } - HashSet maybeDetached = new HashSet(); + FastStringSet maybeDetached = FastStringSet.create(); ValueMap hierarchies = json.getValueMap("hierarchy"); JsArrayString hierarchyKeys = hierarchies.getKeyArray(); @@ -2022,7 +2038,7 @@ public class ApplicationConnection { result.parentChanged.add(childConnector); // Not detached even if previously removed from // parent - maybeDetached.remove(childConnector); + maybeDetached.remove(childConnectorId); } } @@ -2078,7 +2094,7 @@ public class ApplicationConnection { * cleared if it is later on added to some other * parent. */ - maybeDetached.add(oldChild); + maybeDetached.add(oldChild.getConnectorId()); } } } catch (final Throwable e) { @@ -2090,7 +2106,10 @@ public class ApplicationConnection { * Connector is in maybeDetached at this point if it has been * removed from its parent but not added to any other parent */ - for (ServerConnector removed : maybeDetached) { + JsArrayString maybeDetachedArray = maybeDetached.dump(); + for (int i = 0; i < maybeDetachedArray.length(); i++) { + ServerConnector removed = connectorMap + .getConnector(maybeDetachedArray.get(i)); recursivelyDetach(removed, result.events); } diff --git a/client/src/com/vaadin/client/communication/StateChangeEvent.java b/client/src/com/vaadin/client/communication/StateChangeEvent.java index 8e72485a0c..35187b03d4 100644 --- a/client/src/com/vaadin/client/communication/StateChangeEvent.java +++ b/client/src/com/vaadin/client/communication/StateChangeEvent.java @@ -16,10 +16,11 @@ package com.vaadin.client.communication; import java.io.Serializable; -import java.util.Collections; +import java.util.HashSet; import java.util.Set; import com.google.gwt.event.shared.EventHandler; +import com.vaadin.client.FastStringSet; import com.vaadin.client.ServerConnector; import com.vaadin.client.communication.StateChangeEvent.StateChangeHandler; @@ -30,13 +31,41 @@ public class StateChangeEvent extends */ public static final Type TYPE = new Type(); - private Set changedProperties; + private final FastStringSet changedProperties; + + /** + * Used to cache a Set representation of the changedProperties if one is + * needed. + */ + private Set changedPropertiesSet; @Override public Type getAssociatedType() { return TYPE; } + /** + * Creates a new state change event. + * + * @param connector + * the event whose state has changed + * @param changedPropertiesSet + * a set of names of the changed properties + * @deprecated As of 7.0.1, use + * {@link #StateChangeEvent(ServerConnector, FastStringSet)} + * instead for improved performance. + */ + @Deprecated + public StateChangeEvent(ServerConnector connector, + Set changedPropertiesSet) { + setConnector(connector); + this.changedPropertiesSet = changedPropertiesSet; + changedProperties = FastStringSet.create(); + for (String property : changedPropertiesSet) { + changedProperties.add(property); + } + } + /** * Creates a new state change event. * @@ -46,7 +75,7 @@ public class StateChangeEvent extends * a set of names of the changed properties */ public StateChangeEvent(ServerConnector connector, - Set changedProperties) { + FastStringSet changedProperties) { setConnector(connector); this.changedProperties = changedProperties; } @@ -78,8 +107,39 @@ public class StateChangeEvent extends * Gets the properties that have changed. * * @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 public Set getChangedProperties() { - return Collections.unmodifiableSet(changedProperties); + if (changedPropertiesSet == null) { + changedPropertiesSet = new HashSet(); + changedProperties.addAllTo(changedPropertiesSet); + } + return changedPropertiesSet; + } + + /** + * Gets the properties that have changed. + * + * @return a set of names of the changed properties + * + */ + public FastStringSet getChangedPropertiesFastSet() { + return changedProperties; + } + + /** + * Checks whether the give property has changed. + * + * @param property + * the name of the property to check + * @return true if the property has changed, else + * false> + */ + public boolean hasPropertyChanged(String property) { + return changedProperties.contains(property); } } diff --git a/client/src/com/vaadin/client/ui/AbstractComponentConnector.java b/client/src/com/vaadin/client/ui/AbstractComponentConnector.java index c22bd0905c..e35e3eafcf 100644 --- a/client/src/com/vaadin/client/ui/AbstractComponentConnector.java +++ b/client/src/com/vaadin/client/ui/AbstractComponentConnector.java @@ -17,7 +17,6 @@ package com.vaadin.client.ui; import java.util.ArrayList; import java.util.List; -import java.util.Set; import com.google.gwt.core.client.JsArrayString; import com.google.gwt.dom.client.Element; @@ -26,7 +25,6 @@ import com.google.gwt.user.client.ui.HasEnabled; import com.google.gwt.user.client.ui.Widget; import com.vaadin.client.ApplicationConnection; import com.vaadin.client.ComponentConnector; -import com.vaadin.client.ConnectorMap; import com.vaadin.client.HasComponentsConnector; import com.vaadin.client.LayoutManager; import com.vaadin.client.ServerConnector; @@ -125,10 +123,7 @@ public abstract class AbstractComponentConnector extends AbstractConnector @Override public void onStateChanged(StateChangeEvent stateChangeEvent) { - ConnectorMap paintableMap = ConnectorMap.get(getConnection()); - - Set changedProperties = stateChangeEvent.getChangedProperties(); - if (changedProperties.contains("id")) { + if (stateChangeEvent.hasPropertyChanged("id")) { if (getState().id != null) { getWidget().getElement().setId(getState().id); } else if (!initialStateEvent) { @@ -425,6 +420,7 @@ public abstract class AbstractComponentConnector extends AbstractConnector * * @see com.vaadin.client.ComponentConnector#flush() */ + @Override public void flush() { // No generic implementation. Override if needed } diff --git a/client/src/com/vaadin/client/ui/AbstractConnector.java b/client/src/com/vaadin/client/ui/AbstractConnector.java index 4c55f999b6..2791cfddd9 100644 --- a/client/src/com/vaadin/client/ui/AbstractConnector.java +++ b/client/src/com/vaadin/client/ui/AbstractConnector.java @@ -23,10 +23,12 @@ import java.util.List; import java.util.Map; import java.util.Set; +import com.google.gwt.core.client.JsArrayString; import com.google.gwt.event.shared.GwtEvent; import com.google.gwt.event.shared.HandlerManager; import com.google.web.bindery.event.shared.HandlerRegistration; import com.vaadin.client.ApplicationConnection; +import com.vaadin.client.FastStringMap; import com.vaadin.client.ServerConnector; import com.vaadin.client.Util; import com.vaadin.client.VConsole; @@ -55,7 +57,7 @@ public abstract class AbstractConnector implements ServerConnector, private String id; private HandlerManager handlerManager; - private Map statePropertyHandlerManagers; + private FastStringMap statePropertyHandlerManagers; private Map> rpcImplementations; private final boolean debugLogging = false; @@ -202,12 +204,12 @@ public abstract class AbstractConnector implements ServerConnector, } if (statePropertyHandlerManagers != null && event instanceof StateChangeEvent) { - for (String property : ((StateChangeEvent) event) - .getChangedProperties()) { - HandlerManager manager = statePropertyHandlerManagers - .get(property); - if (manager != null) { - manager.fireEvent(event); + StateChangeEvent stateChangeEvent = (StateChangeEvent) event; + JsArrayString keys = statePropertyHandlerManagers.getKeys(); + for (int i = 0; i < keys.length(); i++) { + String property = keys.get(i); + if (stateChangeEvent.hasPropertyChanged(property)) { + statePropertyHandlerManagers.get(property).fireEvent(event); } } } @@ -248,7 +250,7 @@ public abstract class AbstractConnector implements ServerConnector, private HandlerManager ensureHandlerManager(String propertyName) { if (statePropertyHandlerManagers == null) { - statePropertyHandlerManagers = new HashMap(); + statePropertyHandlerManagers = FastStringMap.create(); } HandlerManager manager = statePropertyHandlerManagers.get(propertyName); if (manager == null) { diff --git a/client/src/com/vaadin/client/ui/button/ButtonConnector.java b/client/src/com/vaadin/client/ui/button/ButtonConnector.java index 224da40b5e..0439cd4fdc 100644 --- a/client/src/com/vaadin/client/ui/button/ButtonConnector.java +++ b/client/src/com/vaadin/client/ui/button/ButtonConnector.java @@ -16,8 +16,6 @@ package com.vaadin.client.ui.button; -import java.util.Set; - import com.google.gwt.event.dom.client.BlurEvent; import com.google.gwt.event.dom.client.BlurHandler; import com.google.gwt.event.dom.client.ClickEvent; @@ -109,9 +107,8 @@ public class ButtonConnector extends AbstractComponentConnector implements blurHandlerRegistration = EventHelper.updateBlurHandler(this, blurHandlerRegistration); - Set changedProperties = stateChangeEvent.getChangedProperties(); - if (changedProperties.contains("caption") - || changedProperties.contains("htmlContentAllowed")) { + if (stateChangeEvent.hasPropertyChanged("caption") + || stateChangeEvent.hasPropertyChanged("htmlContentAllowed")) { // Set text if (getState().htmlContentAllowed) { getWidget().setHtml(getState().caption); diff --git a/client/src/com/vaadin/client/ui/colorpicker/AbstractColorPickerConnector.java b/client/src/com/vaadin/client/ui/colorpicker/AbstractColorPickerConnector.java index 777a7eba8f..ba0575d8fe 100644 --- a/client/src/com/vaadin/client/ui/colorpicker/AbstractColorPickerConnector.java +++ b/client/src/com/vaadin/client/ui/colorpicker/AbstractColorPickerConnector.java @@ -15,8 +15,6 @@ */ package com.vaadin.client.ui.colorpicker; -import java.util.Set; - import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.HasClickHandlers; import com.vaadin.client.communication.StateChangeEvent; @@ -46,8 +44,7 @@ public abstract class AbstractColorPickerConnector extends public void onStateChanged(StateChangeEvent stateChangeEvent) { // NOTE: this method is called after @DelegateToWidget super.onStateChanged(stateChangeEvent); - Set changedProperties = stateChangeEvent.getChangedProperties(); - if (changedProperties.contains("color")) { + if (stateChangeEvent.hasPropertyChanged("color")) { refreshColor(); if (getState().showDefaultCaption @@ -57,9 +54,9 @@ public abstract class AbstractColorPickerConnector extends setCaption(getState().color); } } - if (changedProperties.contains("caption") - || changedProperties.contains("htmlContentAllowed") - || changedProperties.contains("showDefaultCaption")) { + if (stateChangeEvent.hasPropertyChanged("caption") + || stateChangeEvent.hasPropertyChanged("htmlContentAllowed") + || stateChangeEvent.hasPropertyChanged("showDefaultCaption")) { setCaption(getCaption()); } diff --git a/client/src/com/vaadin/client/ui/colorpicker/ColorPickerGradientConnector.java b/client/src/com/vaadin/client/ui/colorpicker/ColorPickerGradientConnector.java index e381eb0b70..b28831b860 100644 --- a/client/src/com/vaadin/client/ui/colorpicker/ColorPickerGradientConnector.java +++ b/client/src/com/vaadin/client/ui/colorpicker/ColorPickerGradientConnector.java @@ -15,8 +15,6 @@ */ package com.vaadin.client.ui.colorpicker; -import java.util.Set; - import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.MouseUpEvent; import com.google.gwt.event.dom.client.MouseUpHandler; @@ -68,13 +66,12 @@ public class ColorPickerGradientConnector extends AbstractComponentConnector @Override public void onStateChanged(StateChangeEvent stateChangeEvent) { super.onStateChanged(stateChangeEvent); - Set changedProperties = stateChangeEvent.getChangedProperties(); - if (changedProperties.contains("cursorX") - || changedProperties.contains("cursorY")) { + if (stateChangeEvent.hasPropertyChanged("cursorX") + || stateChangeEvent.hasPropertyChanged("cursorY")) { getWidget().setCursor(getState().cursorX, getState().cursorY); } - if (changedProperties.contains("bgColor")) { + if (stateChangeEvent.hasPropertyChanged("bgColor")) { getWidget().setBGColor(getState().bgColor); } } diff --git a/client/src/com/vaadin/client/ui/colorpicker/ColorPickerGridConnector.java b/client/src/com/vaadin/client/ui/colorpicker/ColorPickerGridConnector.java index 53abc78b4b..730981d2dd 100644 --- a/client/src/com/vaadin/client/ui/colorpicker/ColorPickerGridConnector.java +++ b/client/src/com/vaadin/client/ui/colorpicker/ColorPickerGridConnector.java @@ -15,8 +15,6 @@ */ package com.vaadin.client.ui.colorpicker; -import java.util.Set; - import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; @@ -68,17 +66,16 @@ public class ColorPickerGridConnector extends AbstractComponentConnector @Override public void onStateChanged(StateChangeEvent stateChangeEvent) { super.onStateChanged(stateChangeEvent); - Set changedProperties = stateChangeEvent.getChangedProperties(); - if (changedProperties.contains("rowCount") - || changedProperties.contains("columnCount") - || changedProperties.contains("updateGrid")) { + if (stateChangeEvent.hasPropertyChanged("rowCount") + || stateChangeEvent.hasPropertyChanged("columnCount") + || stateChangeEvent.hasPropertyChanged("updateGrid")) { getWidget().updateGrid(getState().rowCount, getState().columnCount); } - if (changedProperties.contains("changedX") - || changedProperties.contains("changedY") - || changedProperties.contains("changedColor") - || changedProperties.contains("updateColor")) { + if (stateChangeEvent.hasPropertyChanged("changedX") + || stateChangeEvent.hasPropertyChanged("changedY") + || stateChangeEvent.hasPropertyChanged("changedColor") + || stateChangeEvent.hasPropertyChanged("updateColor")) { getWidget().updateColor(getState().changedColor, getState().changedX, getState().changedY); -- 2.39.5