Vinod Kumar S
Committed by Gerrit Code Review

YANG uses Intra file linking

Change-Id: I45936bee910ba4c81805f59daf2702bea5e60d08
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
16 16
17 package org.onosproject.yangutils.datamodel; 17 package org.onosproject.yangutils.datamodel;
18 18
19 +import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
20 +
19 /** 21 /**
20 * Abstraction of YANG resolvable information. Abstracted to obtain the 22 * Abstraction of YANG resolvable information. Abstracted to obtain the
21 * information required for linking resolution. 23 * information required for linking resolution.
...@@ -44,6 +46,9 @@ public interface Resolvable { ...@@ -44,6 +46,9 @@ public interface Resolvable {
44 46
45 /** 47 /**
46 * Resolves the linking. 48 * Resolves the linking.
49 + *
50 + * @throws DataModelException data model error
47 */ 51 */
48 - void resolve(); 52 + void resolve()
53 + throws DataModelException;
49 } 54 }
......
...@@ -16,11 +16,17 @@ ...@@ -16,11 +16,17 @@
16 package org.onosproject.yangutils.datamodel; 16 package org.onosproject.yangutils.datamodel;
17 17
18 import org.onosproject.yangutils.datamodel.exceptions.DataModelException; 18 import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
19 +import org.onosproject.yangutils.translator.tojava.TraversalType;
20 +
21 +import static org.onosproject.yangutils.translator.tojava.TraversalType.CHILD;
22 +import static org.onosproject.yangutils.translator.tojava.TraversalType.PARENT;
23 +import static org.onosproject.yangutils.translator.tojava.TraversalType.SIBILING;
19 24
20 /** 25 /**
21 * Represents base class of a node in data model tree. 26 * Represents base class of a node in data model tree.
22 */ 27 */
23 -public abstract class YangNode { 28 +public abstract class YangNode
29 + implements Cloneable {
24 30
25 /** 31 /**
26 * Type of node. 32 * Type of node.
...@@ -146,7 +152,7 @@ public abstract class YangNode { ...@@ -146,7 +152,7 @@ public abstract class YangNode {
146 * 152 *
147 * @param sibling YANG node 153 * @param sibling YANG node
148 */ 154 */
149 - public void setNextSibling(YangNode sibling) { 155 + private void setNextSibling(YangNode sibling) {
150 nextSibling = sibling; 156 nextSibling = sibling;
151 } 157 }
152 158
...@@ -164,7 +170,7 @@ public abstract class YangNode { ...@@ -164,7 +170,7 @@ public abstract class YangNode {
164 * 170 *
165 * @param previousSibling points to predecessor sibling 171 * @param previousSibling points to predecessor sibling
166 */ 172 */
167 - public void setPreviousSibling(YangNode previousSibling) { 173 + private void setPreviousSibling(YangNode previousSibling) {
168 this.previousSibling = previousSibling; 174 this.previousSibling = previousSibling;
169 } 175 }
170 176
...@@ -175,7 +181,8 @@ public abstract class YangNode { ...@@ -175,7 +181,8 @@ public abstract class YangNode {
175 * @param newChild refers to a child to be added 181 * @param newChild refers to a child to be added
176 * @throws DataModelException due to violation in data model rules 182 * @throws DataModelException due to violation in data model rules
177 */ 183 */
178 - public void addChild(YangNode newChild) throws DataModelException { 184 + public void addChild(YangNode newChild)
185 + throws DataModelException {
179 if (newChild.getNodeType() == null) { 186 if (newChild.getNodeType() == null) {
180 throw new DataModelException("Abstract node cannot be inserted into a tree"); 187 throw new DataModelException("Abstract node cannot be inserted into a tree");
181 } 188 }
...@@ -207,24 +214,10 @@ public abstract class YangNode { ...@@ -207,24 +214,10 @@ public abstract class YangNode {
207 YangNode curNode; 214 YangNode curNode;
208 curNode = getChild(); 215 curNode = getChild();
209 216
210 - /*-
211 - * If the new node needs to be the first child
212 - if (newChild.getNodeType().ordinal() < curNode.getNodeType().ordinal()) {
213 - newChild.setNextSibling(curNode);
214 - curNode.setPreviousSibling(newChild);
215 - setChild(newChild);
216 - return;
217 - }
218 - */
219 -
220 /* 217 /*
221 * Get the predecessor child of new child 218 * Get the predecessor child of new child
222 */ 219 */
223 - while (curNode.getNextSibling() != null 220 + while (curNode.getNextSibling() != null) {
224 - /*
225 - * && newChild.getNodeType().ordinal() >=
226 - * curNode.getNextSibling().getNodeType().ordinal()
227 - */) {
228 221
229 curNode = curNode.getNextSibling(); 222 curNode = curNode.getNextSibling();
230 } 223 }
...@@ -233,16 +226,143 @@ public abstract class YangNode { ...@@ -233,16 +226,143 @@ public abstract class YangNode {
233 if (curNode.getNextSibling() == null) { 226 if (curNode.getNextSibling() == null) {
234 curNode.setNextSibling(newChild); 227 curNode.setNextSibling(newChild);
235 newChild.setPreviousSibling(curNode); 228 newChild.setPreviousSibling(curNode);
229 + }
230 + }
231 +
232 + /**
233 + * Clone the current node contents and create a new node.
234 + *
235 + * @return cloned node
236 + * @throws CloneNotSupportedException clone is not supported by the referred node
237 + */
238 + public YangNode clone()
239 + throws CloneNotSupportedException {
240 + YangNode clonedNode = (YangNode) super.clone();
241 + clonedNode.setParent(null);
242 + clonedNode.setChild(null);
243 + clonedNode.setNextSibling(null);
244 + clonedNode.setPreviousSibling(null);
245 + return clonedNode;
246 + }
247 +
248 + /**
249 + * Clone the subtree from the specified source node to the mentioned target node.
250 + * The source and target root node cloning is carried out by the caller.
251 + *
252 + * @param srcRootNode source node for sub tree cloning
253 + * @param dstRootNode destination node where the sub tree needs to be cloned
254 + * @throws DataModelException data model error
255 + */
256 + public static void cloneSubTree(YangNode srcRootNode, YangNode dstRootNode)
257 + throws DataModelException {
258 +
259 + YangNode nextNodeToClone = srcRootNode;
260 + TraversalType curTraversal;
261 +
262 +
263 + YangNode clonedTreeCurNode = dstRootNode;
264 + YangNode newNode = null;
265 +
266 + nextNodeToClone = nextNodeToClone.getChild();
267 + if (nextNodeToClone == null) {
236 return; 268 return;
269 + } else {
270 + /**
271 + * Root level cloning is taken care in the caller.
272 + */
273 + curTraversal = CHILD;
237 } 274 }
238 275
239 - /*- 276 + /**
240 - * Insert the new node in child node list sorted by type 277 + * Caller ensures the cloning of the root nodes
241 - newChild.setNextSibling(curNode.getNextSibling());
242 - newChild.setPreviousSibling(curNode);
243 - curNode.getNextSibling().setPreviousSibling(newChild);
244 - curNode.setNextSibling(newChild);
245 - return;
246 */ 278 */
279 + try {
280 + while (nextNodeToClone != srcRootNode) {
281 + if (nextNodeToClone == null) {
282 + throw new DataModelException("Internal error: Cloning failed, source tree null pointer reached");
283 + }
284 +
285 + if (curTraversal == CHILD) {
286 + newNode = nextNodeToClone.clone();
287 +
288 + /**
289 + * add the new node to the cloned tree.
290 + */
291 + clonedTreeCurNode.addChild(newNode);
292 +
293 + /**
294 + * update the cloned tree's travesal current node as the new node.
295 + */
296 + clonedTreeCurNode = newNode;
297 + } else if (curTraversal == SIBILING) {
298 + newNode = nextNodeToClone.clone();
299 +
300 + clonedTreeCurNode.addNextSibling(newNode);
301 + clonedTreeCurNode = newNode;
302 + } else if (curTraversal == PARENT) {
303 + clonedTreeCurNode = clonedTreeCurNode.getParent();
304 + }
305 +
306 + if (curTraversal != PARENT && nextNodeToClone.getChild() != null) {
307 + curTraversal = CHILD;
308 +
309 + /**
310 + * update the traversal's current node.
311 + */
312 + nextNodeToClone = nextNodeToClone.getChild();
313 +
314 + } else if (nextNodeToClone.getNextSibling() != null) {
315 +
316 + curTraversal = SIBILING;
317 +
318 + nextNodeToClone = nextNodeToClone.getNextSibling();
319 + } else {
320 + curTraversal = PARENT;
321 + nextNodeToClone = nextNodeToClone.getParent();
322 + }
323 + }
324 + } catch (CloneNotSupportedException e) {
325 + throw new DataModelException("Failed to clone the tree");
326 + }
327 +
328 + }
329 +
330 + /**
331 + * Add a new next sibling.
332 + *
333 + * @param newSibling new sibling to be added
334 + * @throws DataModelException data model error
335 + */
336 + private void addNextSibling(YangNode newSibling)
337 + throws DataModelException {
338 +
339 + if (newSibling.getNodeType() == null) {
340 + throw new DataModelException("Cloned abstract node cannot be inserted into a tree");
341 + }
342 +
343 + if (newSibling.getParent() == null) {
344 + /**
345 + * Since the siblings needs to have a common parent, set the parent as the current node's parent
346 + */
347 + newSibling.setParent(this.getParent());
348 +
349 + } else {
350 + throw new DataModelException("Node is already part of a tree, and cannot be added as a sibling");
351 + }
352 +
353 + if (newSibling.getPreviousSibling() == null) {
354 + newSibling.setPreviousSibling(this);
355 + setNextSibling(newSibling);
356 + } else {
357 + throw new DataModelException("New sibling to be added is not atomic, it already has a previous sibling");
358 + }
359 +
360 + if (newSibling.getChild() != null) {
361 + throw new DataModelException("Sibling to be added is not atomic, it already has a child");
362 + }
363 +
364 + if (newSibling.getNextSibling() != null) {
365 + throw new DataModelException("Sibling to be added is not atomic, it already has a next sibling");
366 + }
247 } 367 }
248 } 368 }
......
...@@ -190,7 +190,8 @@ public class YangResolutionInfo<T> { ...@@ -190,7 +190,8 @@ public class YangResolutionInfo<T> {
190 /** 190 /**
191 * Resolve the current entity in the stack. 191 * Resolve the current entity in the stack.
192 */ 192 */
193 - private void resolveTopOfStack() { 193 + private void resolveTopOfStack()
194 + throws DataModelException {
194 ((Resolvable) getCurrentEntityToResolveFromStack()).resolve(); 195 ((Resolvable) getCurrentEntityToResolveFromStack()).resolve();
195 196
196 if (((Resolvable) getCurrentEntityToResolveFromStack()).getResolvableStatus() 197 if (((Resolvable) getCurrentEntityToResolveFromStack()).getResolvableStatus()
......
...@@ -19,6 +19,8 @@ import org.onosproject.yangutils.datamodel.exceptions.DataModelException; ...@@ -19,6 +19,8 @@ import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
19 import org.onosproject.yangutils.parser.Parsable; 19 import org.onosproject.yangutils.parser.Parsable;
20 import org.onosproject.yangutils.utils.YangConstructType; 20 import org.onosproject.yangutils.utils.YangConstructType;
21 21
22 +import static org.onosproject.yangutils.translator.tojava.utils.JavaIdentifierSyntax.getParentNodeInGenCode;
23 +
22 /*- 24 /*-
23 * Reference RFC 6020. 25 * Reference RFC 6020.
24 * 26 *
...@@ -255,8 +257,33 @@ public class YangUses ...@@ -255,8 +257,33 @@ public class YangUses
255 } 257 }
256 258
257 @Override 259 @Override
258 - public void resolve() { 260 + public void resolve()
259 - //TODO: implement the method. 261 + throws DataModelException {
262 +
263 + YangGrouping referredGrouping = getRefGroup();
264 +
265 + if (referredGrouping == null) {
266 + throw new DataModelException("YANG uses linker error, cannot resolve uses");
267 + }
268 +
269 + YangNode usesParentNode = getParentNodeInGenCode(this);
270 + if (!(usesParentNode instanceof YangLeavesHolder)) {
271 + throw new DataModelException("YANG uses holder construct is wrong");
272 + }
273 +
274 + YangLeavesHolder usesParentLeavesHolder = (YangLeavesHolder) usesParentNode;
275 + if (referredGrouping.getListOfLeaf() != null) {
276 + for (YangLeaf leaf : referredGrouping.getListOfLeaf()) {
277 + usesParentLeavesHolder.addLeaf(leaf);
278 + }
279 + }
280 + if (referredGrouping.getListOfLeafList() != null) {
281 + for (YangLeafList leafList : referredGrouping.getListOfLeafList()) {
282 + usesParentLeavesHolder.addLeafList(leafList);
283 + }
284 + }
285 +
286 + YangNode.cloneSubTree(getRefGroup(), usesParentNode);
260 } 287 }
261 288
262 @Override 289 @Override
......
...@@ -19,6 +19,7 @@ package org.onosproject.yangutils.parser.impl.listeners; ...@@ -19,6 +19,7 @@ package org.onosproject.yangutils.parser.impl.listeners;
19 import org.onosproject.yangutils.datamodel.YangAugment; 19 import org.onosproject.yangutils.datamodel.YangAugment;
20 import org.onosproject.yangutils.datamodel.YangCase; 20 import org.onosproject.yangutils.datamodel.YangCase;
21 import org.onosproject.yangutils.datamodel.YangContainer; 21 import org.onosproject.yangutils.datamodel.YangContainer;
22 +import org.onosproject.yangutils.datamodel.YangGrouping;
22 import org.onosproject.yangutils.datamodel.YangInput; 23 import org.onosproject.yangutils.datamodel.YangInput;
23 import org.onosproject.yangutils.datamodel.YangList; 24 import org.onosproject.yangutils.datamodel.YangList;
24 import org.onosproject.yangutils.datamodel.YangModule; 25 import org.onosproject.yangutils.datamodel.YangModule;
...@@ -37,8 +38,10 @@ import static org.onosproject.yangutils.datamodel.utils.YangDataModelFactory.get ...@@ -37,8 +38,10 @@ import static org.onosproject.yangutils.datamodel.utils.YangDataModelFactory.get
37 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerCollisionDetector.detectCollidingChildUtil; 38 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerCollisionDetector.detectCollidingChildUtil;
38 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY; 39 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
39 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.EXIT; 40 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.EXIT;
40 -import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructExtendedListenerErrorMessage; 41 +import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction
41 -import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage; 42 + .constructExtendedListenerErrorMessage;
43 +import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction
44 + .constructListenerErrorMessage;
42 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER; 45 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
43 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER; 46 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER;
44 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER; 47 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
...@@ -134,7 +137,8 @@ public final class ContainerListener { ...@@ -134,7 +137,8 @@ public final class ContainerListener {
134 || curData instanceof YangList || curData instanceof YangCase 137 || curData instanceof YangList || curData instanceof YangCase
135 || curData instanceof YangNotification 138 || curData instanceof YangNotification
136 || curData instanceof YangInput || curData instanceof YangOutput 139 || curData instanceof YangInput || curData instanceof YangOutput
137 - || curData instanceof YangAugment) { 140 + || curData instanceof YangAugment
141 + || curData instanceof YangGrouping) {
138 YangNode curNode = (YangNode) curData; 142 YangNode curNode = (YangNode) curData;
139 try { 143 try {
140 curNode.addChild(container); 144 curNode.addChild(container);
...@@ -190,6 +194,6 @@ public final class ContainerListener { ...@@ -190,6 +194,6 @@ public final class ContainerListener {
190 ctx.identifier().getText()); 194 ctx.identifier().getText());
191 validateCardinalityMaxOne(ctx.referenceStatement(), REFERENCE_DATA, CONTAINER_DATA, ctx.identifier().getText()); 195 validateCardinalityMaxOne(ctx.referenceStatement(), REFERENCE_DATA, CONTAINER_DATA, ctx.identifier().getText());
192 validateCardinalityMaxOne(ctx.statusStatement(), STATUS_DATA, CONTAINER_DATA, ctx.identifier().getText()); 196 validateCardinalityMaxOne(ctx.statusStatement(), STATUS_DATA, CONTAINER_DATA, ctx.identifier().getText());
193 - // TODO when, grouping, typedef. 197 + // TODO validate 'when' cardinality
194 } 198 }
195 } 199 }
......