Introduce ResourcePath.Key
Change-Id: I4efd5c13a12f2bad5482f5b432e2f1ef2c337805
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 72f8ac0..d07e516 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 Open Networking Laboratory
+ * Copyright 2015-2016 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,7 +21,6 @@
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
-import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@@ -50,12 +49,12 @@
public abstract class ResourcePath {
private final Discrete parent;
- private final Object last;
+ private final Key key;
public static final Discrete ROOT = new Discrete();
public static ResourcePath discrete(DeviceId device) {
- return new Discrete(ImmutableList.of(device));
+ return new Discrete(Key.of(device));
}
/**
@@ -66,10 +65,7 @@
* @return resource path instance
*/
public static ResourcePath discrete(DeviceId device, Object... components) {
- return new Discrete(ImmutableList.builder()
- .add(device)
- .add(components)
- .build());
+ return new Discrete(Key.of(device, components));
}
/**
@@ -81,11 +77,7 @@
* @return resource path instance
*/
public static ResourcePath discrete(DeviceId device, PortNumber port, Object... components) {
- return new Discrete(ImmutableList.builder()
- .add(device)
- .add(port)
- .add(components)
- .build());
+ return new Discrete(Key.of(device, port, components));
}
/**
@@ -100,10 +92,7 @@
checkArgument(components.length > 0,
"Length of components must be greater thant 0, but " + components.length);
- return new Continuous(ImmutableList.builder()
- .add(device)
- .add(components)
- .build(), value);
+ return new Continuous(Key.of(device, components), value);
}
/**
@@ -116,49 +105,29 @@
* @return resource path instance
*/
public static ResourcePath continuous(double value, DeviceId device, PortNumber port, Object... components) {
- return new Continuous(ImmutableList.builder()
- .add(device)
- .add(port)
- .add(components)
- .build(), value);
+ return new Continuous(Key.of(device, port, components), value);
}
/**
- * Creates an resource path from the specified components.
+ * Creates an resource path from the specified key.
*
- * @param components components of the path. The order represents hierarchical structure of the resource.
+ * @param key key of the path
*/
- protected ResourcePath(List<Object> components) {
- checkNotNull(components);
- checkArgument(!components.isEmpty());
+ protected ResourcePath(Key key) {
+ checkNotNull(key);
- LinkedList<Object> children = new LinkedList<>(components);
- this.last = children.pollLast();
- if (children.isEmpty()) {
+ this.key = key;
+ if (key.components.size() == 1) {
this.parent = ROOT;
} else {
- this.parent = new Discrete(children);
+ this.parent = new Discrete(key.parent());
}
}
- /**
- * Creates an resource path from the specified parent and child.
- *
- * @param parent the parent of this resource
- * @param last a child of the parent
- */
- protected ResourcePath(Discrete parent, Object last) {
- checkNotNull(parent);
- checkNotNull(last);
-
- this.parent = parent;
- this.last = last;
- }
-
// for serialization
private ResourcePath() {
this.parent = null;
- this.last = null;
+ this.key = Key.ROOT;
}
/**
@@ -167,15 +136,7 @@
* @return the components of this resource path
*/
public List<Object> components() {
- LinkedList<Object> components = new LinkedList<>();
-
- ResourcePath current = this;
- while (current.parent().isPresent()) {
- components.addFirst(current.last);
- current = current.parent;
- }
-
- return components;
+ return key.components;
}
/**
@@ -199,7 +160,7 @@
public ResourcePath child(Object child) {
checkState(this instanceof Discrete);
- return new Discrete((Discrete) this, child);
+ return new Discrete(key().child(child));
}
/**
@@ -213,7 +174,7 @@
public ResourcePath child(Object child, double value) {
checkState(this instanceof Discrete);
- return new Continuous((Discrete) this, child, value);
+ return new Continuous(key.child(child), value);
}
/**
@@ -223,12 +184,24 @@
* The return value is equal to the last object of {@code components()}.
*/
public Object last() {
- return last;
+ if (key.components.isEmpty()) {
+ return null;
+ }
+ return key.components.get(key.components.size() - 1);
+ }
+
+ /**
+ * Returns the key of this resource path.
+ *
+ * @return the key of this resource path
+ */
+ public Key key() {
+ return key;
}
@Override
public int hashCode() {
- return Objects.hash(this.parent, this.last);
+ return key.hashCode();
}
@Override
@@ -240,15 +213,13 @@
return false;
}
final ResourcePath that = (ResourcePath) obj;
- return Objects.equals(this.parent, that.parent)
- && Objects.equals(this.last, that.last);
+ return Objects.equals(this.key, that.key);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
- .add("parent", parent)
- .add("last", last)
+ .add("key", key)
.toString();
}
@@ -266,12 +237,8 @@
super();
}
- private Discrete(List<Object> components) {
- super(components);
- }
-
- private Discrete(Discrete parent, Object last) {
- super(parent, last);
+ private Discrete(Key key) {
+ super(key);
}
}
@@ -284,17 +251,34 @@
*/
@Beta
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);
+ private Continuous(Key key, double value) {
+ super(key);
this.value = value;
}
- public Continuous(Discrete parent, Object last, double value) {
- super(parent, last);
- this.value = value;
+ @Override
+ public int hashCode() {
+ return Objects.hash(this.key(), this.value);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (!(obj instanceof Continuous)) {
+ return false;
+ }
+
+ if (!super.equals(obj)) {
+ return false;
+ }
+
+ final Continuous other = (Continuous) obj;
+ return Objects.equals(this.key(), other.key());
}
/**
@@ -306,4 +290,80 @@
return value;
}
}
+
+ /**
+ * Represents key of resource path used as a key in ResourceStore.
+ * This class is exposed to public, but intended to use only in ResourceStore implementations.
+ */
+ @Beta
+ public static final class Key {
+ private static final Key ROOT = new Key();
+
+ private final ImmutableList<Object> components;
+
+ private static Key of(DeviceId device, Object... components) {
+ return new Key(ImmutableList.builder()
+ .add(device)
+ .add(components)
+ .build());
+ }
+
+ private static Key of(DeviceId device, PortNumber port, Object... components) {
+ return new Key(ImmutableList.builder()
+ .add(device)
+ .add(port)
+ .add(components)
+ .build());
+ }
+
+ private Key(ImmutableList<Object> components) {
+ this.components = checkNotNull(components);
+ }
+
+ // for serializer
+ private Key() {
+ this.components = ImmutableList.of();
+ }
+
+ // IndexOutOfBoundsException is raised when the instance is equal to ROOT
+ private Key parent() {
+ if (components.size() == 1) {
+ return ROOT;
+ } else {
+ return new Key(components.subList(0, components.size() - 1));
+ }
+ }
+
+ private Key child(Object child) {
+ return new Key(ImmutableList.builder()
+ .add(components)
+ .add(child)
+ .build());
+ }
+
+ @Override
+ public int hashCode() {
+ return components.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof Key)) {
+ return false;
+ }
+
+ Key other = (Key) obj;
+ return Objects.equals(this.components, other.components);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("components", components)
+ .toString();
+ }
+ }
}