ONOS-6730: Topo View i18n:
- Deprecate non-localized PropertyPanel.addProp() methods.
- Add modify*LinkDetails() methods to UiTopoOverlay class.
- Augment TVMH.RequestDetails to handle link details requests.
- Refactor deviceDetails() to allow piecemeal construction of the Properties Panel.
    This allows us to include (or not) the location properties (geo/grid).
- Refactor hostDetails() for piecemeal construction of Properties Panel.
- Add edgeLinkDetails() and infraLinkDetails() methods.
- No lat/long suppression now done server-side. Check for trailing separator.
- Augment requestDetails() to format link details requests.
- Added lion.getSafe(Enum<?>) method.
- Added DeviceEnums and LinkEnums resource bundles.

Change-Id: Ibbd113a7d5ef73765cd10aed0fb7ea8efbaa16c5
diff --git a/core/api/src/main/java/org/onosproject/net/link/LinkService.java b/core/api/src/main/java/org/onosproject/net/link/LinkService.java
index 9d838ac..382ea52 100644
--- a/core/api/src/main/java/org/onosproject/net/link/LinkService.java
+++ b/core/api/src/main/java/org/onosproject/net/link/LinkService.java
@@ -103,6 +103,8 @@
 
     // FIXME: I don't think this makes sense; discuss and remove or adjust return
     // to be a Set<Link> or add Link.Type parameter
+    // NOTE: TopoViewMessageHandler uses this to acquire a given link from
+    //        two connect points. Would hate to see this method go away.. SDH
     /**
      * Returns the infrastructure links between the specified source
      * and destination connection points.
diff --git a/core/api/src/main/java/org/onosproject/ui/UiTopoOverlay.java b/core/api/src/main/java/org/onosproject/ui/UiTopoOverlay.java
index 5e0b439..c373bd3 100644
--- a/core/api/src/main/java/org/onosproject/ui/UiTopoOverlay.java
+++ b/core/api/src/main/java/org/onosproject/ui/UiTopoOverlay.java
@@ -16,6 +16,7 @@
 
 package org.onosproject.ui;
 
+import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.HostId;
 import org.onosproject.net.link.LinkEvent;
@@ -114,7 +115,7 @@
      * a selected device.
      * This default implementation does nothing.
      *
-     * @param pp       property panel model of summary data
+     * @param pp       property panel model of device data
      * @param deviceId device id
      */
     public void modifyDeviceDetails(PropertyPanel pp, DeviceId deviceId) {
@@ -125,13 +126,48 @@
      * a selected host.
      * This default implementation does nothing.
      *
-     * @param pp     property panel model of summary data
+     * @param pp     property panel model of host data
      * @param hostId host id
      */
     public void modifyHostDetails(PropertyPanel pp, HostId hostId) {
     }
 
     /**
+     * Callback to modify the contents of the details panel for a selected
+     * edge link. The parameters include identifiers for the host and the
+     * connect point (device and port) to which the host is connected.
+     * <p>
+     * This default implementation does nothing.
+     *
+     * @param pp     property panel model of edge link data
+     * @param hostId host ID
+     * @param cp     connect point
+     */
+    public void modifyEdgeLinkDetails(PropertyPanel pp,
+                                      HostId hostId, ConnectPoint cp) {
+    }
+
+    /**
+     * Callback to modify the contents of the details panel for a selected
+     * infrastructure link. The parameters include the two connect points
+     * at either end of the link.
+     * <p>
+     * Note that links in the topology view are (usually) "bi-directional",
+     * meaning that both {@literal A-->B} and {@literal B-->A} backing links
+     * exist. If, however, there is only one backing link, it is guaranteed
+     * to be {@literal A-->B}.
+     * <p>
+     * This default implementation does nothing.
+     *
+     * @param pp  property panel model of infrastructure link data
+     * @param cpA connect point A
+     * @param cpB connect point B
+     */
+    public void modifyInfraLinkDetails(PropertyPanel pp,
+                                       ConnectPoint cpA, ConnectPoint cpB) {
+    }
+
+    /**
      * Callback invoked when a link event is processed (e.g.&nbsp;link added).
      * A subclass may override this method to return a map of property
      * key/value pairs to be included in the JSON event back to the client,
@@ -144,7 +180,8 @@
      * @param event the link event
      * @return map of additional key/value pairs to be added to the JSON event
      * @deprecated this is a temporary addition for Goldeneye (1.6) release,
-     * and expected to be replaced in the Ibis (1.8) release
+     * and is superceded by use of {@link #modifyEdgeLinkDetails} and
+     * {@link #modifyInfraLinkDetails}.
      */
     @Deprecated
     public Map<String, String> additionalLinkData(LinkEvent event) {
diff --git a/core/api/src/main/java/org/onosproject/ui/lion/LionBundle.java b/core/api/src/main/java/org/onosproject/ui/lion/LionBundle.java
index 780dea8..56fc4bc 100644
--- a/core/api/src/main/java/org/onosproject/ui/lion/LionBundle.java
+++ b/core/api/src/main/java/org/onosproject/ui/lion/LionBundle.java
@@ -97,6 +97,17 @@
     }
 
     /**
+     * Converts the given enum constant to lowercase and then uses that as the
+     * key to invoke {@link #getSafe(String)}.
+     *
+     * @param enumConst the constant to use as the key
+     * @return the localized value (or a wrapped key placeholder)
+     */
+    public String getSafe(Enum<?> enumConst) {
+        return getSafe(enumConst.name().toLowerCase());
+    }
+
+    /**
      * Returns an immutable set of the items in this bundle.
      *
      * @return the items in this bundle
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 561fa76..892a75d 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
@@ -31,7 +31,7 @@
     private static final NumberFormat NF = NumberFormat.getInstance();
 
     private String title;
-    private String typeId;
+    private String glyphId;
     private String id;
     private String navPath;
     private List<Prop> properties = new ArrayList<>();
@@ -39,14 +39,14 @@
 
     /**
      * Constructs a property panel model with the given title and
-     * type identifier (icon to display).
+     * glyph identifier (icon to display).
      *
-     * @param title  title text
-     * @param typeId type (icon) ID
+     * @param title   title text
+     * @param glyphId glyph ID
      */
-    public PropertyPanel(String title, String typeId) {
+    public PropertyPanel(String title, String glyphId) {
         this.title = title;
-        this.typeId = typeId;
+        this.glyphId = glyphId;
     }
 
     /**
@@ -154,7 +154,7 @@
      * regular expression string are stripped.
      *
      * @param key     property key
-     * @param label property label (localized)
+     * @param label   property label (localized)
      * @param value   property value
      * @param reStrip regexp characters to strip from value string
      * @return self, for chaining
@@ -177,8 +177,9 @@
      * @param key   property key (also used as display label)
      * @param value property value
      * @return self, for chaining
-     * @see #addProp(String, String, String)
+     * @deprecated as of Loon (1.11) in deference to the localized version
      */
+    @Deprecated
     public PropertyPanel addProp(String key, String value) {
         return addProp(key, key, value);
     }
@@ -190,7 +191,9 @@
      * @param key   property key (also used as display label)
      * @param value property value
      * @return self, for chaining
+     * @deprecated as of Loon (1.11) in deference to the localized version
      */
+    @Deprecated
     public PropertyPanel addProp(String key, int value) {
         return addProp(key, key, value);
     }
@@ -202,7 +205,9 @@
      * @param key   property key (also used as display label)
      * @param value property value
      * @return self, for chaining
+     * @deprecated as of Loon (1.11) in deference to the localized version
      */
+    @Deprecated
     public PropertyPanel addProp(String key, long value) {
         return addProp(key, key, value);
     }
@@ -216,7 +221,9 @@
      * @param key   property key (also used as display label)
      * @param value property value
      * @return self, for chaining
+     * @deprecated as of Loon (1.11) in deference to the localized version
      */
+    @Deprecated
     public PropertyPanel addProp(String key, Object value) {
         return addProp(key, key, value);
     }
@@ -232,7 +239,9 @@
      * @param value   property value
      * @param reStrip regexp characters to strip from value string
      * @return self, for chaining
+     * @deprecated as of Loon (1.11) in deference to the localized version
      */
+    @Deprecated
     public PropertyPanel addProp(String key, Object value, String reStrip) {
         return addProp(key, key, value, reStrip);
     }
@@ -257,12 +266,12 @@
     }
 
     /**
-     * Returns the type identifier.
+     * Returns the glyph identifier.
      *
-     * @return type identifier
+     * @return glyph identifier
      */
-    public String typeId() {
-        return typeId;
+    public String glyphId() {
+        return glyphId;
     }
 
     /**
@@ -288,7 +297,6 @@
      *
      * @return the property list
      */
-    // TODO: consider protecting this?
     public List<Prop> properties() {
         return properties;
     }
@@ -298,7 +306,6 @@
      *
      * @return the button list
      */
-    // TODO: consider protecting this?
     public List<ButtonId> buttons() {
         return buttons;
     }
@@ -317,13 +324,13 @@
     }
 
     /**
-     * Sets the type identifier (icon ID).
+     * Sets the glyph identifier.
      *
-     * @param typeId type identifier
+     * @param glyphId glyph identifier
      * @return self, for chaining
      */
-    public PropertyPanel typeId(String typeId) {
-        this.typeId = typeId;
+    public PropertyPanel glyphId(String glyphId) {
+        this.glyphId = glyphId;
         return this;
     }
 
@@ -478,8 +485,8 @@
     /**
      * Auxiliary class representing a separator property.
      */
-    public static class Separator extends Prop {
-        public Separator() {
+    static class Separator extends Prop {
+        Separator() {
             super("-", "-", "");
         }
     }
diff --git a/core/api/src/main/java/org/onosproject/ui/topo/TopoConstants.java b/core/api/src/main/java/org/onosproject/ui/topo/TopoConstants.java
index c5952a1..50898ab 100644
--- a/core/api/src/main/java/org/onosproject/ui/topo/TopoConstants.java
+++ b/core/api/src/main/java/org/onosproject/ui/topo/TopoConstants.java
@@ -22,8 +22,8 @@
 public final class TopoConstants {
 
     /**
-     * Defines constants for property keys on the default summary and
-     * details panels. Note that display labels should be looked up using
+     * Defines constants for property/localization keys on the default summary
+     * and details panels. Note that display labels should be looked up using
      * the "core.view.Topo" localization bundle (LionBundle).
      */
     public static final class Properties {
@@ -56,6 +56,7 @@
         public static final String MAC = "mac";
         public static final String IP = "ip";
         public static final String VLAN = "vlan";
+        public static final String VLAN_NONE = "vlan_none";
     }
 
     /**
diff --git a/core/api/src/main/java/org/onosproject/ui/topo/TopoJson.java b/core/api/src/main/java/org/onosproject/ui/topo/TopoJson.java
index a0646c7..07a187c 100644
--- a/core/api/src/main/java/org/onosproject/ui/topo/TopoJson.java
+++ b/core/api/src/main/java/org/onosproject/ui/topo/TopoJson.java
@@ -46,7 +46,7 @@
     static final String MSG = "msg";
 
     static final String TITLE = "title";
-    static final String TYPE = "type";
+    static final String GLYPH_ID = "glyphId";
     static final String NAV_PATH = "navPath";
     static final String PROP_ORDER = "propOrder";
     static final String PROP_LABELS = "propLabels";
@@ -179,7 +179,7 @@
     public static ObjectNode json(PropertyPanel pp) {
         ObjectNode result = objectNode()
                 .put(TITLE, pp.title())
-                .put(TYPE, pp.typeId())
+                .put(GLYPH_ID, pp.glyphId())
                 .put(ID, pp.id());
 
         if (pp.navPath() != null) {