Use concrete types instead of abstract types
- ResourceId -> DiscreteResourceId/ContinuousResourceId
- Resource -> DiscreteResource/ContinuousResource
In addition, stop sharing the implementations in the super classes
Change-Id: I44662f6b7c23a23c30844a5b693e1cabab2cc091
diff --git a/core/api/src/main/java/org/onosproject/net/newresource/ContinuousResource.java b/core/api/src/main/java/org/onosproject/net/newresource/ContinuousResource.java
index b0573dc..a15ed34 100644
--- a/core/api/src/main/java/org/onosproject/net/newresource/ContinuousResource.java
+++ b/core/api/src/main/java/org/onosproject/net/newresource/ContinuousResource.java
@@ -16,8 +16,11 @@
package org.onosproject.net.newresource;
import com.google.common.annotations.Beta;
+import com.google.common.base.MoreObjects;
+import java.util.List;
import java.util.Objects;
+import java.util.Optional;
/**
* Represents a resource path which specifies a resource which can be measured
@@ -27,15 +30,20 @@
* implementation only. It is not for resource API user.
*/
@Beta
-// TODO: consider how to restrict the visibility
-public final class ContinuousResource extends Resource {
+public final class ContinuousResource implements Resource {
+ private final ContinuousResourceId id;
private final double value;
- ContinuousResource(ResourceId id, double value) {
- super(id);
+ ContinuousResource(ContinuousResourceId id, double value) {
+ this.id = id;
this.value = value;
}
+ @Override
+ public ContinuousResourceId id() {
+ return id;
+ }
+
/**
* The user of this methods must receive the return value as Double or double.
* Otherwise, this methods throws an exception.
@@ -49,6 +57,44 @@
return (T) Double.valueOf(value);
}
+ /**
+ * Returns the value of the resource amount.
+ *
+ * @return the value of the resource amount
+ */
+ // FIXME: overlapping a purpose with volume()
+ public double value() {
+ return value;
+ }
+
+ @Override
+ public List<Object> components() {
+ return id.components;
+ }
+
+ @Override
+ public Object last() {
+ if (id.components.isEmpty()) {
+ return null;
+ }
+ return id.components.get(id.components.size() - 1);
+ }
+
+ @Override
+ public DiscreteResource child(Object child) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ContinuousResource child(Class<?> child, double value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Optional<DiscreteResource> parent() {
+ return Optional.ofNullable(id.parent()).map(DiscreteResource::new);
+ }
+
@Override
public int hashCode() {
return Objects.hash(id(), value);
@@ -67,13 +113,11 @@
&& Objects.equals(this.value, other.value);
}
- /**
- * Returns the value of the resource amount.
- *
- * @return the value of the resource amount
- */
- // FIXME: overlapping a purpose with volume()
- public double value() {
- return value;
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("id", id)
+ .add("volume", value)
+ .toString();
}
}
diff --git a/core/api/src/main/java/org/onosproject/net/newresource/ContinuousResourceId.java b/core/api/src/main/java/org/onosproject/net/newresource/ContinuousResourceId.java
index cd25a92..b0937bc 100644
--- a/core/api/src/main/java/org/onosproject/net/newresource/ContinuousResourceId.java
+++ b/core/api/src/main/java/org/onosproject/net/newresource/ContinuousResourceId.java
@@ -18,6 +18,8 @@
import com.google.common.annotations.Beta;
import com.google.common.collect.ImmutableList;
+import java.util.Objects;
+
import static com.google.common.base.Preconditions.checkNotNull;
/**
@@ -27,16 +29,73 @@
* implementation only. It is not for resource API user.
*/
@Beta
-// TODO: consider how to restrict the visibility
public final class ContinuousResourceId extends ResourceId {
+ final ImmutableList<Object> components;
+
// for printing purpose only (used in toString() implementation)
private final String name;
ContinuousResourceId(ImmutableList<Object> components, String name) {
- super(components);
+ this.components = components;
this.name = checkNotNull(name);
}
+ ContinuousResourceId(ImmutableList.Builder<Object> parentComponents, Class<?> last) {
+ this.components = parentComponents.add(last.getCanonicalName()).build();
+ this.name = last.getSimpleName();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * A child of a continuous-type resource is prohibited.
+ * {@link UnsupportedOperationException} is always thrown.
+ */
+ @Override
+ public DiscreteResourceId child(Object child) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * A child of a continuous-type resource is prohibited.
+ * {@link UnsupportedOperationException} is always thrown.
+ */
+ @Override
+ public ContinuousResourceId child(Class<?> child) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ DiscreteResourceId parent() {
+ if (components.size() == 0) {
+ return null;
+ }
+ if (components.size() == 1) {
+ return ROOT;
+ } else {
+ return new DiscreteResourceId(components.subList(0, components.size() - 1));
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return components.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ final ContinuousResourceId other = (ContinuousResourceId) obj;
+ return Objects.equals(this.components, other.components);
+ }
+
@Override
public String toString() {
// due to performance consideration, the value might need to be stored in a field
diff --git a/core/api/src/main/java/org/onosproject/net/newresource/DiscreteResource.java b/core/api/src/main/java/org/onosproject/net/newresource/DiscreteResource.java
index 9efbbd1..9e9468a 100644
--- a/core/api/src/main/java/org/onosproject/net/newresource/DiscreteResource.java
+++ b/core/api/src/main/java/org/onosproject/net/newresource/DiscreteResource.java
@@ -16,8 +16,13 @@
package org.onosproject.net.newresource;
import com.google.common.annotations.Beta;
+import com.google.common.base.MoreObjects;
+import java.util.List;
import java.util.Objects;
+import java.util.Optional;
+
+import static com.google.common.base.Preconditions.checkArgument;
/**
* Represents a resource path which specifies a resource which can be measured
@@ -28,14 +33,20 @@
* </p>
*/
@Beta
-// TODO: consider how to restrict the visibility
-public final class DiscreteResource extends Resource {
- protected DiscreteResource() {
- super();
+public final class DiscreteResource implements Resource {
+ private final DiscreteResourceId id;
+
+ DiscreteResource(DiscreteResourceId id) {
+ this.id = id;
}
- DiscreteResource(ResourceId id) {
- super(id);
+ protected DiscreteResource() {
+ this.id = ResourceId.ROOT;
+ }
+
+ @Override
+ public DiscreteResourceId id() {
+ return id;
}
/**
@@ -53,6 +64,36 @@
}
@Override
+ public List<Object> components() {
+ return id.components;
+ }
+
+ @Override
+ public Object last() {
+ if (id.components.isEmpty()) {
+ return null;
+ }
+ return id.components.get(id.components.size() - 1);
+ }
+
+ @Override
+ public DiscreteResource child(Object child) {
+ checkArgument(!(child instanceof Class<?>));
+
+ return new DiscreteResource(id().child(child));
+ }
+
+ @Override
+ public ContinuousResource child(Class<?> child, double value) {
+ return new ContinuousResource(id.child(child), value);
+ }
+
+ @Override
+ public Optional<DiscreteResource> parent() {
+ return Optional.ofNullable(id.parent()).map(DiscreteResource::new);
+ }
+
+ @Override
public int hashCode() {
// the value returing from volume() is excluded due to optimization
return id().hashCode();
@@ -70,4 +111,12 @@
// the value returing from volume() is excluded due to optimization
return Objects.equals(this.id(), other.id());
}
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("id", id)
+ .add("volume", volume())
+ .toString();
+ }
}
diff --git a/core/api/src/main/java/org/onosproject/net/newresource/DiscreteResourceId.java b/core/api/src/main/java/org/onosproject/net/newresource/DiscreteResourceId.java
index cf9d334..035561d 100644
--- a/core/api/src/main/java/org/onosproject/net/newresource/DiscreteResourceId.java
+++ b/core/api/src/main/java/org/onosproject/net/newresource/DiscreteResourceId.java
@@ -18,6 +18,11 @@
import com.google.common.annotations.Beta;
import com.google.common.collect.ImmutableList;
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
/**
* ResourceId for {@link DiscreteResource}.
*
@@ -25,13 +30,65 @@
* implementation only. It is not for resource API user.
*/
@Beta
-// TODO: consider how to restrict the visibility
public final class DiscreteResourceId extends ResourceId {
+ final ImmutableList<Object> components;
+
DiscreteResourceId(ImmutableList<Object> components) {
- super(components);
+ this.components = components;
}
DiscreteResourceId() {
- super();
+ this.components = ImmutableList.of();
+ }
+
+ @Override
+ public DiscreteResourceId child(Object child) {
+ checkArgument(!(child instanceof Class<?>));
+
+ return new DiscreteResourceId(ImmutableList.builder()
+ .addAll(components)
+ .add(child)
+ .build());
+ }
+
+ @Override
+ public ContinuousResourceId child(Class<?> child) {
+ checkNotNull(child);
+
+ return new ContinuousResourceId(ImmutableList.builder().addAll(components), child);
+ }
+
+ @Override
+ DiscreteResourceId parent() {
+ if (components.size() == 0) {
+ return null;
+ }
+ if (components.size() == 1) {
+ return ROOT;
+ } else {
+ return new DiscreteResourceId(components.subList(0, components.size() - 1));
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return components.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ final DiscreteResourceId other = (DiscreteResourceId) obj;
+ return Objects.equals(this.components, other.components);
+ }
+
+ @Override
+ public String toString() {
+ return components.toString();
}
}
diff --git a/core/api/src/main/java/org/onosproject/net/newresource/Resource.java b/core/api/src/main/java/org/onosproject/net/newresource/Resource.java
index 1dadcc2..a2b539e 100644
--- a/core/api/src/main/java/org/onosproject/net/newresource/Resource.java
+++ b/core/api/src/main/java/org/onosproject/net/newresource/Resource.java
@@ -16,7 +16,6 @@
package org.onosproject.net.newresource;
import com.google.common.annotations.Beta;
-import com.google.common.base.MoreObjects;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
@@ -24,8 +23,6 @@
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 represent a resource in a network.
@@ -44,14 +41,11 @@
* VLAN ID:100/Device:1/Port:1 is not valid because a link is not a sub-component of a VLAN ID.
*/
@Beta
-public abstract class Resource {
+public interface Resource {
- private final DiscreteResource parent;
- private final ResourceId id;
+ DiscreteResource ROOT = new DiscreteResource();
- public static final DiscreteResource ROOT = new DiscreteResource();
-
- public static Resource discrete(DeviceId device) {
+ static DiscreteResource discrete(DeviceId device) {
return new DiscreteResource(ResourceId.discrete(device));
}
@@ -62,7 +56,7 @@
* @param components following components of the path. The order represents hierarchical structure of the resource.
* @return resource path instance
*/
- public static Resource discrete(DeviceId device, Object... components) {
+ static DiscreteResource discrete(DeviceId device, Object... components) {
return new DiscreteResource(ResourceId.discrete(device, components));
}
@@ -74,7 +68,7 @@
* @param components following components of the path. The order represents hierarchical structure of the resource.
* @return resource path instance
*/
- public static Resource discrete(DeviceId device, PortNumber port, Object... components) {
+ static DiscreteResource discrete(DeviceId device, PortNumber port, Object... components) {
return new DiscreteResource(ResourceId.discrete(device, port, components));
}
@@ -88,7 +82,7 @@
* an IllegalArgumentException.
* @return resource path instance
*/
- public static Resource continuous(double value, DeviceId device, Object... components) {
+ static ContinuousResource continuous(double value, DeviceId device, Object... components) {
checkArgument(components.length > 0,
"Length of components must be greater thant 0, but " + components.length);
@@ -106,40 +100,16 @@
* an IllegalArgumentException.
* @return resource path instance
*/
- public static Resource continuous(double value, DeviceId device, PortNumber port, Object... components) {
+ static ContinuousResource continuous(double value, DeviceId device, PortNumber port, Object... components) {
return new ContinuousResource(ResourceId.continuous(device, port, components), value);
}
/**
- * Creates an resource path from the specified id.
- *
- * @param id id of the path
- */
- protected Resource(ResourceId id) {
- checkNotNull(id);
-
- this.id = id;
- if (id.components.size() == 1) {
- this.parent = ROOT;
- } else {
- this.parent = new DiscreteResource(id.parent());
- }
- }
-
- // for serialization
- protected Resource() {
- this.parent = null;
- this.id = ResourceId.ROOT;
- }
-
- /**
* Returns the components of this resource path.
*
* @return the components of this resource path
*/
- public List<Object> components() {
- return id.components;
- }
+ List<Object> components();
/**
* Returns the volume of this resource.
@@ -147,7 +117,7 @@
* @return the volume of this resource
*/
// TODO: think about other naming possibilities. amount? quantity?
- public abstract <T> T volume();
+ <T> T volume();
/**
* Returns the parent resource path of this instance.
@@ -156,9 +126,7 @@
* @return the parent resource path of this instance.
* If there is no parent, empty instance will be returned.
*/
- public Optional<DiscreteResource> parent() {
- return Optional.ofNullable(parent);
- }
+ Optional<DiscreteResource> parent();
/**
* Returns a child resource path of this instance with specifying the child object.
@@ -167,11 +135,7 @@
* @param child child object
* @return a child resource path
*/
- public Resource child(Object child) {
- checkState(this instanceof DiscreteResource);
-
- return new DiscreteResource(id().child(child));
- }
+ DiscreteResource child(Object child);
/**
* Returns a child resource path of this instance with specifying a child object and
@@ -181,11 +145,7 @@
* @param value value
* @return a child resource path
*/
- public Resource child(Object child, double value) {
- checkState(this instanceof DiscreteResource);
-
- return new ContinuousResource(id.child(child), value);
- }
+ ContinuousResource child(Class<?> child, double value);
/**
* Returns the last component of this instance.
@@ -193,28 +153,12 @@
* @return the last component of this instance.
* The return value is equal to the last object of {@code components()}.
*/
- public Object last() {
- if (id.components.isEmpty()) {
- return null;
- }
- return id.components.get(id.components.size() - 1);
- }
+ Object last();
/**
* Returns the ID of this resource path.
*
* @return the ID of this resource path
*/
- public ResourceId id() {
- return id;
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(this)
- .add("id", id())
- .add("volume", volume())
- .toString();
- }
-
+ ResourceId id();
}
diff --git a/core/api/src/main/java/org/onosproject/net/newresource/ResourceId.java b/core/api/src/main/java/org/onosproject/net/newresource/ResourceId.java
index 93c4472..7638f64 100644
--- a/core/api/src/main/java/org/onosproject/net/newresource/ResourceId.java
+++ b/core/api/src/main/java/org/onosproject/net/newresource/ResourceId.java
@@ -21,11 +21,8 @@
import org.onosproject.net.PortNumber;
import java.util.Arrays;
-import java.util.Objects;
import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
/**
* Represents identifier of resource.
@@ -33,18 +30,16 @@
*/
@Beta
public abstract class ResourceId {
- static final ResourceId ROOT = new DiscreteResourceId();
+ static final DiscreteResourceId ROOT = new DiscreteResourceId();
- final ImmutableList<Object> components;
-
- static ResourceId discrete(DeviceId device, Object... components) {
+ static DiscreteResourceId discrete(DeviceId device, Object... components) {
return new DiscreteResourceId(ImmutableList.builder()
.add(device)
.add(components)
.build());
}
- static ResourceId discrete(DeviceId device, PortNumber port, Object... components) {
+ static DiscreteResourceId discrete(DeviceId device, PortNumber port, Object... components) {
return new DiscreteResourceId(ImmutableList.builder()
.add(device)
.add(port)
@@ -52,92 +47,41 @@
.build());
}
- static ResourceId continuous(DeviceId device, Object... components) {
+ static ContinuousResourceId continuous(DeviceId device, Object... components) {
Object last = components[components.length - 1];
checkArgument(last instanceof Class<?>);
- return continuous(ImmutableList.builder()
+ return new ContinuousResourceId(ImmutableList.builder()
.add(device)
.add(Arrays.copyOfRange(components, 0, components.length - 1)), (Class<?>) last);
}
- static ResourceId continuous(DeviceId device, PortNumber port, Object... components) {
+ static ContinuousResourceId continuous(DeviceId device, PortNumber port, Object... components) {
Object last = components[components.length - 1];
checkArgument(last instanceof Class<?>);
- return continuous(ImmutableList.builder()
+ return new ContinuousResourceId(ImmutableList.builder()
.add(device)
.add(port)
.add(Arrays.copyOfRange(components, 0, components.length - 1)), (Class<?>) last);
}
- private static ResourceId continuous(ImmutableList.Builder<Object> parentComponents, Class<?> last) {
- return new ContinuousResourceId(parentComponents
- .add(last.getCanonicalName())
- .build(), last.getSimpleName());
- }
-
- protected ResourceId(ImmutableList<Object> components) {
- this.components = checkNotNull(components);
- }
-
- // for serializer
- protected ResourceId() {
- this.components = ImmutableList.of();
- }
-
- // IndexOutOfBoundsException is raised when the instance is equal to ROOT
- ResourceId parent() {
- if (components.size() == 1) {
- return ROOT;
- } else {
- return new DiscreteResourceId(components.subList(0, components.size() - 1));
- }
- }
+ abstract DiscreteResourceId parent();
/**
* Returns a resource ID of a child of this resource based on the specified object.
- * If the argument is an instance of {@link Class}, this method returns an instance of
- * {@link ContinuousResourceId}. Otherwise, it returns an instance of {@link DiscreteResourceId}
- * This method only work when the receiver is {@link DiscreteResourceId}. Otherwise,
- * this method throws an exception.
+ * If the given object is a {@link Class} instance, {@link IllegalArgumentException} is thrown.
*
* @param child the last component of the child
* @return a child resource ID
*/
- public ResourceId child(Object child) {
- checkState(this instanceof DiscreteResourceId);
+ public abstract DiscreteResourceId child(Object child);
- if (child instanceof Class<?>) {
- return continuous(ImmutableList.builder().addAll(components), (Class<?>) child);
- } else {
- return new DiscreteResourceId(ImmutableList.builder()
- .addAll(components)
- .add(child)
- .build());
- }
- }
-
- @Override
- public int hashCode() {
- return components.hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null || getClass() != obj.getClass()) {
- return false;
- }
- final ResourceId other = (ResourceId) obj;
- return Objects.equals(this.components, other.components);
- }
-
- @Override
- public String toString() {
- return components.toString();
- }
-
+ /**
+ * Returns a resource ID of a child of this resource based on the specified object.
+ *
+ * @param child the last component of the child
+ * @return a child resource ID
+ */
+ public abstract ContinuousResourceId child(Class<?> child);
}
diff --git a/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java b/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java
index 7862dfc..b92db06 100644
--- a/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java
+++ b/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java
@@ -181,8 +181,6 @@
import org.onosproject.net.newresource.DiscreteResource;
import org.onosproject.net.newresource.DiscreteResourceId;
import org.onosproject.net.newresource.ResourceAllocation;
-import org.onosproject.net.newresource.ResourceId;
-import org.onosproject.net.newresource.Resource;
import org.onosproject.net.packet.DefaultOutboundPacket;
import org.onosproject.net.packet.DefaultPacketRequest;
import org.onosproject.net.packet.PacketPriority;
@@ -442,10 +440,8 @@
DefaultLinkResourceAllocations.class,
BandwidthResourceAllocation.class,
LambdaResourceAllocation.class,
- Resource.class,
DiscreteResource.class,
ContinuousResource.class,
- ResourceId.class,
DiscreteResourceId.class,
ContinuousResourceId.class,
ResourceAllocation.class,