ONOS-5863, ONOS-5804 DynamicConfig store and service implementation(create and read supported)
Change-Id: I299a27afe46b87f98d4af79643732e2f1bdc2010
diff --git a/apps/config/src/main/java/org/onosproject/config/model/DataNode.java b/apps/config/src/main/java/org/onosproject/config/model/DataNode.java
index 5c43304..f0a94f0 100755
--- a/apps/config/src/main/java/org/onosproject/config/model/DataNode.java
+++ b/apps/config/src/main/java/org/onosproject/config/model/DataNode.java
@@ -15,102 +15,17 @@
*/
package org.onosproject.config.model;
-import java.util.LinkedHashMap;
-
/**
- * Hollow definition of DataNode for ConfigService APIs.
+ * Abstraction of an entity which represents data tree node. Information
+ * exchange between YANG runtime, protocol and store will be based on this
+ * node, agnostic of schema.
*/
-public interface DataNode {
- //will remove this when the corresponding changes in onos-yang-tools become available
+public abstract class DataNode {
- /**
- * Builder for DataNode.
- */
- interface Builder<V> {
- /**
- * clones a base Data node obj to a new one.
- *
- * @param base base DataNode obj to be cloned
- * @return a DataNode builder
- */
- Builder addBaseObj(DataNode base);
- /**
- * Adds the value of the instance node.
- *
- * @param key of the node
- * @return a DataNode builder
- */
- Builder addKey(NodeKey key);
- /**
- * Adds the value of the instance node.
- *
- * @param type of the node
- * @return a DataNode builder
- */
- Builder addType(DataNode.Type type);
- /**
- * Adds the value of the leaf node.
- *
- * @param value at the node
- * @return a DataNode builder
- */
- Builder addValue(String value);
-
- /**
- * Adds children to the children field.
- *
- * @param children to be added
- * @return a DataNode builder
- */
- //Builder addChildren(LinkedHashMap<NodeKey, DataNode> children);
-
- /**
- * Builds an immutable DataNode entity.
- *
- * @return DataNode
- */
- DataNode build();
- }
-
- /**
- * Returns the children if DataNode contains an inner node.
- *
- * @return LinkedHashMap of children for an inner node, null for a leaf node
- */
- LinkedHashMap<NodeKey, DataNode> children();
-
- /**
- * Returns the value at the leaf node as a string.
- *
- * @return value at the leaf node as a string, null if it is an innernode
- */
- String value();
-
- /**
- * Returns the node schema identifier.
- *
- * @return node schema identifier
- */
- SchemaIdentifier identifier();
-
- /**
- * Returns the type of node.
- *
- * @return node type
- */
- Type type();
-
- /**
- * Returns the key to identify a branching node.
- *
- * @return key to identify a branching node
- */
- NodeKey key();
-
- /**
+ /*
* Represents type of node in data store.
*/
- enum Type {
+ public enum Type {
/**
* Single instance node.
@@ -132,4 +47,237 @@
*/
MULTI_INSTANCE_LEAF_VALUE_NODE
}
+
+ /**
+ * Type of node in data store.
+ */
+ protected Type type;
+
+ /**
+ * Identifies a node uniquely among its siblings.
+ */
+ protected NodeKey key;
+
+ /**
+ * Returns the type of node.
+ *
+ * @return node type
+ */
+ public Type type() {
+ return type;
+ }
+
+ /**
+ * Returns the key to identify a branching node.
+ *
+ * @return key to identify a branching node
+ */
+ public NodeKey key() {
+ return key;
+ }
+
+ /**
+ * Creates an instance of data node.
+ *
+ * @param builder data node builder
+ */
+ protected DataNode(Builder builder) {
+ type = builder.type;
+ key = builder.key;
+ }
+
+ /**
+ * Returns data node builder for a given data node.
+ * It contains all the attributes from the data node. It is to provide
+ * mutability of data node using builder pattern.
+ *
+ * @return data node builder
+ */
+ public abstract Builder copyBuilder();
+
+ /**
+ * Represents the implementation of data node builder class.
+ *
+ * @param <B> type of data node builder
+ */
+ public abstract static class Builder<B extends Builder<B>> {
+
+ /**
+ * Type of node in data store.
+ */
+ protected Type type;
+
+ /**
+ * Identifies a node uniquely among its siblings.
+ */
+ protected NodeKey key;
+
+ /**
+ * Node key builder.
+ */
+ protected NodeKey.NodeKeyBuilder keyBuilder;
+
+ /**
+ * Parent data node.
+ */
+ protected InnerNode.Builder parent;
+
+ /**
+ * Creates an instance of data node builder.
+ */
+ protected Builder() {
+ }
+
+ /**
+ * Creates an instance of data node builder using old data node.
+ *
+ * @param node data node which
+ */
+ protected Builder(DataNode node) {
+ type = node.type;
+ key = node.key;
+ }
+
+ /**
+ * Sets node key in builder object.
+ * when serializers have an instance of key present with them they can
+ * directly set the key value using this method.
+ *
+ * @param key node key identifier
+ * @return data node builder object
+ */
+ public B key(NodeKey key) {
+ this.key = key;
+ return (B) this;
+ }
+
+ /**
+ * Sets parent node's builder.
+ *
+ * @param node parent node builder
+ * @return builder object
+ */
+ protected B parent(InnerNode.Builder node) {
+ parent = node;
+ return (B) this;
+ }
+
+ /**
+ * Sets node type in builder object.
+ *
+ * @param type node type
+ * @return data node builder
+ */
+ public B type(Type type) {
+ this.type = type;
+ return (B) this;
+ }
+
+ /**
+ * Creates a child builder of type inner node and set a back reference
+ * of parent node. it is used while creating a data tree.
+ *
+ * @param name name of inner node
+ * @param nameSpace namespace of inner node
+ * @return child node builder
+ */
+ public abstract InnerNode.Builder createChildBuilder(
+ String name, String nameSpace);
+
+ /**
+ * Creates a child build of type leaf node and set a back reference
+ * of parent node. it is used while creating a data tree. the value
+ * of leaf is set while creation.
+ *
+ * @param name name of leaf node
+ * @param nameSpace namespace of leaf node
+ * @param value value for leaf node
+ * @return child node builder
+ */
+ public abstract LeafNode.Builder createChildBuilder(
+ String name, String nameSpace, Object value);
+
+ /**
+ * Deletes child node for a given node key from parent node.
+ * <p>
+ * for deleting a node from data tree , caller should parse resource
+ * identifier to reach to the child node. while parsing the resource
+ * identifier caller need to create a new data node using copy
+ * builder. this copy builder can be used further to create child
+ * nodes copy builders.
+ *
+ * @param key node key for child node
+ * @return data node builder
+ */
+ public abstract InnerNode.Builder deleteChild(NodeKey key);
+
+ /**
+ * Returns a child node builder for a given node key. it contains all
+ * the attribute of child node. it is used to modify the data tree
+ * while delete or update operations.
+ * <p>
+ * this method provides copy builder of child node when a
+ * update/delete request comes. it sets a back reference of parent
+ * node as well in child node's copy builder.
+ *
+ * @param key data node key
+ * @return child node
+ */
+ public abstract InnerNode.Builder getChildBuilder(NodeKey key);
+
+
+ /**
+ * Add key leaf for list node key. It can be used while handling a
+ * list node when in your yang file you have multiple key leaves.
+ * <p>
+ * this method is used for adding multiple key leaves in you list
+ * node. these keys will be added to key builder which is built while
+ * while node building. To use this method caller should know about
+ * schema of list and key leaves.
+ *
+ * @param name name of leaf node
+ * @param nameSpace namespace of leaf node
+ * @param val value of leaf
+ * @return data node builder
+ */
+ public abstract InnerNode.Builder addKeyLeaf(String name, String nameSpace,
+ Object val);
+
+ /**
+ * Add key value to leaf list key. this can be used while handling a
+ * leaf list where you need to add multiple values.
+ *
+ * @param val value
+ * @return data node builder
+ */
+ public abstract LeafNode.Builder addLeafListValue(Object val);
+
+ /**
+ * Builds data node.
+ *
+ * @return data node
+ */
+ public abstract DataNode build();
+
+ /**
+ * Returns parent node builder after building and adding the child
+ * node to parent's child node map.
+ * <p>
+ * This method is used when caller has reached to the depth of the
+ * subtree and then he wants to go back to its parent node so he
+ * should build the node and then it should add it to parent node's
+ * map. this method provides both the functionalities of build and
+ * add to parent . Also it returns back the parent pointer so caller
+ * can do further operations on data tree.
+ *
+ * @return parent's builder object
+ */
+ public InnerNode.Builder exitNode() {
+ if (parent != null) {
+ parent.addNode(build());
+ }
+ return parent;
+ }
+ }
}
+
diff --git a/apps/config/src/main/java/org/onosproject/config/model/DefaultDataNode.java b/apps/config/src/main/java/org/onosproject/config/model/DefaultDataNode.java
deleted file mode 100755
index 44b8c1e..0000000
--- a/apps/config/src/main/java/org/onosproject/config/model/DefaultDataNode.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright 2016-present 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.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.config.model;
-
-import java.util.LinkedHashMap;
-
-/**
- * Representation of an instance node in the Dynamic config store.
- */
-public final class DefaultDataNode implements DataNode {
- DataNode.Type type;
- NodeKey key;
- //Object value;
- String value;
- LinkedHashMap<NodeKey, DataNode> children;
-
- /**
- * Creates a new DefaultDataNode.
- *
- * @param key node key
- * @param type of the node
- * @param value of leaf node
- * @param children of the inner node
- */
- private DefaultDataNode(NodeKey key, DataNode.Type type,
- String value, LinkedHashMap<NodeKey, DataNode> children) {
- this.type = type;
- this.key = key;
- this.value = value;
- this.children = children;
- }
- /**
- *
- */
- /**
- * Creates a new DefaultDataNode.
- *
- * @param node to be cloned
- * @param value of leaf node
- */
- private DefaultDataNode(DataNode node, String value) {
- this.type = node.type();
- this.key = node.key();
- this.value = value;
- this.children = null;
- }
- /**
- * Creates a new DefaultDataNode.
- *
- * @param node to be cloned
- * @param children to be added
- */
- private DefaultDataNode(DataNode node, LinkedHashMap<NodeKey, DataNode> children) {
- this.type = node.type();
- this.key = node.key();
- this.value = null;
- this.children = children;
- }
-
- @Override
- public LinkedHashMap<NodeKey, DataNode> children() {
- return this.children;
- }
-
- @Override
- public String value() {
- return value;
- //return value.toString();
- }
-
-
- /**
- * Creates and returns a new builder instance.
- *
- * @return new builder
- */
- public static Builder builder() {
- return new Builder();
- }
-
- public static final class Builder<V> implements DataNode.Builder {
-
- private DataNode.Type type;
- private NodeKey key;
- //Object value;
- private String value;
- private LinkedHashMap<NodeKey, DataNode> children;
-
- private Builder() {
- this.type = null;
- this.key = null;
- this.value = null;
- this.children = null;
- }
-
- @Override
- public Builder addBaseObj(DataNode base) {
- this.key = base.key();
- this.type = base.type();
- this.value = base.value();
- this.children = base.children();
- return this;
- }
-
- @Override
- public Builder addKey(NodeKey key) {
- this.key = key;
- return this;
- }
-
- @Override
- public Builder addType(DataNode.Type type) {
- this.type = type;
- return this;
- }
-
- @Override
- public Builder addValue(String value) {
- this.value = value;
- return this;
- }
-
- //@Override
- public Builder addChildren(LinkedHashMap<NodeKey, DataNode> children) {
- this.children = children;
- return this;
- }
-
- @Override
- public DataNode build() {
- return new DefaultDataNode(this.key, this.type, this.value, this.children);
- }
- }
-
-
- @Override
- public SchemaIdentifier identifier() {
- return this.key.schemaId;
- }
-
- @Override
- public Type type() {
- return this.type;
- }
-
- @Override
- public NodeKey key() {
- return this.key;
- }
-}
\ No newline at end of file
diff --git a/apps/config/src/main/java/org/onosproject/config/model/DefaultResourceIdentifier.java b/apps/config/src/main/java/org/onosproject/config/model/DefaultResourceIdentifier.java
deleted file mode 100755
index 63aba40..0000000
--- a/apps/config/src/main/java/org/onosproject/config/model/DefaultResourceIdentifier.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright 2016-present 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.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.config.model;
-
-/**
- * Created by sdn on 12/15/16.
- */
-public class DefaultResourceIdentifier<V> implements ResourceIdentifier {
- NodeKey key;
- ResourceIdentifier next;
-
- public DefaultResourceIdentifier(String nm, String nmspc) {
- this.key = new NodeKey(nm, nmspc);
- this.next = null;
- }
-
- public DefaultResourceIdentifier(ResourceIdentifier parent, NodeKey ckey) {
- this.key = parent.nodeKey();
- //new NodeKey(parent.nodeKey().schemaId.name, parent.nodeKey().schemaId.nameSpace);
- this.next = new DefaultResourceIdentifier(ckey);
- }
-
- public DefaultResourceIdentifier(ResourceIdentifier parent, ResourceIdentifier child) {
- this.key = parent.nodeKey();
- this.next = child;
- }
-
- public DefaultResourceIdentifier(NodeKey nkey) {
- this.key = nkey;
- this.next = null;
- }
-
- /*public void setChild(NodeKey ckey) {
- this.next = new DefaultResourceIdentifier(ckey);
- }*/
-
- @Override
- public NodeKey nodeKey() {
- return this.key;
- }
-
- @Override
- public ResourceIdentifier descendentIdentifier() {
- return this.next;
- }
-
- @Override
- public String getBase() {
- return this.key.schemaId.name.concat("#").concat(this.key.schemaId.nameSpace);
- }
-
- @Override
- public String asString() {
- String base = getBase();
- ResourceIdentifier desc = next;
- while (desc != null) {
- base.concat(".").concat(desc.getBase());
- desc = desc.descendentIdentifier();
- }
- return base;
- }
-}
\ No newline at end of file
diff --git a/apps/config/src/main/java/org/onosproject/config/model/InnerNode.java b/apps/config/src/main/java/org/onosproject/config/model/InnerNode.java
new file mode 100644
index 0000000..2a0dfee
--- /dev/null
+++ b/apps/config/src/main/java/org/onosproject/config/model/InnerNode.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright 2016-present 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.config.model;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import static org.onosproject.config.model.ModelConstants.LEAF_IS_TERMINAL;
+
+/**
+ * Abstraction of an entity which represents an inner node in data store.
+ */
+public final class InnerNode extends DataNode {
+
+ /**
+ * Map containing info of all child data nodes with respect to their node
+ * keys.
+ */
+ private Map<NodeKey, DataNode> childNodes = new LinkedHashMap<>();
+
+ /**
+ * Returns the children nodes to the current node.
+ * Children nodes are identified based on the node key.
+ *
+ * @return read only linked map of children nodes
+ */
+ public Map<NodeKey, DataNode> childNodes() {
+ return childNodes;
+ }
+
+ /**
+ * Creates an instance of inner node.
+ *
+ * @param builder inner node builder
+ */
+ public InnerNode(Builder builder) {
+ super(builder);
+ childNodes = builder.childNodes;
+ }
+
+ /**
+ * Returns inner node builder instance.
+ *
+ * @param name name of node
+ * @param nameSpace namespace of node
+ * @return inner node builder instance
+ */
+ public static Builder builder(String name, String nameSpace) {
+ return new Builder(name, nameSpace);
+ }
+
+ /**
+ * Returns inner node copy builder.
+ *
+ * @return inner node copy builder
+ */
+ @Override
+ public Builder copyBuilder() {
+ return new Builder(this);
+ }
+
+ /**
+ * Builder with get and set functions to build inner node,
+ * builder will be used both to create inner node from scratch or from a
+ * given inner node.
+ */
+ public static class Builder extends DataNode.Builder<Builder> {
+
+ /**
+ * Map containing info of all child data nodes with respect to their
+ * node keys.
+ */
+ private Map<NodeKey, DataNode> childNodes = new LinkedHashMap<>();
+
+ public Builder() {
+ }
+ /**
+ * Creates an instance of data node builder.
+ *
+ * @param name name of node
+ * @param namespace namespace of node
+ */
+ public Builder(String name, String namespace) {
+ keyBuilder = NodeKey.builder().schemaId(name, namespace);
+ }
+
+ /**
+ * Creates an instance of inner node builder.
+ *
+ * @param node old inner node
+ */
+ public Builder(InnerNode node) {
+ super(node);
+ childNodes = node.childNodes;
+ }
+
+ /**
+ * Adds node to the builder.
+ *
+ * @param node node to be added
+ * @return inner node builder
+ */
+ public Builder addNode(DataNode node) {
+ childNodes.put(node.key(), node);
+ return this;
+ }
+
+ /**
+ * Builds a inner node object.
+ *
+ * @return inner node
+ */
+ @Override
+ public InnerNode build() {
+ if (type == null) {
+ throw new IllegalStateException("node should have a type.");
+ }
+ if (key == null) {
+ key = keyBuilder.build();
+ }
+ return new InnerNode(this);
+ }
+
+ @Override
+ public InnerNode.Builder createChildBuilder(String name, String nameSpace) {
+ return InnerNode.builder(name, nameSpace)
+ .parent(this);
+ }
+
+ @Override
+ public LeafNode.Builder createChildBuilder(String name, String nameSpace,
+ Object value) {
+ return LeafNode.builder(name, nameSpace)
+ .parent(this)
+ .value(value);
+ }
+
+ @Override
+ public InnerNode.Builder deleteChild(NodeKey key) {
+ childNodes.remove(key);
+ return this;
+ }
+
+ @Override
+ public Builder getChildBuilder(NodeKey nodeKey) {
+ DataNode node = childNodes.get(nodeKey);
+ if (node == null) {
+ throw new IllegalArgumentException(
+ "Invalid key: no child nodes found for given key: " +
+ nodeKey);
+ }
+ return (Builder) node.copyBuilder().parent(this);
+ }
+
+ @Override
+ public Builder addKeyLeaf(String name, String nameSpace, Object val) {
+ ListKey.ListKeyBuilder listKeyBuilder;
+ if (!(keyBuilder instanceof ListKey.ListKeyBuilder)) {
+ if (keyBuilder instanceof LeafListKey.LeafListKeyBuilder) {
+ throw new ModelException(LEAF_IS_TERMINAL);
+ }
+
+ listKeyBuilder = new ListKey.ListKeyBuilder(keyBuilder);
+ } else {
+ listKeyBuilder = (ListKey.ListKeyBuilder) keyBuilder;
+ }
+
+ listKeyBuilder.addKeyLeaf(name, nameSpace, val);
+ keyBuilder = listKeyBuilder;
+ return this;
+ }
+
+ @Override
+ public LeafNode.Builder addLeafListValue(Object val) {
+ throw new IllegalStateException("node is not of leaf list type.");
+ }
+ }
+}
diff --git a/apps/config/src/main/java/org/onosproject/config/model/KeyLeaf.java b/apps/config/src/main/java/org/onosproject/config/model/KeyLeaf.java
new file mode 100644
index 0000000..1f21687
--- /dev/null
+++ b/apps/config/src/main/java/org/onosproject/config/model/KeyLeaf.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2017-present 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.config.model;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static java.util.Objects.hash;
+
+/**
+ * Represents the List's key leaf value.
+ */
+public class KeyLeaf implements Cloneable {
+
+ private SchemaId leafSchema;
+ private Object leafVal;
+
+ private KeyLeaf() {
+ }
+
+ /**
+ * Constructs a key leaf with all the identifier and value initialized.
+ *
+ * @param name name of the leaf
+ * @param nameSpace namespace of leaf
+ * @param leafVal value of leaf
+ */
+ public KeyLeaf(String name, String nameSpace, Object leafVal) {
+ leafSchema = new SchemaId(name, nameSpace);
+ this.leafVal = leafVal;
+ }
+
+ /**
+ * Creates and returns a deep copy of this object.
+ *
+ * @return cloned copy
+ * @throws CloneNotSupportedException if the object's class does not
+ * support the {@code Cloneable} interface
+ */
+ public KeyLeaf clone() throws CloneNotSupportedException {
+ KeyLeaf clonedLeaf = (KeyLeaf) super.clone();
+ clonedLeaf.leafSchema = leafSchema.clone();
+ return clonedLeaf;
+ }
+
+ /**
+ * Returns the node schema schemaId.
+ *
+ * @return node schema schemaId
+ */
+ public SchemaId leafSchema() {
+ return leafSchema;
+ }
+
+ /**
+ * Returns value contained in leaf node.
+ *
+ * @return value contained in leaf node
+ */
+ public Object leafValue() {
+ return leafVal;
+ }
+
+ /**
+ * Returns value as string, for usage in serializers.
+ *
+ * @return string representation of value
+ */
+ public String leafValAsString() {
+ return leafVal.toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return hash(leafSchema, leafVal);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+
+ KeyLeaf that = (KeyLeaf) obj;
+ return Objects.equals(leafSchema, that.leafSchema) &&
+ Objects.equals(leafVal, that.leafVal);
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(getClass())
+ .add("schemaId", leafSchema)
+ .add("leafValue", leafVal)
+ .toString();
+ }
+}
diff --git a/apps/config/src/main/java/org/onosproject/config/model/LeafListKey.java b/apps/config/src/main/java/org/onosproject/config/model/LeafListKey.java
new file mode 100644
index 0000000..c532ae2
--- /dev/null
+++ b/apps/config/src/main/java/org/onosproject/config/model/LeafListKey.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2017-present 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.config.model;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Representation of an entity which identifies a uniquely branching
+ * leaf-list entry corresponding to a multi instance leaf schema.
+ */
+public final class LeafListKey extends NodeKey<LeafListKey>
+ implements Comparable<LeafListKey> {
+ private Object val;
+
+ /**
+ * Create object from builder.
+ *
+ * @param builder initialized builder
+ */
+ private LeafListKey(LeafListKeyBuilder builder) {
+ super(builder);
+ val = builder.val;
+ }
+
+ /**
+ * Returns value of node, this is only valid for multi-instance leaf, node.
+ *
+ * @return value maintained in the node
+ */
+ Object value() {
+ return val;
+ }
+
+ /**
+ * Returns value as string, for usage in serializers.
+ *
+ * @return string representation of value
+ */
+ String asString() {
+ return val.toString();
+ }
+
+ /**
+ * Creates and returns a deep copy of this object.
+ *
+ * @return cloned copy
+ * @throws CloneNotSupportedException if the object's class does not
+ * support the {@code Cloneable} interface
+ */
+ public LeafListKey clone() throws CloneNotSupportedException {
+ return (LeafListKey) super.clone();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(schemaId, val);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+
+ if (!getClass().equals(obj.getClass())) {
+ return false;
+ }
+
+ LeafListKey that = (LeafListKey) obj;
+ return Objects.equals(val, that.val) &&
+ Objects.equals(schemaId, that.schemaId);
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(getClass())
+ .add("value", val)
+ .toString();
+ }
+
+ /**
+ * Represents Leaf list key builder.
+ */
+ public static class LeafListKeyBuilder
+ extends NodeKeyBuilder<LeafListKeyBuilder> {
+
+ private Object val;
+
+ /**
+ * constructor used while constructing the key from scratch.
+ */
+ public LeafListKeyBuilder() {
+
+ }
+
+ /**
+ * Adds the value for for the leaf list node identifier.
+ *
+ * @param val leaf list value
+ * @return LeafListKeyBuilder
+ */
+ LeafListKeyBuilder value(Object val) {
+ this.val = val;
+ return this;
+ }
+
+ /**
+ * Creates a leaf list entry identifier.
+ *
+ * @return leaf list entry identifier
+ */
+ public LeafListKey build() {
+ return new LeafListKey(this);
+ }
+ }
+}
diff --git a/apps/config/src/main/java/org/onosproject/config/model/LeafNode.java b/apps/config/src/main/java/org/onosproject/config/model/LeafNode.java
new file mode 100644
index 0000000..44319c8
--- /dev/null
+++ b/apps/config/src/main/java/org/onosproject/config/model/LeafNode.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2016-present 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.config.model;
+
+import static org.onosproject.config.model.ModelConstants.NON_KEY_LEAF;
+
+/**
+ * Abstraction of an entity which represents leaf data tree node.
+ */
+public final class LeafNode extends DataNode {
+
+ /**
+ * Leaf node value.
+ */
+ private Object value;
+
+ /**
+ * Returns value contained in leaf node.
+ *
+ * @return value contained in leaf node
+ */
+ public Object value() {
+ return value;
+ }
+
+ /**
+ * Returns value as string, for usage in serializers.
+ *
+ * @return string representation of value
+ */
+ public String asString() {
+ return String.valueOf(value);
+ }
+
+ /**
+ * Creates an instance of leaf node.
+ *
+ * @param builder leaf node builder
+ */
+ public LeafNode(Builder builder) {
+ super(builder);
+ value = builder.value;
+ }
+
+ /**
+ * Returns data node builder instance.
+ *
+ * @param name name of node
+ * @param nameSpace namespace of node
+ * @return data node builder instance
+ */
+ public static Builder builder(String name, String nameSpace) {
+ return new Builder(name, nameSpace);
+ }
+
+ /**
+ * Returns data node copy builder.
+ *
+ * @return data node copy builder
+ */
+ @Override
+ public Builder copyBuilder() {
+ return new Builder(this);
+ }
+
+ /**
+ * Builder with get and set functions to build leaf node,
+ * builder will be used both to create leaf node from scratch or from a
+ * given leaf node.
+ */
+ public static final class Builder extends DataNode.Builder<Builder> {
+
+ /**
+ * Leaf node value.
+ */
+ private Object value;
+
+ public Builder() {
+ }
+
+ /**
+ * Creates an instance of data node builder.
+ *
+ * @param name name of node
+ * @param namespace namespace of node
+ */
+ public Builder(String name, String namespace) {
+ keyBuilder = NodeKey.builder().schemaId(name, namespace);
+ }
+
+ /**
+ * Creates an instance of leaf node copy builder.
+ *
+ * @param node old leaf node
+ */
+ public Builder(LeafNode node) {
+ super(node);
+ value = node.value;
+ }
+
+ /**
+ * Sets value of leaf node builder.
+ *
+ * @param value value
+ * @return leaf node builder
+ */
+ public Builder value(Object value) {
+ this.value = value;
+ return this;
+ }
+
+ @Override
+ public InnerNode.Builder createChildBuilder(String name, String nameSpace) {
+ throw new IllegalStateException("leaf node can't have a child " +
+ "node");
+ }
+
+ @Override
+ public LeafNode.Builder createChildBuilder(String name, String nameSpace,
+ Object value) {
+ throw new IllegalStateException("leaf node can't have a child " +
+ "node");
+ }
+
+ @Override
+ public InnerNode.Builder deleteChild(NodeKey key) {
+ throw new IllegalStateException("leaf node can't have a child " +
+ "node");
+ }
+
+ @Override
+ public InnerNode.Builder getChildBuilder(NodeKey key) {
+ throw new IllegalStateException("leaf node can't have a child " +
+ "node");
+ }
+
+
+ @Override
+ public InnerNode.Builder addKeyLeaf(String name, String nameSpace, Object val) {
+ throw new IllegalStateException("leaf node can't have a key " +
+ "leaves node");
+ }
+
+ @Override
+ public Builder addLeafListValue(Object val) {
+ LeafListKey.LeafListKeyBuilder leafListKeyBuilder;
+ if (!(keyBuilder instanceof LeafListKey.LeafListKeyBuilder)) {
+ if (keyBuilder instanceof ListKey.ListKeyBuilder) {
+ throw new ModelException(NON_KEY_LEAF);
+ }
+
+ leafListKeyBuilder = new LeafListKey.LeafListKeyBuilder();
+ NodeKey key = keyBuilder.build();
+ leafListKeyBuilder.schemaId(key.schemaId());
+ } else {
+ leafListKeyBuilder = (LeafListKey.LeafListKeyBuilder) keyBuilder;
+ }
+
+ leafListKeyBuilder.value(val);
+ keyBuilder = leafListKeyBuilder;
+ return this;
+ }
+
+ /**
+ * Builds a leaf node object.
+ *
+ * @return leaf node
+ */
+ @Override
+ public LeafNode build() {
+ if (type == null) {
+ throw new IllegalStateException("node should have a type.");
+ }
+ if (key == null) {
+ key = keyBuilder.build();
+ }
+ return new LeafNode(this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/apps/config/src/main/java/org/onosproject/config/model/ListKey.java b/apps/config/src/main/java/org/onosproject/config/model/ListKey.java
new file mode 100644
index 0000000..617efaf
--- /dev/null
+++ b/apps/config/src/main/java/org/onosproject/config/model/ListKey.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2017-present 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.config.model;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Represents an entity which identifies a unique branching node
+ * corresponding to a multi instance schema definition.
+ */
+public final class ListKey extends NodeKey<ListKey> implements Comparable<ListKey> {
+
+ private List<KeyLeaf> keyLeafs;
+
+ /**
+ * Create object from builder.
+ *
+ * @param builder initialized builder
+ */
+ private ListKey(ListKeyBuilder builder) {
+ super(builder);
+ keyLeafs = builder.keyLeafs;
+ }
+
+ /**
+ * Returns the list of key leaf nodes of a multi instance node, which
+ * uniquely identifies the branching node entry corresponding to a multi
+ * instance schema definition.
+ *
+ * @return List of key leaf nodes
+ */
+ List<KeyLeaf> keyLeafs() {
+ return keyLeafs;
+ }
+
+ /**
+ * Creates and returns a deep copy of this object.
+ *
+ * @return cloned copy
+ * @throws CloneNotSupportedException if the object's class does not
+ * support the {@code Cloneable} interface
+ */
+ public ListKey clone() throws CloneNotSupportedException {
+ ListKey clonedListKey = (ListKey) super.clone();
+ List<KeyLeaf> clonedKeyLeafs = new LinkedList<>();
+ for (KeyLeaf leaf : keyLeafs) {
+ clonedKeyLeafs.add(leaf.clone());
+ }
+ clonedListKey.keyLeafs = clonedKeyLeafs;
+ return clonedListKey;
+ }
+
+ public int compareTo(ListKey o) {
+ //TODO: implement me
+ return 0;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(schemaId, keyLeafs);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+
+ if (!getClass().equals(obj.getClass())) {
+ return false;
+ }
+
+ ListKey that = (ListKey) obj;
+ List<KeyLeaf> thatList = that.keyLeafs;
+ return keyLeafs.size() == thatList.size() &&
+ keyLeafs.containsAll(thatList) &&
+ Objects.equals(schemaId, that.schemaId);
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(getClass())
+ .add("value", keyLeafs)
+ .toString();
+ }
+
+ /**
+ * Represents list key builder.
+ */
+ public static class ListKeyBuilder extends NodeKeyBuilder<ListKeyBuilder> {
+ private List<KeyLeaf> keyLeafs = new LinkedList<>();
+
+ /**
+ * used to construct the key from scratch.
+ */
+ public ListKeyBuilder() {
+ }
+
+ /**
+ * used to construct a key from an existing node key.
+ *
+ * @param base existing node key
+ */
+ public ListKeyBuilder(NodeKeyBuilder base) {
+ super(base);
+ }
+
+ /**
+ * Adds the key leaf for the list resource.
+ *
+ * @param name key leaf name
+ * @param nameSpace key laef namespace
+ * @param val value of key
+ */
+ void addKeyLeaf(String name, String nameSpace, Object val) {
+ KeyLeaf keyLeaf = new KeyLeaf(name, nameSpace, val);
+ keyLeafs.add(keyLeaf);
+ }
+
+ /**
+ * Creates the list key object.
+ *
+ * @return list key
+ */
+ public ListKey build() {
+ return new ListKey(this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/apps/config/src/main/java/org/onosproject/config/model/SchemaIdentifier.java b/apps/config/src/main/java/org/onosproject/config/model/ModelConstants.java
old mode 100755
new mode 100644
similarity index 62%
rename from apps/config/src/main/java/org/onosproject/config/model/SchemaIdentifier.java
rename to apps/config/src/main/java/org/onosproject/config/model/ModelConstants.java
index 20ce4cb..532de78
--- a/apps/config/src/main/java/org/onosproject/config/model/SchemaIdentifier.java
+++ b/apps/config/src/main/java/org/onosproject/config/model/ModelConstants.java
@@ -16,13 +16,14 @@
package org.onosproject.config.model;
/**
- * Created by sdn on 12/15/16.
+ * Constants used in model package.
*/
-public class SchemaIdentifier {
- String name;
- String nameSpace;
- SchemaIdentifier(String nm, String nmspc) {
- this.name = nm;
- this.nameSpace = nmspc;
+final class ModelConstants {
+ private ModelConstants() {
+
}
+ static final String INCOMPLETE_SCHEMA_INFO = "Schema info is not complete";
+ static final String LEAF_IS_TERMINAL = "Leaf must be the terminal node";
+ static final String NON_KEY_LEAF = "Leaf list is not a key of list";
+ static final String NO_KEY_SET = "Resource Identifier is empty";
}
diff --git a/apps/config/src/main/java/org/onosproject/config/model/ModelException.java b/apps/config/src/main/java/org/onosproject/config/model/ModelException.java
new file mode 100755
index 0000000..f2f6459
--- /dev/null
+++ b/apps/config/src/main/java/org/onosproject/config/model/ModelException.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2016-present 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.config.model;
+
+/**
+ * Exceptions for use by the {@code DynamicConfigService}.
+ */
+public class ModelException extends RuntimeException {
+
+ /**
+ * Constructs a new runtime exception with no error message.
+ */
+ public ModelException() {
+ super();
+ }
+
+ /**
+ * Constructs a new runtime exception with the given error message.
+ *
+ * @param message error message
+ */
+ public ModelException(String message) {
+ super(message);
+ }
+}
\ No newline at end of file
diff --git a/apps/config/src/main/java/org/onosproject/config/model/NodeKey.java b/apps/config/src/main/java/org/onosproject/config/model/NodeKey.java
index 9b462a0..18919e3 100755
--- a/apps/config/src/main/java/org/onosproject/config/model/NodeKey.java
+++ b/apps/config/src/main/java/org/onosproject/config/model/NodeKey.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-present Open Networking Laboratory
+ * Copyright 2017-present 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.
@@ -13,15 +13,154 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.onosproject.config.model;
-/**
- * Created by sdn on 12/15/16.
- */
-public class NodeKey {
- SchemaIdentifier schemaId;
+import java.util.Objects;
- public NodeKey(String nm, String nmspc) {
- this.schemaId = new SchemaIdentifier(nm, nmspc);
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.Objects.hash;
+import static org.onosproject.config.model.ModelConstants.INCOMPLETE_SCHEMA_INFO;
+
+/**
+ * Abstraction of an entity which identifies a node uniquely among its
+ * siblings.
+ */
+public class NodeKey<E extends NodeKey> implements Comparable<E>, Cloneable {
+
+ protected SchemaId schemaId;
+
+ /**
+ * Create object from builder.
+ *
+ * @param builder initialized builder
+ */
+ protected NodeKey(NodeKeyBuilder builder) {
+ schemaId = builder.schemaId;
+ }
+
+ /**
+ * Returns node key builder.
+ *
+ * @return node key builder
+ */
+ public static NodeKeyBuilder builder() {
+ return new NodeKeyBuilder();
+ }
+
+ /**
+ * Returns the schema identifier as minimal key required to identify a
+ * branching node.
+ *
+ * @return schema identifier of a key
+ */
+ public SchemaId schemaId() {
+ return schemaId;
+ }
+
+ @Override
+ public int compareTo(NodeKey o) {
+ checkNotNull(o);
+ return schemaId.compareTo(o.schemaId());
+ }
+
+ @Override
+ public int hashCode() {
+ return hash(schemaId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+
+ if (!getClass().equals(obj.getClass())) {
+ return false;
+ }
+
+ NodeKey that = (NodeKey) obj;
+ return Objects.equals(schemaId, that.schemaId);
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(getClass())
+ .add("schemaId", schemaId)
+ .toString();
+ }
+
+ /**
+ * Creates and returns a deep copy of this object.
+ *
+ * @return cloned copy
+ * @throws CloneNotSupportedException if the object's class does not
+ * support the {@code Cloneable} interface
+ */
+ public NodeKey clone() throws CloneNotSupportedException {
+ NodeKey clonedKey = (NodeKey) super.clone();
+ clonedKey.schemaId = schemaId.clone();
+ return clonedKey;
+ }
+
+ /**
+ * Builder for node key.
+ *
+ * @param <B> node key type
+ */
+ public static class NodeKeyBuilder<B extends NodeKeyBuilder<B>> {
+ private SchemaId schemaId;
+
+ /**
+ * Create the node key from scratch.
+ */
+ public NodeKeyBuilder() {
+ }
+
+ /**
+ * Support the derived object to inherit from existing node key builder.
+ *
+ * @param base existing node key builder
+ */
+ protected NodeKeyBuilder(NodeKeyBuilder base) {
+ checkNotNull(base.schemaId, INCOMPLETE_SCHEMA_INFO);
+ schemaId = base.schemaId;
+ }
+
+ /**
+ * set the schema identifier.
+ *
+ * @param schema schema identifier
+ * @return current builder
+ */
+ public B schemaId(SchemaId schema) {
+ schemaId = schema;
+ return (B) this;
+ }
+
+ /**
+ * set the schema identifier.
+ *
+ * @param name name of the node
+ * @param nameSpace name space of the node
+ * @return current builder
+ */
+ public B schemaId(String name, String nameSpace) {
+ schemaId = new SchemaId(name, nameSpace);
+ return (B) this;
+ }
+
+ /**
+ * construct the node key.
+ *
+ * @return node key
+ */
+ public NodeKey build() {
+ checkNotNull(schemaId.name(), INCOMPLETE_SCHEMA_INFO);
+ checkNotNull(schemaId.namespace(), INCOMPLETE_SCHEMA_INFO);
+ return new NodeKey(this);
+ }
}
}
+
diff --git a/apps/config/src/main/java/org/onosproject/config/model/ResourceId.java b/apps/config/src/main/java/org/onosproject/config/model/ResourceId.java
new file mode 100755
index 0000000..a279d40
--- /dev/null
+++ b/apps/config/src/main/java/org/onosproject/config/model/ResourceId.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright 2017-present 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.config.model;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.Objects.hash;
+import static org.onosproject.config.model.ModelConstants.*;
+
+/**
+ * Representation of an entity which identifies a resource in the logical tree
+ * data store. It is a list of node keys to identify the branch point
+ * hierarchy to reach a resource in the instance tree.
+ */
+
+public final class ResourceId {
+
+ //private final Logger log = LoggerFactory.getLogger(getClass());
+ /**
+ * List of node keys.
+ */
+ private List<NodeKey> nodeKeyList;
+
+ /**
+ * Create object from builder.
+ *
+ * @param builder initialized builder
+ */
+ private ResourceId(Builder builder) {
+ nodeKeyList = builder.nodeKeyList;
+ }
+
+ /**
+ * Retrieves a new resource builder.
+ *
+ * @return resource builder
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Returns the list of node key used to uniquely identify the branch in the
+ * logical tree starting from root.
+ *
+ * @return node key uniquely identifying the branch
+ */
+ public List<NodeKey> nodeKeys() {
+ return nodeKeyList;
+ }
+
+ /**
+ * Returns resource identifier builder for a given resource identifier.
+ * It contains all the attributes from the resource identifier. It is to
+ * provide mutability of resource identifier using builder pattern.
+ *
+ * @return data node builder
+ * @throws CloneNotSupportedException if clone fails
+ */
+ public Builder copyBuilder() throws CloneNotSupportedException {
+ return new Builder(this);
+ }
+
+ @Override
+ public int hashCode() {
+ return hash(nodeKeyList);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ ResourceId that = (ResourceId) obj;
+ List<NodeKey> thatList = that.nodeKeyList;
+ return nodeKeyList.size() == thatList.size() &&
+ nodeKeyList.containsAll(thatList);
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(getClass())
+ .add("nodeKeyList", nodeKeyList)
+ .toString();
+ }
+
+ /**
+ * Builder to construct resource identifier.
+ */
+ public static class Builder {
+
+ /**
+ * Application related information, this enables application to use
+ * this builder as there work bench.
+ */
+ protected Object appInfo;
+
+ private List<NodeKey> nodeKeyList;
+ private NodeKey.NodeKeyBuilder curKeyBuilder = null;
+
+ /**
+ * Creates an instance of resource identifier builder.
+ */
+ public Builder() {
+ nodeKeyList = new LinkedList<>();
+ }
+
+ /**
+ * Creates an instance of resource identifier builder. This is used
+ * in scenario when builder is required from a given resource
+ * identifier.
+ *
+ * @param id old resource identifier
+ * @throws CloneNotSupportedException if clone fails
+ */
+ public Builder(ResourceId id) throws CloneNotSupportedException {
+ nodeKeyList = new LinkedList<>();
+ for (NodeKey key : id.nodeKeyList) {
+ nodeKeyList.add(key.clone());
+ }
+ }
+
+ /**
+ * Appends a given resource id to current builder.
+ *
+ * @param id resource identifier to be appended
+ * @return builder
+ * @throws CloneNotSupportedException if clone fails
+ */
+ public Builder append(ResourceId id) throws CloneNotSupportedException {
+ processCurKey();
+ curKeyBuilder = null;
+ Builder ob = id.copyBuilder();
+ nodeKeyList.addAll(ob.nodeKeyList);
+ return this;
+ }
+
+ /**
+ * Validates, build and add current key.
+ */
+ private void processCurKey() {
+ if (curKeyBuilder != null) {
+ if (curKeyBuilder instanceof LeafListKey.LeafListKeyBuilder) {
+ throw new ModelException(LEAF_IS_TERMINAL);
+ }
+ nodeKeyList.add(curKeyBuilder.build());
+ }
+ }
+
+ /**
+ * Adds the descendent node's schema identity.
+ *
+ * @param name name of descendent node
+ * @param nameSpace name space pf descendent node
+ * @return updated builder pointing to the specified schema location
+ */
+ public Builder addBranchPointSchema(String name, String nameSpace) {
+ processCurKey();
+ curKeyBuilder = new NodeKey.NodeKeyBuilder();
+ curKeyBuilder.schemaId(name, nameSpace);
+ return this;
+ }
+
+ /**
+ * Adds a multi instance attribute's node identity.
+ *
+ * @param name name of the leaf list
+ * @param nameSpace name space of leaf list
+ * @param val value of attribute to identify the instance
+ * @return updated builder pointing to the specific attribute
+ * value instance
+ */
+ public Builder addLeafListBranchPoint(String name, String nameSpace,
+ Object val) {
+ LeafListKey.LeafListKeyBuilder leafListKeyBuilder;
+ if (curKeyBuilder instanceof LeafListKey.LeafListKeyBuilder) {
+ throw new ModelException(NON_KEY_LEAF);
+ }
+ leafListKeyBuilder = new LeafListKey.LeafListKeyBuilder()
+ .schemaId(name, nameSpace).value(val);
+
+ curKeyBuilder = leafListKeyBuilder;
+ return this;
+ }
+
+ /**
+ * Adds a multi instance nodes key attribute value to identify
+ * the branch point of instance tree.
+ *
+ * @param name name of the key attribute
+ * @param nameSpace name space of key attribute
+ * @param val value of the key leaf, to match in the list entry
+ * @return updated builder with list branching information
+ */
+ public Builder addKeyLeaf(String name, String nameSpace, Object val) {
+ ListKey.ListKeyBuilder listKeyBuilder;
+ if (!(curKeyBuilder instanceof ListKey.ListKeyBuilder)) {
+ if (curKeyBuilder instanceof LeafListKey.LeafListKeyBuilder) {
+ throw new ModelException(LEAF_IS_TERMINAL);
+ }
+
+ listKeyBuilder = new ListKey.ListKeyBuilder(curKeyBuilder);
+ } else {
+ listKeyBuilder = (ListKey.ListKeyBuilder) curKeyBuilder;
+ }
+
+ listKeyBuilder.addKeyLeaf(name, nameSpace, val);
+ curKeyBuilder = listKeyBuilder;
+ return this;
+ }
+
+ /**
+ * Builds a resource identifier to based on set path information of
+ * the resource.
+ *
+ * @return built resource identifier
+ */
+ public ResourceId build() {
+ checkNotNull(curKeyBuilder, NO_KEY_SET);
+ nodeKeyList.add(curKeyBuilder.build());
+ return new ResourceId(this);
+ }
+
+ /**
+ * Returns application information. This enables application to use
+ * this builder as there work bench.
+ *
+ * @return application information
+ */
+ public Object appInfo() {
+ return appInfo;
+ }
+
+ /**
+ * Sets application information. This enables application to use
+ * this builder as there work bench.
+ *
+ * @param appInfo application related information
+ */
+ public void appInfo(Object appInfo) {
+ appInfo = appInfo;
+ }
+ }
+
+ public String asString() {
+ StringBuilder bldr = new StringBuilder();
+ bldr.append("root.");
+ Iterator<NodeKey> iter = nodeKeyList.iterator();
+ NodeKey key;
+ while (iter.hasNext()) {
+ key = iter.next();
+ //log.info("Iter: key {}", key.toString());
+ bldr.append(key.schemaId().name());
+ bldr.append("#");
+ bldr.append(key.schemaId().namespace());
+ if (iter.hasNext()) {
+ bldr.append(".");
+ }
+ }
+ return bldr.toString();
+ }
+
+ public String lastNm() {
+ int sz = nodeKeyList.size();
+ return nodeKeyList.get(sz - 1).schemaId().name();
+ }
+
+ public String lastNmspc() {
+ int sz = nodeKeyList.size();
+ return nodeKeyList.get(sz - 1).schemaId().namespace();
+ }
+}
\ No newline at end of file
diff --git a/apps/config/src/main/java/org/onosproject/config/model/ResourceIdentifier.java b/apps/config/src/main/java/org/onosproject/config/model/ResourceIdentifier.java
deleted file mode 100755
index 4862fb2..0000000
--- a/apps/config/src/main/java/org/onosproject/config/model/ResourceIdentifier.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2016-present 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.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.config.model;
-
-/**
- * Hollow definition of ResourceIdentifier for ConfigService APIs.
- */
-public interface ResourceIdentifier {
- //will remove this when the corresponding changes in onos-yang-tools become available
-
- /**
- * Returns the node key used to uniquely identify the branch in the
- * logical tree.
- *
- * @return node key uniquely identifying the branch
- */
- NodeKey nodeKey();
-
- /**
- * Returns the descendent resource identifier.
- *
- * @return descendent resource identifier
- */
- ResourceIdentifier descendentIdentifier();
-
- String getBase();
- String asString();
- //DefaultResourceIdentifier asResId(NodeKey nkey);
-}
diff --git a/apps/config/src/main/java/org/onosproject/config/model/SchemaId.java b/apps/config/src/main/java/org/onosproject/config/model/SchemaId.java
new file mode 100755
index 0000000..c7ea7ef
--- /dev/null
+++ b/apps/config/src/main/java/org/onosproject/config/model/SchemaId.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2016-present 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.config.model;
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.config.model.ModelConstants.INCOMPLETE_SCHEMA_INFO;
+
+/**
+ * Representation of an entity which identifies a schema node in the schema /
+ * data tree.
+ */
+public class SchemaId implements Comparable<SchemaId>, Cloneable {
+
+ private String name;
+ private String nameSpace;
+
+ private SchemaId() {
+ }
+
+ public SchemaId(String name, String nameSpace) {
+ checkNotNull(name, INCOMPLETE_SCHEMA_INFO);
+ checkNotNull(nameSpace, INCOMPLETE_SCHEMA_INFO);
+ this.name = name;
+ this.nameSpace = nameSpace;
+ }
+
+ /**
+ * Returns node schema name. This is mandatory to identify node according
+ * to schema.
+ *
+ * @return node name
+ */
+ public String name() {
+ return name;
+ }
+
+ /**
+ * Returns node's namespace. This is mandatory serializers must translate
+ * any implicit namespace to explicit namespace.
+ *
+ * @return node's namespace
+ */
+ public String namespace() {
+ return nameSpace;
+ }
+
+ /**
+ * Creates and returns a deep copy of this object.
+ *
+ * @return cloned copy
+ * @throws CloneNotSupportedException if the object's class does not
+ * support the {@code Cloneable} interface
+ */
+ public SchemaId clone() throws CloneNotSupportedException {
+ return (SchemaId) super.clone();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(name, nameSpace);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ SchemaId that = (SchemaId) obj;
+ return Objects.equals(name, that.name) &&
+ Objects.equals(nameSpace, that.nameSpace);
+ }
+
+ @Override
+ public int compareTo(SchemaId o) {
+ checkNotNull(o);
+ if (name.equals(o.name)) {
+ if (nameSpace.equals(o.nameSpace)) {
+ return 0;
+ }
+ }
+ return -1;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(getClass())
+ .add("name", name)
+ .add("nameSpace", nameSpace)
+ .toString();
+ }
+}
\ No newline at end of file