]> source.dussan.org Git - vaadin-framework.git/commitdiff
#8602 Added support for Map<Connector,?>
authorArtur Signell <artur@vaadin.com>
Wed, 4 Apr 2012 15:04:52 +0000 (18:04 +0300)
committerArtur Signell <artur@vaadin.com>
Wed, 4 Apr 2012 21:09:40 +0000 (00:09 +0300)
src/com/vaadin/terminal/gwt/client/communication/JsonDecoder.java
src/com/vaadin/terminal/gwt/client/communication/JsonEncoder.java
src/com/vaadin/terminal/gwt/client/ui/CssLayoutConnector.java
src/com/vaadin/terminal/gwt/server/JsonCodec.java
src/com/vaadin/ui/CssLayout.java

index 86a64cb47cfea3cfd64a2a2fe52504e539ec283b..2b58c13f3ec4f510132e29eef3c3ee963bccf044 100644 (file)
@@ -17,6 +17,7 @@ import com.google.gwt.json.client.JSONArray;
 import com.google.gwt.json.client.JSONObject;
 import com.google.gwt.json.client.JSONString;
 import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.Connector;
 import com.vaadin.terminal.gwt.client.ConnectorMap;
 import com.vaadin.terminal.gwt.client.ServerConnector;
 
@@ -63,6 +64,8 @@ public class JsonDecoder {
             val = decodeArray((JSONArray) value, idMapper, connection);
         } else if (JsonEncoder.VTYPE_MAP.equals(variableType)) {
             val = decodeMap((JSONObject) value, idMapper, connection);
+        } else if (JsonEncoder.VTYPE_MAP_CONNECTOR.equals(variableType)) {
+            val = decodeConnectorMap((JSONObject) value, idMapper, connection);
         } else if (JsonEncoder.VTYPE_LIST.equals(variableType)) {
             val = decodeList((JSONArray) value, idMapper, connection);
         } else if (JsonEncoder.VTYPE_SET.equals(variableType)) {
@@ -114,6 +117,21 @@ public class JsonDecoder {
         return map;
     }
 
+    private static Map<Connector, Object> decodeConnectorMap(
+            JSONObject jsonMap, ConnectorMap idMapper,
+            ApplicationConnection connection) {
+        HashMap<Connector, Object> map = new HashMap<Connector, Object>();
+        Iterator<String> it = jsonMap.keySet().iterator();
+        while (it.hasNext()) {
+            String connectorId = it.next();
+            Connector connector = idMapper.getConnector(connectorId);
+            map.put(connector,
+                    decodeValue((JSONArray) jsonMap.get(connectorId), idMapper,
+                            connection));
+        }
+        return map;
+    }
+
     private static String[] decodeStringArray(JSONArray jsonArray) {
         int size = jsonArray.size();
         List<String> tokens = new ArrayList<String>(size);
index 121574379081918f4cc888cc52a25cc8d92208f7..294626e71acbe6e7ad2ec934bdf229fef565bdf7 100644 (file)
@@ -42,6 +42,10 @@ public class JsonEncoder {
     public static final String VTYPE_ARRAY = "a";
     public static final String VTYPE_STRINGARRAY = "S";
     public static final String VTYPE_MAP = "m";
+    // Hack to support Map<Connector,?>. Should be replaced by generic support
+    // for any object as key (#8602)
+    @Deprecated
+    public static final String VTYPE_MAP_CONNECTOR = "M";
     public static final String VTYPE_LIST = "L";
     public static final String VTYPE_SET = "q";
     public static final String VTYPE_NULL = "n";
@@ -77,14 +81,26 @@ public class JsonEncoder {
         } else if (value instanceof Object[]) {
             return encodeObjectArray((Object[]) value, connectorMap, connection);
         } else if (value instanceof Map) {
-            Map<String, Object> map = (Map<String, Object>) value;
+            Map<Object, Object> map = (Map<Object, Object>) value;
             JSONObject jsonMap = new JSONObject();
-            for (String mapKey : map.keySet()) {
-                // TODO handle object graph loops?
+            String type = VTYPE_MAP;
+            for (Object mapKey : map.keySet()) {
                 Object mapValue = map.get(mapKey);
-                jsonMap.put(mapKey, encode(mapValue, connectorMap, connection));
+                if (mapKey instanceof Connector) {
+                    mapKey = ((Connector) mapKey).getConnectorId();
+                    type = VTYPE_MAP_CONNECTOR;
+                }
+
+                if (!(mapKey instanceof String)) {
+                    throw new RuntimeException(
+                            "Only Map<String,?> and Map<Connector,?> is currently supported."
+                                    + " Failed map used "
+                                    + mapKey.getClass().getName() + " as keys");
+                }
+                jsonMap.put((String) mapKey,
+                        encode(mapValue, connectorMap, connection));
             }
-            return combineTypeAndValue(VTYPE_MAP, jsonMap);
+            return combineTypeAndValue(type, jsonMap);
         } else if (value instanceof Connector) {
             Connector connector = (Connector) value;
             return combineTypeAndValue(VTYPE_CONNECTOR, new JSONString(
index 7d375501dbff981aec0ec04edfef8cd302eea042..554cec0d36dec58728d8f3527a012982ac8cdfda 100644 (file)
@@ -12,6 +12,7 @@ import com.google.gwt.user.client.Element;
 import com.google.gwt.user.client.ui.Widget;
 import com.vaadin.terminal.gwt.client.BrowserInfo;
 import com.vaadin.terminal.gwt.client.ComponentConnector;
+import com.vaadin.terminal.gwt.client.Connector;
 import com.vaadin.terminal.gwt.client.ConnectorHierarchyChangeEvent;
 import com.vaadin.terminal.gwt.client.Util;
 import com.vaadin.terminal.gwt.client.VCaption;
@@ -25,13 +26,13 @@ import com.vaadin.ui.CssLayout;
 public class CssLayoutConnector extends AbstractLayoutConnector {
 
     public static class CssLayoutState extends AbstractLayoutState {
-        private Map<String, String> childCss = new HashMap<String, String>();
+        private Map<Connector, String> childCss = new HashMap<Connector, String>();
 
-        public Map<String, String> getChildCss() {
+        public Map<Connector, String> getChildCss() {
             return childCss;
         }
 
-        public void setChildCss(Map<String, String> childCss) {
+        public void setChildCss(Map<Connector, String> childCss) {
             this.childCss = childCss;
         }
 
@@ -79,10 +80,10 @@ public class CssLayoutConnector extends AbstractLayoutConnector {
                 new VMarginInfo(getState().getMarginsBitmask()));
 
         for (ComponentConnector child : getChildren()) {
-            if (!getState().getChildCss().containsKey(child.getConnectorId())) {
+            if (!getState().getChildCss().containsKey(child)) {
                 continue;
             }
-            String css = getState().getChildCss().get(child.getConnectorId());
+            String css = getState().getChildCss().get(child);
             Style style = child.getWidget().getElement().getStyle();
             // should we remove styles also? How can we know what we have added
             // as it is added directly to the child component?
index 21a189a435a5d9c8ec919cef02b41f4360057c90..15be2673bac8c2d8b632ce01eba371a922375826 100644 (file)
@@ -90,6 +90,8 @@ public class JsonCodec implements Serializable {
             val = decodeList((JSONArray) value, application);
         } else if (JsonEncoder.VTYPE_SET.equals(variableType)) {
             val = decodeSet((JSONArray) value, application);
+        } else if (JsonEncoder.VTYPE_MAP_CONNECTOR.equals(variableType)) {
+            val = decodeConnectorMap((JSONObject) value, application);
         } else if (JsonEncoder.VTYPE_MAP.equals(variableType)) {
             val = decodeMap((JSONObject) value, application);
         } else if (JsonEncoder.VTYPE_STRINGARRAY.equals(variableType)) {
@@ -135,6 +137,19 @@ public class JsonCodec implements Serializable {
         return map;
     }
 
+    private static Object decodeConnectorMap(JSONObject jsonMap,
+            Application application) throws JSONException {
+        HashMap<Connector, Object> map = new HashMap<Connector, Object>();
+        Iterator<String> it = jsonMap.keys();
+        while (it.hasNext()) {
+            String connectorId = it.next();
+            Connector connector = application.getConnector(connectorId);
+            map.put(connector,
+                    decode(jsonMap.getJSONArray(connectorId), application));
+        }
+        return map;
+    }
+
     private static String[] decodeStringArray(JSONArray jsonArray)
             throws JSONException {
         int length = jsonArray.length();
@@ -227,7 +242,14 @@ public class JsonCodec implements Serializable {
         } else if (value instanceof Map) {
             Map<Object, Object> map = (Map<Object, Object>) value;
             JSONObject jsonMap = encodeMapContents(map, application);
-            return combineTypeAndValue(JsonEncoder.VTYPE_MAP, jsonMap);
+            // Hack to support Connector as map key. Should be fixed by #
+            if (!map.isEmpty()
+                    && map.keySet().iterator().next() instanceof Connector) {
+                return combineTypeAndValue(JsonEncoder.VTYPE_MAP_CONNECTOR,
+                        jsonMap);
+            } else {
+                return combineTypeAndValue(JsonEncoder.VTYPE_MAP, jsonMap);
+            }
         } else if (value instanceof Connector) {
             Connector connector = (Connector) value;
             return combineTypeAndValue(JsonEncoder.VTYPE_CONNECTOR,
@@ -328,12 +350,16 @@ public class JsonCodec implements Serializable {
             Application application) throws JSONException {
         JSONObject jsonMap = new JSONObject();
         for (Object mapKey : map.keySet()) {
+            Object mapValue = map.get(mapKey);
+
+            if (mapKey instanceof ClientConnector) {
+                mapKey = ((ClientConnector) mapKey).getConnectorId();
+            }
             if (!(mapKey instanceof String)) {
                 throw new JSONException(
-                        "Only maps with String keys are currently supported (#8602)");
+                        "Only maps with String/Connector keys are currently supported (#8602)");
             }
 
-            Object mapValue = map.get(mapKey);
             jsonMap.put((String) mapKey, encode(mapValue, application));
         }
         return jsonMap;
index 27dc9b830669bbc385c6e26120638ee67a8686fe..5c14d55d118e95c69e8a61a9def46df8c4c61a02 100644 (file)
@@ -11,7 +11,6 @@ import com.vaadin.event.LayoutEvents.LayoutClickListener;
 import com.vaadin.event.LayoutEvents.LayoutClickNotifier;
 import com.vaadin.terminal.gwt.client.Connector;
 import com.vaadin.terminal.gwt.client.MouseEventDetails;
-import com.vaadin.terminal.gwt.client.ui.CssLayoutConnector;
 import com.vaadin.terminal.gwt.client.ui.CssLayoutConnector.CssLayoutServerRPC;
 import com.vaadin.terminal.gwt.client.ui.CssLayoutConnector.CssLayoutState;
 import com.vaadin.terminal.gwt.client.ui.LayoutClickEventHandler;
@@ -189,8 +188,7 @@ public class CssLayout extends AbstractLayout implements LayoutClickNotifier {
         for (Component child : this) {
             String componentCssString = getCss(child);
             if (componentCssString != null) {
-                getState().getChildCss().put(child.getConnectorId(),
-                        componentCssString);
+                getState().getChildCss().put(child, componentCssString);
             }
 
         }