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