[ONOS-5149] YPM Implementation

Change-Id: I9814d28cfe5e4278019fa565ea6d16bd8778b4c8
diff --git a/apps/yms/api/src/main/java/org/onosproject/yms/ypm/DefaultYpmNode.java b/apps/yms/api/src/main/java/org/onosproject/yms/ypm/DefaultYpmNode.java
new file mode 100644
index 0000000..662d3c3
--- /dev/null
+++ b/apps/yms/api/src/main/java/org/onosproject/yms/ypm/DefaultYpmNode.java
@@ -0,0 +1,226 @@
+/*
+ * 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.yms.ypm;
+
+/**
+ * Represents implementation of interfaces to build and obtain YANG protocol metadata tree node.
+ */
+public class DefaultYpmNode implements YpmContext {
+
+    /**
+     * Name of the node.
+     */
+    private String name;
+
+    /**
+     * Parent reference.
+     */
+    private DefaultYpmNode parent;
+
+    /**
+     * First child reference.
+     */
+    private DefaultYpmNode child;
+
+    /**
+     * Next sibling reference.
+     */
+    private DefaultYpmNode nextSibling;
+
+    /**
+     * Previous sibling reference.
+     */
+    private DefaultYpmNode previousSibling;
+
+    /**
+     * Protocol metadata object.
+     */
+    private Object metaData;
+
+    /**
+     * Creates a specific type of node.
+     *
+     * @param name of ypm node
+     */
+    public DefaultYpmNode(String name) {
+        setName(name);
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public DefaultYpmNode getParent() {
+        return parent;
+    }
+
+    @Override
+    public void setParent(YpmContext parent) {
+        this.parent = (DefaultYpmNode) parent;
+    }
+
+    @Override
+    public YpmContext getFirstChild() {
+        return child;
+    }
+
+    @Override
+    public YpmContext getChild(String ypmName) {
+        if (ypmName == null) {
+            // Input is null. So, will not proceed.
+            return null;
+        }
+
+        if (child == null) {
+            // No children
+            return null;
+        }
+
+        // Check the first child
+        if (child.name.equals(ypmName)) {
+            return child;
+        }
+
+        // Check its siblings
+        YpmContext currentChild = child;
+        while (currentChild.getNextSibling() != null) {
+            currentChild = currentChild.getNextSibling();
+            if (currentChild.getName().equals(ypmName)) {
+                return currentChild;
+            }
+        }
+
+        return null;
+    }
+
+    @Override
+    public void addChild(String ypmName) {
+        if (ypmName == null) {
+            // Input is null. So, will not proceed.
+            return;
+        }
+
+        if (getChild(ypmName) != null) {
+            // Already available with the same name. So, no need to add
+            return;
+        }
+
+        // Create new ypm node and attach to its parent
+        DefaultYpmNode newNode = new DefaultYpmNode(ypmName);
+        newNode.setParent(this);
+
+        // Check the first child
+        if (child == null) {
+            child = newNode;
+            return;
+        }
+
+        // Add it to its siblings
+        YpmContext currentChild = child;
+        // Go to the last child
+        while (currentChild.getNextSibling() != null) {
+            currentChild = currentChild.getNextSibling();
+        }
+        currentChild.setNextSibling(newNode);
+        newNode.setPreviousSibling((DefaultYpmNode) currentChild);
+    }
+
+    @Override
+    public YpmContext getSibling(String ypmName) {
+        if (ypmName == null) {
+            // Input is null. So, will not proceed.
+            return null;
+        }
+
+        YpmContext sibling = getNextSibling();
+        while (sibling != null) {
+            if (sibling.getName().equals(ypmName)) {
+                return sibling;
+            }
+            sibling = sibling.getNextSibling();
+        }
+        return null;
+    }
+
+    @Override
+    public void addSibling(String ypmName) {
+        if (ypmName == null) {
+            // Input is null. So, will not proceed.
+            return;
+        }
+
+        if (getSibling(ypmName) != null) {
+            // Already available with the same name. So, no need to add
+            return;
+        }
+
+        // Create new ypm node and attach to its parent
+        DefaultYpmNode newSibling = new DefaultYpmNode(ypmName);
+        newSibling.setParent(this.getParent());
+
+        // Add it as its sibling
+        YpmContext sibling = getNextSibling();
+        if (sibling == null) {
+            setNextSibling(newSibling);
+            newSibling.setPreviousSibling(this);
+        } else {
+            // Go to the last sibling
+            while (sibling.getNextSibling() != null) {
+                sibling = sibling.getNextSibling();
+            }
+            sibling.setNextSibling(newSibling);
+            newSibling.setPreviousSibling((DefaultYpmNode) sibling);
+        }
+    }
+
+    @Override
+    public DefaultYpmNode getNextSibling() {
+        return nextSibling;
+    }
+
+    @Override
+    public void setNextSibling(DefaultYpmNode sibling) {
+        nextSibling = sibling;
+    }
+
+    @Override
+    public DefaultYpmNode getPreviousSibling() {
+        return previousSibling;
+    }
+
+    @Override
+    public void setPreviousSibling(DefaultYpmNode sibling) {
+        this.previousSibling = sibling;
+    }
+
+    @Override
+    public Object getMetaData() {
+        return this.metaData;
+    }
+
+    @Override
+    public void setMetaData(Object data) {
+        this.metaData = data;
+    }
+}
diff --git a/apps/yms/api/src/main/java/org/onosproject/yms/ypm/YpmContext.java b/apps/yms/api/src/main/java/org/onosproject/yms/ypm/YpmContext.java
new file mode 100644
index 0000000..fe7efb5
--- /dev/null
+++ b/apps/yms/api/src/main/java/org/onosproject/yms/ypm/YpmContext.java
@@ -0,0 +1,131 @@
+/*
+ * 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.yms.ypm;
+
+/**
+ * Abstraction of an entity which represents YANG protocol metadata context
+ * information.
+ */
+public interface YpmContext {
+
+    /**
+     * Returns the node name.
+     *
+     * @return node name
+     */
+    String getName();
+
+    /**
+     * Sets the nodes name.
+     *
+     * @param name nodes name
+     */
+    void setName(String name);
+
+    /**
+     * Returns the context of parent node.
+     *
+     * @return context of parent node
+     */
+    YpmContext getParent();
+
+    /**
+     * Sets the context of parent node.
+     *
+     * @param parent node parent
+     */
+    void setParent(YpmContext parent);
+
+    /**
+     * Retrieves the first child of a node.
+     *
+     * @return first child of a node
+     */
+    YpmContext getFirstChild();
+
+    /**
+     * Retrieves the child of a node for corresponding ydt node.
+     *
+     * @param name ypm node
+     * @return child of a node
+     */
+    YpmContext getChild(String name);
+
+    /**
+     * Adds child to a node by ydt name.
+     *
+     * @param name ypm name
+     */
+    void addChild(String name);
+
+    /**
+     * Retrieves sibling of a child by (ydt) name.
+     *
+     * @param name ypm name
+     * @return sibling of a child
+     */
+    YpmContext getSibling(String name);
+
+    /**
+     * Adds new sibling to a child.
+     *
+     * @param name ypm name
+     */
+    void addSibling(String name);
+
+    /**
+     * Returns the context of next sibling.
+     *
+     * @return context of next sibling
+     */
+    YpmContext getNextSibling();
+
+    /**
+     * Sets the next sibling of node.
+     *
+     * @param sibling ypm node
+     */
+    void setNextSibling(DefaultYpmNode sibling);
+
+    /**
+     * Returns the previous sibling of a node.
+     *
+     * @return previous sibling of a node
+     */
+    DefaultYpmNode getPreviousSibling();
+
+    /**
+     * Sets the previous sibling.
+     *
+     * @param previousSibling points to predecessor sibling
+     */
+    void setPreviousSibling(DefaultYpmNode previousSibling);
+
+    /**
+     * Retrieves protocol metadata.
+     *
+     * @return metadata
+     */
+    Object getMetaData();
+
+    /**
+     * Sets the protocol metadata.
+     *
+     * @param data metadata
+     */
+    void setMetaData(Object data);
+}
diff --git a/apps/yms/api/src/main/java/org/onosproject/yms/ypm/YpmService.java b/apps/yms/api/src/main/java/org/onosproject/yms/ypm/YpmService.java
new file mode 100644
index 0000000..18ecd8a
--- /dev/null
+++ b/apps/yms/api/src/main/java/org/onosproject/yms/ypm/YpmService.java
@@ -0,0 +1,41 @@
+/*
+ * 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.yms.ypm;
+
+import org.onosproject.yms.ydt.YdtContext;
+
+/**
+ * Abstraction of an entity which provides interfaces to YANG Protocol Metadata Manager.
+ */
+public interface YpmService {
+
+    /**
+     * Returns the protocol data stored in sepecific data model path.
+     *
+     * @param rootNode YANG data tree
+     * @return YANG protocol metadata
+     */
+    YpmContext getProtocolData(YdtContext rootNode);
+
+    /**
+     * Sets the YANG protocol metadata in specific ydt path in ypm tree.
+     *
+     * @param rootNode YANG data tree
+     * @param data YANG protocol metadata
+     */
+    void setProtocolData(YdtContext rootNode, Object data);
+}
diff --git a/apps/yms/api/src/main/java/org/onosproject/yms/ypm/package-info.java b/apps/yms/api/src/main/java/org/onosproject/yms/ypm/package-info.java
new file mode 100644
index 0000000..b1472aa
--- /dev/null
+++ b/apps/yms/api/src/main/java/org/onosproject/yms/ypm/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/**
+ * Provides interfaces to YANG protocol metadata manager. YPM maintains protocol specific information
+ * (like timestamp, entity tag, etc.) for YANG modeled data.
+ */
+package org.onosproject.yms.ypm;