blob: da7d346c732aac8b01a26c5b129221347e02ba35 [file] [log] [blame]
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -07001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.net.newresource;
17
18import com.google.common.annotations.Beta;
19import com.google.common.base.MoreObjects;
20import com.google.common.collect.ImmutableList;
21
22import java.util.Arrays;
Sho SHIMIZUc9546a32015-11-10 11:22:28 -080023import java.util.LinkedList;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070024import java.util.List;
25import java.util.Objects;
26import java.util.Optional;
27
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070028import static com.google.common.base.Preconditions.checkNotNull;
29
30/**
31 * An object that is used to locate a resource in a network.
32 * A ResourcePath represents a path that is hierarchical and composed of a sequence
33 * of elementary resources that are not globally identifiable. A ResourcePath can be a globally
34 * unique resource identifier.
35 *
36 * Users of this class must keep the semantics of resources regarding the hierarchical structure.
37 * For example, resource path, Link:1/VLAN ID:100, is valid, but resource path, VLAN ID:100/Link:1
38 * is not valid because a link is not a sub-component of a VLAN ID.
39 */
40@Beta
41public final class ResourcePath {
42
Sho SHIMIZUc9546a32015-11-10 11:22:28 -080043 private final ResourcePath parent;
44 private final Object last;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070045
Sho SHIMIZUba41fc12015-08-12 15:43:22 -070046 public static final ResourcePath ROOT = new ResourcePath(ImmutableList.of());
47
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070048 /**
49 * Creates an resource path from the specified components.
50 *
51 * @param components components of the path. The order represents hierarchical structure of the resource.
52 */
53 public ResourcePath(Object... components) {
54 this(Arrays.asList(components));
55 }
56
57 /**
58 * Creates an resource path from the specified components.
59 *
60 * @param components components of the path. The order represents hierarchical structure of the resource.
61 */
62 public ResourcePath(List<Object> components) {
63 checkNotNull(components);
Sho SHIMIZUc9546a32015-11-10 11:22:28 -080064 if (components.isEmpty()) {
65 this.parent = null;
66 this.last = null;
67 return;
68 }
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070069
Sho SHIMIZUc9546a32015-11-10 11:22:28 -080070 LinkedList<Object> children = new LinkedList<>(components);
71 this.last = children.pollLast();
72 this.parent = new ResourcePath(children);
73 }
74
75 /**
76 * Creates an resource path from the specified parent and child.
77 *
78 * @param parent the parent of this resource
79 * @param last a child of the parent
80 */
81 public ResourcePath(ResourcePath parent, Object last) {
82 this.parent = checkNotNull(parent);
83 this.last = checkNotNull(last);
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070084 }
85
86 // for serialization
87 private ResourcePath() {
Sho SHIMIZUc9546a32015-11-10 11:22:28 -080088 this.parent = null;
89 this.last = null;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -070090 }
91
92 /**
93 * Returns the components of this resource path.
94 *
95 * @return the components of this resource path
96 */
97 public List<Object> components() {
Sho SHIMIZUc9546a32015-11-10 11:22:28 -080098 LinkedList<Object> components = new LinkedList<>();
99
100 ResourcePath parentPath = parent;
101 while (parentPath != null) {
102 components.addFirst(last);
103 parentPath = parent.parent;
104 }
105
106 return components;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700107 }
108
109 /**
110 * Returns the parent resource path of this instance.
111 * E.g. if this path is Link:1/VLAN ID:100, the return value is the resource path for Link:1.
112 *
113 * @return the parent resource path of this instance.
114 * If there is no parent, empty instance will be returned.
115 */
116 public Optional<ResourcePath> parent() {
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800117 return Optional.ofNullable(parent);
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700118 }
119
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800120 public ResourcePath child(Object child) {
121 return new ResourcePath(this, child);
Sho SHIMIZU01120782015-08-21 15:48:43 -0700122 }
123
124 /**
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700125 * Returns the last component of this instance.
126 *
127 * @return the last component of this instance.
128 * The return value is equal to the last object of {@code components()}.
129 */
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800130 public Object last() {
131 return last;
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700132 }
133
134 @Override
135 public int hashCode() {
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800136 return Objects.hash(this.parent, this.last);
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700137 }
138
139 @Override
140 public boolean equals(Object obj) {
141 if (this == obj) {
142 return true;
143 }
144 if (!(obj instanceof ResourcePath)) {
145 return false;
146 }
147 final ResourcePath that = (ResourcePath) obj;
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800148 return Objects.equals(this.parent, that.parent)
149 && Objects.equals(this.last, that.last);
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700150 }
151
152 @Override
153 public String toString() {
154 return MoreObjects.toStringHelper(this)
Sho SHIMIZUc9546a32015-11-10 11:22:28 -0800155 .add("parent", parent)
156 .add("last", last)
Sho SHIMIZU1f5e5912015-08-10 17:00:00 -0700157 .toString();
158 }
159}