ONOS-1479 -- GUI - augmenting topology view for extensibility:
- Cleaning up PropertyPanel methods - overloading values (string, int, long, object)

Change-Id: I84c86a48de8a776b407982687bc02def18eaef61
diff --git a/core/api/src/main/java/org/onosproject/ui/topo/PropertyPanel.java b/core/api/src/main/java/org/onosproject/ui/topo/PropertyPanel.java
index 88dad9a..87b6839 100644
--- a/core/api/src/main/java/org/onosproject/ui/topo/PropertyPanel.java
+++ b/core/api/src/main/java/org/onosproject/ui/topo/PropertyPanel.java
@@ -29,6 +29,8 @@
  */
 public class PropertyPanel {
 
+    private static final DecimalFormat DF0 = new DecimalFormat("#,###");
+
     private String title;
     private String typeId;
     private String id;
@@ -47,17 +49,6 @@
     }
 
     /**
-     * Adds a property to the panel.
-     *
-     * @param p the property
-     * @return self, for chaining
-     */
-    public PropertyPanel add(Prop p) {
-        properties.add(p);
-        return this;
-    }
-
-    /**
      * Adds an ID field to the panel data, to be included in
      * the returned JSON data to the client.
      *
@@ -69,6 +60,82 @@
         return this;
     }
 
+    /**
+     * Adds a property to the panel data.
+     *
+     * @param key property key
+     * @param value property value
+     * @return self, for chaining
+     */
+    public PropertyPanel addProp(String key, String value) {
+        properties.add(new Prop(key, value));
+        return this;
+    }
+
+    /**
+     * Adds a property to the panel data, using a decimal formatter.
+     *
+     * @param key property key
+     * @param value property value
+     * @return self, for chaining
+     */
+    public PropertyPanel addProp(String key, int value) {
+        properties.add(new Prop(key, DF0.format(value)));
+        return this;
+    }
+
+    /**
+     * Adds a property to the panel data, using a decimal formatter.
+     *
+     * @param key property key
+     * @param value property value
+     * @return self, for chaining
+     */
+    public PropertyPanel addProp(String key, long value) {
+        properties.add(new Prop(key, DF0.format(value)));
+        return this;
+    }
+
+    /**
+     * Adds a property to the panel data. Note that the value's
+     * {@link Object#toString toString()} method is used to convert the
+     * value to a string.
+     *
+     * @param key property key
+     * @param value property value
+     * @return self, for chaining
+     */
+    public PropertyPanel addProp(String key, Object value) {
+        properties.add(new Prop(key, value.toString()));
+        return this;
+    }
+
+    /**
+     * Adds a property to the panel data. Note that the value's
+     * {@link Object#toString toString()} method is used to convert the
+     * value to a string, from which the characters defined in the given
+     * regular expression string are stripped.
+     *
+     * @param key property key
+     * @param value property value
+     * @param reStrip regexp characters to strip from value string
+     * @return self, for chaining
+     */
+    public PropertyPanel addProp(String key, Object value, String reStrip) {
+        String val = value.toString().replaceAll(reStrip, "");
+        properties.add(new Prop(key, val));
+        return this;
+    }
+
+    /**
+     * Adds a separator to the panel data.
+     *
+     * @return self, for chaining
+     */
+    public PropertyPanel addSeparator() {
+        properties.add(new Separator());
+        return this;
+    }
 
     /**
      * Returns the title text.
@@ -161,7 +228,6 @@
 
     // ====================
 
-    private static final DecimalFormat DF0 = new DecimalFormat("#,###");
 
     /**
      * Simple data carrier for a property, composed of a key/value pair.
@@ -182,26 +248,6 @@
         }
 
         /**
-         * Constructs a property data value.
-         * @param key property key
-         * @param value property value
-         */
-        public Prop(String key, int value) {
-            this.key = key;
-            this.value = DF0.format(value);
-        }
-
-        /**
-         * Constructs a property data value.
-         * @param key property key
-         * @param value property value
-         */
-        public Prop(String key, long value) {
-            this.key = key;
-            this.value = DF0.format(value);
-        }
-
-        /**
          * Returns the property's key.
          *
          * @return the key
diff --git a/core/api/src/test/java/org/onosproject/ui/topo/PropertyPanelTest.java b/core/api/src/test/java/org/onosproject/ui/topo/PropertyPanelTest.java
index 65bb167..7ca9ce5 100644
--- a/core/api/src/test/java/org/onosproject/ui/topo/PropertyPanelTest.java
+++ b/core/api/src/test/java/org/onosproject/ui/topo/PropertyPanelTest.java
@@ -17,12 +17,17 @@
 
 package org.onosproject.ui.topo;
 
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.onosproject.ui.topo.PropertyPanel.Prop;
 
+import java.util.HashMap;
 import java.util.Iterator;
+import java.util.Map;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
 
 /**
  * Unit tests for {@link PropertyPanel}.
@@ -33,20 +38,49 @@
     private static final String TYPE_ORIG = "Original type ID";
     private static final String TITLE_NEW = "New Title";
     private static final String TYPE_NEW = "New type";
+    private static final String SOME_IDENTIFICATION = "It's Me!";
 
-    private static final Prop PROP_A = new Prop("A", "Hay");
-    private static final Prop PROP_B = new Prop("B", "Bee");
-    private static final Prop PROP_C = new Prop("C", "Sea");
-    private static final Prop PROP_Z = new Prop("Z", "Zed");
+    private static final String KEY_A = "A";
+    private static final String KEY_B = "B";
+    private static final String KEY_C = "C";
+    private static final String KEY_Z = "Z";
+    private static final String VALUE_A = "Hay";
+    private static final String VALUE_B = "Bee";
+    private static final String VALUE_C = "Sea";
+    private static final String VALUE_Z = "Zed";
+
+    private static final Map<String, Prop> PROP_MAP = new HashMap<>();
+
+    private static class FooClass {
+        private final String s;
+        FooClass(String s) {
+            this.s = s;
+        }
+
+        @Override
+        public String toString() {
+            return ">" + s + "<";
+        }
+    }
 
     private PropertyPanel pp;
 
 
+
+    @BeforeClass
+    public static void setUpClass() {
+        PROP_MAP.put(KEY_A, new Prop(KEY_A, VALUE_A));
+        PROP_MAP.put(KEY_B, new Prop(KEY_B, VALUE_B));
+        PROP_MAP.put(KEY_C, new Prop(KEY_C, VALUE_C));
+        PROP_MAP.put(KEY_Z, new Prop(KEY_Z, VALUE_Z));
+    }
+
     @Test
     public void basic() {
         pp = new PropertyPanel(TITLE_ORIG, TYPE_ORIG);
         assertEquals("wrong title", TITLE_ORIG, pp.title());
         assertEquals("wrong type", TYPE_ORIG, pp.typeId());
+        assertNull("id?", pp.id());
         assertEquals("unexpected props", 0, pp.properties().size());
     }
 
@@ -64,20 +98,46 @@
         assertEquals("wrong type", TYPE_NEW, pp.typeId());
     }
 
-    private void validateProps(Prop... props) {
+    @Test
+    public void setId() {
+        basic();
+        pp.id(SOME_IDENTIFICATION);
+        assertEquals("wrong id", SOME_IDENTIFICATION, pp.id());
+    }
+
+    private void validateProps(String... keys) {
         Iterator<Prop> iter = pp.properties().iterator();
-        for (Prop p: props) {
-            Prop ppProp = iter.next();
-            assertEquals("Bad prop sequence", p, ppProp);
+        for (String k: keys) {
+            Prop exp = PROP_MAP.get(k);
+            Prop act = iter.next();
+            assertEquals("Bad prop sequence", exp, act);
         }
     }
 
+    private void validateProp(String key, String expValue) {
+        Iterator<Prop> iter = pp.properties().iterator();
+        Prop prop = null;
+        while (iter.hasNext()) {
+            Prop p = iter.next();
+            if (p.key().equals(key)) {
+                prop = p;
+                break;
+            }
+        }
+        if (prop == null) {
+            fail("no prop found with key: " + key);
+        }
+        assertEquals("Wrong prop value", expValue, prop.value());
+    }
+
     @Test
     public void props() {
         basic();
-        pp.add(PROP_A).add(PROP_B).add(PROP_C);
+        pp.addProp(KEY_A, VALUE_A)
+            .addProp(KEY_B, VALUE_B)
+            .addProp(KEY_C, VALUE_C);
         assertEquals("bad props", 3, pp.properties().size());
-        validateProps(PROP_A, PROP_B, PROP_C);
+        validateProps(KEY_A, KEY_B, KEY_C);
     }
 
     @Test
@@ -91,8 +151,45 @@
     @Test
     public void adjustProps() {
         props();
-        pp.removeProps("B", "A");
-        pp.add(PROP_Z);
-        validateProps(PROP_C, PROP_Z);
+        pp.removeProps(KEY_B, KEY_A);
+        pp.addProp(KEY_Z, VALUE_Z);
+        validateProps(KEY_C, KEY_Z);
     }
+
+    @Test
+    public void intValues() {
+        basic();
+        pp.addProp(KEY_A, 200)
+          .addProp(KEY_B, 2000)
+          .addProp(KEY_C, 1234567);
+
+        validateProp(KEY_A, "200");
+        validateProp(KEY_B, "2,000");
+        validateProp(KEY_C, "1,234,567");
+    }
+
+    @Test
+    public void longValues() {
+        basic();
+        pp.addProp(KEY_A, 200L)
+          .addProp(KEY_B, 2000L)
+          .addProp(KEY_C, 1234567L)
+          .addProp(KEY_Z, Long.MAX_VALUE);
+
+        validateProp(KEY_A, "200");
+        validateProp(KEY_B, "2,000");
+        validateProp(KEY_C, "1,234,567");
+        validateProp(KEY_Z, "9,223,372,036,854,775,807");
+    }
+
+    @Test
+    public void objectValue() {
+        basic();
+        pp.addProp(KEY_A, new FooClass("a"))
+            .addProp(KEY_B, new FooClass("bxyyzy"), "[xz]");
+
+        validateProp(KEY_A, ">a<");
+        validateProp(KEY_B, ">byyy<");
+    }
+
 }