[ONOS-3884] Base Data model node and parser interface

Change-Id: I94caf7fbf26125126d0779c283076c05fc7cd8cf
diff --git a/src/main/java/org/onosproject/yangutils/datamodel/YangNode.java b/src/main/java/org/onosproject/yangutils/datamodel/YangNode.java
new file mode 100644
index 0000000..c34e8dc
--- /dev/null
+++ b/src/main/java/org/onosproject/yangutils/datamodel/YangNode.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.yangutils.datamodel;
+
+import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+
+/**
+ * Base class of a node in data model tree.
+ */
+public abstract class YangNode {
+
+    /* Type of information maintained in node */
+    private YangNodeType nodeType;
+
+    /* Parent reference */
+    private YangNode parent;
+
+    /* First child reference */
+    private YangNode child;
+
+    /* Next sibling reference */
+    private YangNode nextSibling;
+
+    /* Previous sibling reference */
+    private YangNode previousSibling;
+
+    /**
+     * Default constructor is made private to ensure node type is always set.
+     */
+    @SuppressWarnings("unused")
+    private YangNode() {
+
+    }
+
+    /**
+     * Create a specific type of node.
+     *
+     * @param type of YANG node
+     */
+    protected YangNode(YangNodeType type) {
+        setNodeType(type);
+    }
+
+    /**
+     * Get the node type.
+     *
+     * @return node type
+     */
+    public YangNodeType getNodeType() {
+        return nodeType;
+    }
+
+    /**
+     * Set the node type.
+     *
+     * @param nodeType type of node
+     */
+    private void setNodeType(YangNodeType nodeType) {
+        this.nodeType = nodeType;
+    }
+
+    /**
+     * Get the parent of node.
+     *
+     * @return parent of node
+     */
+    public YangNode getParent() {
+        return parent;
+    }
+
+    /**
+     * Set the parent of node.
+     *
+     * @param parent node
+     */
+    public void setParent(YangNode parent) {
+        this.parent = parent;
+    }
+
+    /**
+     * Get the first child of node.
+     *
+     * @return first child of node
+     */
+    public YangNode getChild() {
+        return child;
+    }
+
+    /**
+     * Set the first instance of a child node.
+     *
+     * @param child is only child to be set
+     */
+    public void setChild(YangNode child) {
+        this.child = child;
+    }
+
+    /**
+     * Get the next sibling of node.
+     *
+     * @return next sibling of node
+     */
+    public YangNode getNextSibling() {
+        return nextSibling;
+    }
+
+    /**
+     * Set the next sibling of node.
+     *
+     * @param sibling YANG node
+     */
+    public void setNextSibling(YangNode sibling) {
+        nextSibling = sibling;
+    }
+
+    /**
+     * Get the previous sibling.
+     *
+     * @return previous sibling node
+     */
+    public YangNode getPreviousSibling() {
+        return previousSibling;
+    }
+
+    /**
+     * Set the previous sibling.
+     *
+     * @param previousSibling points to predecessor sibling
+     */
+    public void setPreviousSibling(YangNode previousSibling) {
+        this.previousSibling = previousSibling;
+    }
+
+    /**
+     * Add a child node, the children sibling list will be sorted based on node
+     * type.
+     *
+     * @param newChild refers to a child to be added
+     * @throws DataModelException due to violation in data model rules
+     */
+    void addChild(YangNode newChild) throws DataModelException {
+        if (newChild.getNodeType() == null) {
+            throw new DataModelException("Abstract node cannot be inserted into a tree");
+        }
+
+        if (newChild.getParent() == null) {
+            newChild.setParent(this);
+        } else if (newChild.getParent() != this) {
+            throw new DataModelException("Node is already part of a tree");
+        }
+
+        if (newChild.getChild() != null) {
+            throw new DataModelException("Child to be added is not atomic, it already has a child");
+        }
+
+        if (newChild.getNextSibling() != null) {
+            throw new DataModelException("Child to be added is not atomic, it already has a next sibling");
+        }
+
+        if (newChild.getPreviousSibling() != null) {
+            throw new DataModelException("Child to be added is not atomic, it already has a previous sibling");
+        }
+
+        /* First child to be added */
+        if (getChild() == null) {
+            setChild(newChild);
+            return;
+        }
+
+        YangNode curNode;
+        curNode = getChild();
+
+        /* If the new node needs to be the first child */
+        if (newChild.getNodeType().ordinal() < curNode.getNodeType().ordinal()) {
+            newChild.setNextSibling(curNode);
+            curNode.setPreviousSibling(newChild);
+            setChild(newChild);
+            return;
+        }
+
+        /*
+         * Get the predecessor child of new child
+         */
+        while (curNode.getNextSibling() != null
+                && newChild.getNodeType().ordinal() >= curNode.getNextSibling().getNodeType().ordinal()) {
+            curNode = curNode.getNextSibling();
+        }
+
+        /* If the new node needs to be the last child */
+        if (curNode.getNextSibling() == null) {
+            curNode.setNextSibling(newChild);
+            newChild.setPreviousSibling(curNode);
+            return;
+        }
+
+        /* Insert the new node in child node list sorted by type */
+        newChild.setNextSibling(curNode.getNextSibling());
+        newChild.setPreviousSibling(curNode);
+        curNode.getNextSibling().setPreviousSibling(newChild);
+        curNode.setNextSibling(newChild);
+        return;
+    }
+}
diff --git a/src/main/java/org/onosproject/yangutils/parser/Parsable.java b/src/main/java/org/onosproject/yangutils/parser/Parsable.java
new file mode 100644
index 0000000..2beae10
--- /dev/null
+++ b/src/main/java/org/onosproject/yangutils/parser/Parsable.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.yangutils.parser;
+
+import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+
+/**
+ * Abstraction of an entity which process the data of lexer's parse tree.
+ */
+public interface Parsable {
+
+    /**
+     * Get the type of parsable data.
+     *
+     * @return the type of parsable data
+     */
+    ParsableDataType getParsableDataType();
+
+    /**
+     * Check if the node is valid as per YANG grammar's syntax and semantics.
+     * This validation will be performed on entering the node in traversal
+     *
+     * @throws DataModelException if there is any violation of the YANG rules
+     * in parsed data, corresponding exception should be thrown
+     */
+    void validateDataOnEntry() throws DataModelException;
+
+    /**
+     * Check if the node is valid as per YANG grammar's syntax and semantics.
+     * This validation will be performed on exiting the node in traversal
+     *
+     * @throws DataModelException if there is any violation of the YANG rules
+     * in parsed data, corresponding exception should be thrown
+     */
+    void validateDataOnExit() throws DataModelException;
+}
diff --git a/src/main/java/org/onosproject/yangutils/parser/ParsableDataType.java b/src/main/java/org/onosproject/yangutils/parser/ParsableDataType.java
new file mode 100644
index 0000000..50addeb
--- /dev/null
+++ b/src/main/java/org/onosproject/yangutils/parser/ParsableDataType.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.yangutils.parser;
+
+/**
+ * ENUM to represent the type of data in parse tree.
+ */
+public enum ParsableDataType {
+    /**
+     * Identifies the module parsed data.
+     */
+    MODULE_DATA,
+
+    /**
+     * Identifies the sub module parsed data.
+     */
+    SUB_MODULE_DATA,
+
+    /**
+     * Identifies the typedef parsed data.
+     */
+    TYPEDEF_DATA,
+
+    /**
+     * Identifies the type parsed data.
+     */
+    TYPE_DATA,
+
+    /**
+     * Identifies the choice parsed data.
+     */
+    CHOICE_DATA,
+
+    /**
+     * Identifies the case parsed data.
+     */
+    CASE_DATA,
+
+    /**
+     * Identifies the YANG enumeration parsed data.
+     */
+    ENUMERATION_DATA,
+
+    /**
+     * Identifies the grouping parsed data.
+     */
+    GROUPING_DATA,
+
+    /**
+     * Identifies the uses parsed data.
+     */
+    USES_DATA,
+
+    /**
+     * Identifies the augment parsed data.
+     */
+    AUGMENT_DATA,
+
+    /**
+     * Identifies the container parsed data.
+     */
+    CONTAINER_DATA,
+
+    /**
+     * Identifies the YANG list parsed data.
+     */
+    LIST_DATA,
+
+    /**
+     * Identifies the YANG belongs-to parsed data.
+     */
+    BELONGS_TO_DATA,
+
+    /**
+     * Identifies the YANG bit parsed data.
+     */
+    BIT_DATA,
+
+    /**
+     * Identifies the YANG bits parsed data.
+     */
+    BITS_DATA,
+
+    /**
+     * Identifies the YANG enum parsed data.
+     */
+    ENUM_DATA,
+
+    /**
+     * Identifies the YANG import parsed data.
+     */
+    IMPORT_DATA,
+
+    /**
+     * Identifies the YANG include parsed data.
+     */
+    INCLUDE_DATA,
+
+    /**
+     * Identifies the YANG leaf parsed data.
+     */
+    LEAF_DATA,
+
+    /**
+     * Identifies the YANG leaf list parsed data.
+     */
+    LEAF_LIST_DATA,
+
+    /**
+     * Identifies the YANG must parsed data.
+     */
+    MUST_DATA,
+
+    /**
+     * Identifies the YANG revision parsed data.
+     */
+    REVISION_DATA,
+
+    /**
+     * Identifies the YANG namespace parsed data.
+     */
+    NAMESPACE_DATA
+}