Working on model annotations; still in progress.
diff --git a/core/api/src/main/java/org/onlab/onos/net/Annotations.java b/core/api/src/main/java/org/onlab/onos/net/Annotations.java
new file mode 100644
index 0000000..6076172
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/Annotations.java
@@ -0,0 +1,113 @@
+package org.onlab.onos.net;
+
+import com.google.common.collect.ImmutableMap;
+
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Represents a set of simple annotations that can be used to add arbitrary
+ * attributes to various parts of the data model.
+ */
+public final class Annotations {
+
+ private final Map<String, String> map;
+
+ /**
+ * Creates a new set of annotations using the specified immutable map.
+ *
+ * @param map immutable map of key/value pairs
+ */
+ private Annotations(ImmutableMap<String, String> map) {
+ this.map = map;
+ }
+
+ /**
+ * Creates a new annotations builder.
+ *
+ * @return new annotations builder
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Returns the set of keys for available annotations. Note that this set
+ * includes keys for any attributes tagged for removal.
+ *
+ * @return annotation keys
+ */
+ public Set<String> keys() {
+ return map.keySet();
+ }
+
+ /**
+ * Returns the value of the specified annotation.
+ *
+ * @param key annotation key
+ * @return annotation value
+ */
+ public String value(String key) {
+ String value = map.get(key);
+ return Objects.equals(Builder.REMOVED, value) ? null : value;
+ }
+
+ /**
+ * Indicates whether the specified key has been tagged as removed. This is
+ * used to for merging sparse annotation sets.
+ *
+ * @param key annotation key
+ * @return true if the previous annotation has been tagged for removal
+ */
+ public boolean isRemoved(String key) {
+ return Objects.equals(Builder.REMOVED, map.get(key));
+ }
+
+ /**
+ * Facility for gradually building model annotations.
+ */
+ public static final class Builder {
+
+ private static final String REMOVED = "~rEmOvEd~";
+ private final ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
+
+ // Private construction is forbidden.
+ private Builder() {
+ }
+
+ /**
+ * Adds the specified annotation. Any previous value associated with
+ * the given annotation key will be overwritten.
+ *
+ * @param key annotation key
+ * @param value annotation value
+ * @return self
+ */
+ public Builder set(String key, String value) {
+ builder.put(key, value);
+ return this;
+ }
+
+ /**
+ * Adds the specified annotation. Any previous value associated with
+ * the given annotation key will be tagged for removal.
+ *
+ * @param key annotation key
+ * @return self
+ */
+ public Builder remove(String key) {
+ builder.put(key, REMOVED);
+ return this;
+ }
+
+ /**
+ * Returns immutable annotations built from the accrued key/values pairs.
+ *
+ * @return annotations
+ */
+ public Annotations build() {
+ return new Annotations(builder.build());
+ }
+ }
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/DefaultPort.java b/core/api/src/main/java/org/onlab/onos/net/DefaultPort.java
index 534cbe4..ac57498 100644
--- a/core/api/src/main/java/org/onlab/onos/net/DefaultPort.java
+++ b/core/api/src/main/java/org/onlab/onos/net/DefaultPort.java
@@ -2,12 +2,13 @@
import static com.google.common.base.MoreObjects.toStringHelper;
+import java.util.Map;
import java.util.Objects;
/**
* Default port implementation.
*/
-public class DefaultPort implements Port {
+public class DefaultPort extends AbstractAnnotated implements Port {
private final Element element;
private final PortNumber number;
@@ -19,9 +20,13 @@
* @param element parent network element
* @param number port number
* @param isEnabled indicator whether the port is up and active
+ * @param annotations optional key/value annotations
*/
+ @SafeVarargs
public DefaultPort(Element element, PortNumber number,
- boolean isEnabled) {
+ boolean isEnabled,
+ Map<String, String>... annotations) {
+ super(annotations);
this.element = element;
this.number = number;
this.isEnabled = isEnabled;
diff --git a/core/api/src/main/java/org/onlab/onos/net/Element.java b/core/api/src/main/java/org/onlab/onos/net/Element.java
index 5d3969e..1c5e22b 100644
--- a/core/api/src/main/java/org/onlab/onos/net/Element.java
+++ b/core/api/src/main/java/org/onlab/onos/net/Element.java
@@ -3,7 +3,7 @@
/**
* Base abstraction of a network element, i.e. an infrastructure device or an end-station host.
*/
-public interface Element extends Provided {
+public interface Element extends Annotated, Provided {
/**
* Returns the network element identifier.
diff --git a/core/api/src/main/java/org/onlab/onos/net/Link.java b/core/api/src/main/java/org/onlab/onos/net/Link.java
index 0b60b9c..be2f99bf 100644
--- a/core/api/src/main/java/org/onlab/onos/net/Link.java
+++ b/core/api/src/main/java/org/onlab/onos/net/Link.java
@@ -3,7 +3,7 @@
/**
* Abstraction of a network infrastructure link.
*/
-public interface Link extends Provided {
+public interface Link extends Annotated, Provided {
/**
* Coarse representation of the link type.
diff --git a/core/api/src/main/java/org/onlab/onos/net/Port.java b/core/api/src/main/java/org/onlab/onos/net/Port.java
index 2ebbd15..e2da4a1 100644
--- a/core/api/src/main/java/org/onlab/onos/net/Port.java
+++ b/core/api/src/main/java/org/onlab/onos/net/Port.java
@@ -4,7 +4,7 @@
/**
* Abstraction of a network port.
*/
-public interface Port {
+public interface Port extends Annotated {
/**
* Returns the port number.