[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
+}