blob: c34e8dc42aca242e9ef6e140173f5d3bf21b8b46 [file] [log] [blame]
Vinod Kumar S8c4e6492016-02-05 20:21:19 +05301/*
2 * Copyright 2016 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.yangutils.datamodel;
17
18import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
19
20/**
21 * Base class of a node in data model tree.
22 */
23public abstract class YangNode {
24
25 /* Type of information maintained in node */
26 private YangNodeType nodeType;
27
28 /* Parent reference */
29 private YangNode parent;
30
31 /* First child reference */
32 private YangNode child;
33
34 /* Next sibling reference */
35 private YangNode nextSibling;
36
37 /* Previous sibling reference */
38 private YangNode previousSibling;
39
40 /**
41 * Default constructor is made private to ensure node type is always set.
42 */
43 @SuppressWarnings("unused")
44 private YangNode() {
45
46 }
47
48 /**
49 * Create a specific type of node.
50 *
51 * @param type of YANG node
52 */
53 protected YangNode(YangNodeType type) {
54 setNodeType(type);
55 }
56
57 /**
58 * Get the node type.
59 *
60 * @return node type
61 */
62 public YangNodeType getNodeType() {
63 return nodeType;
64 }
65
66 /**
67 * Set the node type.
68 *
69 * @param nodeType type of node
70 */
71 private void setNodeType(YangNodeType nodeType) {
72 this.nodeType = nodeType;
73 }
74
75 /**
76 * Get the parent of node.
77 *
78 * @return parent of node
79 */
80 public YangNode getParent() {
81 return parent;
82 }
83
84 /**
85 * Set the parent of node.
86 *
87 * @param parent node
88 */
89 public void setParent(YangNode parent) {
90 this.parent = parent;
91 }
92
93 /**
94 * Get the first child of node.
95 *
96 * @return first child of node
97 */
98 public YangNode getChild() {
99 return child;
100 }
101
102 /**
103 * Set the first instance of a child node.
104 *
105 * @param child is only child to be set
106 */
107 public void setChild(YangNode child) {
108 this.child = child;
109 }
110
111 /**
112 * Get the next sibling of node.
113 *
114 * @return next sibling of node
115 */
116 public YangNode getNextSibling() {
117 return nextSibling;
118 }
119
120 /**
121 * Set the next sibling of node.
122 *
123 * @param sibling YANG node
124 */
125 public void setNextSibling(YangNode sibling) {
126 nextSibling = sibling;
127 }
128
129 /**
130 * Get the previous sibling.
131 *
132 * @return previous sibling node
133 */
134 public YangNode getPreviousSibling() {
135 return previousSibling;
136 }
137
138 /**
139 * Set the previous sibling.
140 *
141 * @param previousSibling points to predecessor sibling
142 */
143 public void setPreviousSibling(YangNode previousSibling) {
144 this.previousSibling = previousSibling;
145 }
146
147 /**
148 * Add a child node, the children sibling list will be sorted based on node
149 * type.
150 *
151 * @param newChild refers to a child to be added
152 * @throws DataModelException due to violation in data model rules
153 */
154 void addChild(YangNode newChild) throws DataModelException {
155 if (newChild.getNodeType() == null) {
156 throw new DataModelException("Abstract node cannot be inserted into a tree");
157 }
158
159 if (newChild.getParent() == null) {
160 newChild.setParent(this);
161 } else if (newChild.getParent() != this) {
162 throw new DataModelException("Node is already part of a tree");
163 }
164
165 if (newChild.getChild() != null) {
166 throw new DataModelException("Child to be added is not atomic, it already has a child");
167 }
168
169 if (newChild.getNextSibling() != null) {
170 throw new DataModelException("Child to be added is not atomic, it already has a next sibling");
171 }
172
173 if (newChild.getPreviousSibling() != null) {
174 throw new DataModelException("Child to be added is not atomic, it already has a previous sibling");
175 }
176
177 /* First child to be added */
178 if (getChild() == null) {
179 setChild(newChild);
180 return;
181 }
182
183 YangNode curNode;
184 curNode = getChild();
185
186 /* If the new node needs to be the first child */
187 if (newChild.getNodeType().ordinal() < curNode.getNodeType().ordinal()) {
188 newChild.setNextSibling(curNode);
189 curNode.setPreviousSibling(newChild);
190 setChild(newChild);
191 return;
192 }
193
194 /*
195 * Get the predecessor child of new child
196 */
197 while (curNode.getNextSibling() != null
198 && newChild.getNodeType().ordinal() >= curNode.getNextSibling().getNodeType().ordinal()) {
199 curNode = curNode.getNextSibling();
200 }
201
202 /* If the new node needs to be the last child */
203 if (curNode.getNextSibling() == null) {
204 curNode.setNextSibling(newChild);
205 newChild.setPreviousSibling(curNode);
206 return;
207 }
208
209 /* Insert the new node in child node list sorted by type */
210 newChild.setNextSibling(curNode.getNextSibling());
211 newChild.setPreviousSibling(curNode);
212 curNode.getNextSibling().setPreviousSibling(newChild);
213 curNode.setNextSibling(newChild);
214 return;
215 }
216}