Add sub-types to distinguish type of resources
Change-Id: Ia43cbf4a13937c9bd9dbc97221062ef5fa3e578f
diff --git a/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java b/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java
index da7d346..0a4d385 100644
--- a/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java
+++ b/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java
@@ -19,13 +19,14 @@
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
-import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
+import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
/**
* An object that is used to locate a resource in a network.
@@ -33,25 +34,45 @@
* of elementary resources that are not globally identifiable. A ResourcePath can be a globally
* unique resource identifier.
*
+ * Two types of resource are considered. One is discrete type and the other is continuous type.
+ * Discrete type resource is a resource whose amount is measured as a discrete unit. VLAN ID and
+ * MPLS label are examples of discrete type resource. Continuous type resource is a resource whose
+ * amount is measured as a continuous value. Bandwidth is an example of continuous type resource.
+ * A double value is associated with a continuous type value.
+ *
* Users of this class must keep the semantics of resources regarding the hierarchical structure.
* For example, resource path, Link:1/VLAN ID:100, is valid, but resource path, VLAN ID:100/Link:1
* is not valid because a link is not a sub-component of a VLAN ID.
*/
@Beta
-public final class ResourcePath {
+public abstract class ResourcePath {
- private final ResourcePath parent;
+ private final Discrete parent;
private final Object last;
- public static final ResourcePath ROOT = new ResourcePath(ImmutableList.of());
+ public static final Discrete ROOT = new Discrete();
/**
- * Creates an resource path from the specified components.
+ * Creates an resource path which represents a discrete-type resource from the specified components.
*
* @param components components of the path. The order represents hierarchical structure of the resource.
*/
- public ResourcePath(Object... components) {
- this(Arrays.asList(components));
+ public static ResourcePath discrete(Object... components) {
+ if (components.length == 0) {
+ return ROOT;
+ } else {
+ return new Discrete(ImmutableList.copyOf(components));
+ }
+ }
+
+ /**
+ * Creates an resource path which represents a continuous-type resource from the specified components.
+ *
+ * @param value amount of the resource
+ * @param components components of the path. The order represents hierarchical structure of the resource.
+ */
+ public static ResourcePath continuous(double value, Object... components) {
+ return new Continuous(ImmutableList.copyOf(components), value);
}
/**
@@ -59,17 +80,17 @@
*
* @param components components of the path. The order represents hierarchical structure of the resource.
*/
- public ResourcePath(List<Object> components) {
+ ResourcePath(List<Object> components) {
checkNotNull(components);
- if (components.isEmpty()) {
- this.parent = null;
- this.last = null;
- return;
- }
+ checkArgument(!components.isEmpty());
LinkedList<Object> children = new LinkedList<>(components);
this.last = children.pollLast();
- this.parent = new ResourcePath(children);
+ if (children.isEmpty()) {
+ this.parent = ROOT;
+ } else {
+ this.parent = new Discrete(children);
+ }
}
/**
@@ -78,9 +99,12 @@
* @param parent the parent of this resource
* @param last a child of the parent
*/
- public ResourcePath(ResourcePath parent, Object last) {
- this.parent = checkNotNull(parent);
- this.last = checkNotNull(last);
+ ResourcePath(Discrete parent, Object last) {
+ checkNotNull(parent);
+ checkNotNull(last);
+
+ this.parent = parent;
+ this.last = last;
}
// for serialization
@@ -97,10 +121,10 @@
public List<Object> components() {
LinkedList<Object> components = new LinkedList<>();
- ResourcePath parentPath = parent;
- while (parentPath != null) {
+ Optional<Discrete> parentPath = Optional.ofNullable(parent);
+ while (parentPath.isPresent()) {
components.addFirst(last);
- parentPath = parent.parent;
+ parentPath = parent.parent();
}
return components;
@@ -113,12 +137,20 @@
* @return the parent resource path of this instance.
* If there is no parent, empty instance will be returned.
*/
- public Optional<ResourcePath> parent() {
+ public Optional<Discrete> parent() {
return Optional.ofNullable(parent);
}
public ResourcePath child(Object child) {
- return new ResourcePath(this, child);
+ checkState(this instanceof Discrete);
+
+ return new Discrete((Discrete) this, child);
+ }
+
+ public ResourcePath child(Object child, double value) {
+ checkState(this instanceof Discrete);
+
+ return new Continuous((Discrete) this, child, value);
}
/**
@@ -156,4 +188,57 @@
.add("last", last)
.toString();
}
+
+ /**
+ * Represents a resource path which specifies a resource which can be measured
+ * as a discrete unit. A VLAN ID and a MPLS label of a link are examples of the resource.
+ * <p>
+ * Note: This class is exposed to the public, but intended to be used in the resource API
+ * implementation only. It is not for resource API user.
+ * </p>
+ */
+ public static final class Discrete extends ResourcePath {
+ private Discrete() {
+ super();
+ }
+
+ private Discrete(List<Object> components) {
+ super(components);
+ }
+
+ private Discrete(Discrete parent, Object last) {
+ super(parent, last);
+ }
+ }
+
+ /**
+ * Represents a resource path which specifies a resource which can be measured
+ * as continuous value. Bandwidth of a link is an example of the resource.
+ * <p>
+ * Note: This class is exposed to the public, but intended to be used in the resource API
+ * implementation only. It is not for resource API user.
+ */
+ public static final class Continuous extends ResourcePath {
+ // Note: value is not taken into account for equality
+ private final double value;
+
+ private Continuous(List<Object> components, double value) {
+ super(components);
+ this.value = value;
+ }
+
+ public Continuous(Discrete parent, Object last, double value) {
+ super(parent, last);
+ this.value = value;
+ }
+
+ /**
+ * Returns the value of the resource amount.
+ *
+ * @return the value of the resource amount
+ */
+ public double value() {
+ return value;
+ }
+ }
}