Committed by
Gerrit Code Review
YANG uses Intra file linking
Change-Id: I45936bee910ba4c81805f59daf2702bea5e60d08
Showing
5 changed files
with
191 additions
and
34 deletions
... | @@ -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 | ... | ... |
utils/yangutils/src/main/java/org/onosproject/yangutils/parser/impl/listeners/ContainerListener.java
... | @@ -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 | } | ... | ... |
-
Please register or login to post a comment