Bug 2363, Bug 2205. Beta version of LeafRefContext tree computation
[yangtools.git] / yang / yang-data-impl / src / main / java / org / opendaylight / yangtools / yang / data / impl / leafref / LeafRefUtils.java
1 /**
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.yangtools.yang.data.impl.leafref;
9
10 import java.util.Iterator;
11 import java.util.LinkedList;
12 import org.opendaylight.yangtools.yang.common.QName;
13 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
14 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
15 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
16 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
17 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
18 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
19 import org.opendaylight.yangtools.yang.model.api.Module;
20 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
21
22 public class LeafRefUtils {
23
24     /**
25      * @param leafRefPath
26      * @param contextNodeSchemaPath
27      * @return
28      */
29     public static LeafRefPath createAbsoluteLeafRefPath(
30             final LeafRefPath leafRefPath, final SchemaPath contextNodeSchemaPath,
31             final Module module) {
32
33         if (leafRefPath.isAbsolute())
34             return leafRefPath;
35
36         final LinkedList<QNameWithPredicate> absoluteLeafRefTargetPathList = schemaPathToXPathQNames(
37                 contextNodeSchemaPath, module);
38
39         final Iterable<QNameWithPredicate> leafRefTargetPathFromRoot = leafRefPath
40                 .getPathFromRoot();
41         final Iterator<QNameWithPredicate> leafRefTgtPathFromRootIterator = leafRefTargetPathFromRoot
42                 .iterator();
43
44         while (leafRefTgtPathFromRootIterator.hasNext()) {
45             final QNameWithPredicate qname = leafRefTgtPathFromRootIterator.next();
46             if (qname.equals(QNameWithPredicate.UP_PARENT)) {
47                 absoluteLeafRefTargetPathList.removeLast();
48             } else {
49                 absoluteLeafRefTargetPathList.add(qname);
50             }
51         }
52
53         return LeafRefPath.create(absoluteLeafRefTargetPathList, true);
54     }
55
56     /**
57      * @param currentNodePath
58      * @param module
59      * @param absoluteLeafRefTargetPathList
60      */
61     private static LinkedList<QNameWithPredicate> schemaPathToXPathQNames(
62             final SchemaPath nodePath, final Module module) {
63
64         final LinkedList<QNameWithPredicate> xpath = new LinkedList<QNameWithPredicate>();
65
66         final Iterator<QName> nodePathIterator = nodePath.getPathFromRoot()
67                 .iterator();
68
69         DataNodeContainer currenDataNodeContainer = module;
70         while (nodePathIterator.hasNext()) {
71             final QName qname = nodePathIterator.next();
72             final DataSchemaNode child = currenDataNodeContainer
73                     .getDataChildByName(qname);
74
75             if (child instanceof DataNodeContainer) {
76                 if (!(child instanceof ChoiceCaseNode)) {
77                     final QNameWithPredicate newQName = new QNameWithPredicateBuilder(
78                             qname.getModule(), qname.getLocalName()).build();
79                     xpath.add(newQName);
80                 }
81                 currenDataNodeContainer = (DataNodeContainer) child;
82             } else if (child instanceof ChoiceSchemaNode) {
83                 if (nodePathIterator.hasNext()) {
84                     currenDataNodeContainer = ((ChoiceSchemaNode) child)
85                             .getCaseNodeByName(nodePathIterator.next());
86                 } else {
87                     break;
88                 }
89             } else if (child instanceof LeafSchemaNode
90                     || child instanceof LeafListSchemaNode) {
91
92                 final QNameWithPredicate newQName = new QNameWithPredicateBuilder(
93                         qname.getModule(), qname.getLocalName()).build();
94                 xpath.add(newQName);
95                 break;
96
97             } else if (child == null) {
98                 throw new IllegalArgumentException("No child " + qname
99                         + " found in node container " + currenDataNodeContainer
100                         + " in module " + module.getName());
101             } else {
102                 throw new IllegalStateException(
103                         "Illegal schema node type in the path: "
104                                 + child.getClass());
105             }
106         }
107
108         return xpath;
109     }
110
111     public static LeafRefPath schemaPathToLeafRefPath(final SchemaPath nodePath,
112             final Module module) {
113         final LinkedList<QNameWithPredicate> xpathQNames = schemaPathToXPathQNames(
114                 nodePath, module);
115         return LeafRefPath.create(xpathQNames, true);
116     }
117
118 }