Address review comments
[controller.git] / opendaylight / md-sal / sal-dom-broker / src / main / java / org / opendaylight / controller / sal / dom / broker / util / YangSchemaUtils.java
1 /*
2  * Copyright (c) 2014 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.controller.sal.dom.broker.util;
9
10 import static com.google.common.base.Preconditions.checkArgument;
11 import static com.google.common.base.Preconditions.checkState;
12
13 import com.google.common.base.Function;
14 import com.google.common.collect.FluentIterable;
15
16 import java.util.Iterator;
17 import java.util.List;
18 import java.util.Set;
19
20 import org.opendaylight.yangtools.yang.common.QName;
21 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
22 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
23 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
24 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
25 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
26 import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
27 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
28 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
29 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
30 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
31 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
32 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
33 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
34 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
35 import org.opendaylight.yangtools.yang.model.api.Status;
36 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
37 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
38 import org.opendaylight.yangtools.yang.model.api.UsesNode;
39
40 public final class YangSchemaUtils {
41
42     private static final Function<PathArgument, QName> QNAME_FROM_PATH_ARGUMENT = new Function<PathArgument, QName>(){
43
44         @Override
45         public QName apply(final PathArgument input) {
46             if(input == null) {
47                 return null;
48             }
49             return input.getNodeType();
50         }
51     };
52
53     private YangSchemaUtils() {
54         throw new UnsupportedOperationException("Utility class.");
55     }
56
57     public static DataSchemaNode getSchemaNode(final SchemaContext schema,final YangInstanceIdentifier path) {
58         checkArgument(schema != null,"YANG Schema must not be null.");
59         checkArgument(path != null,"Path must not be null.");
60         return getSchemaNode(schema, FluentIterable.from(path.getPathArguments()).transform(QNAME_FROM_PATH_ARGUMENT));
61     }
62
63     public static DataSchemaNode getSchemaNode(final SchemaContext schema,final Iterable<QName> path) {
64         checkArgument(schema != null,"YANG Schema must not be null.");
65         checkArgument(path != null,"Path must not be null.");
66         if(!path.iterator().hasNext()){
67             return toRootDataNode(schema);
68         }
69
70         QName firstNode = path.iterator().next();
71         DataNodeContainer previous = schema.findModuleByNamespaceAndRevision(firstNode.getNamespace(),
72                 firstNode.getRevision());
73         Iterator<QName> iterator = path.iterator();
74
75         while (iterator.hasNext()) {
76             checkArgument(previous!= null, "Supplied path does not resolve into valid schema node.");
77             QName arg = iterator.next();
78             DataSchemaNode currentNode = previous.getDataChildByName(arg);
79             if (currentNode == null && previous instanceof DataNodeContainer) {
80                 currentNode = searchInChoices(previous, arg);
81             }
82             if (currentNode instanceof DataNodeContainer) {
83                 previous = (DataNodeContainer) currentNode;
84             } else if (currentNode instanceof LeafSchemaNode || currentNode instanceof LeafListSchemaNode) {
85                 checkArgument(!iterator.hasNext(), "Path nests inside leaf node, which is not allowed.");
86                 return currentNode;
87             }
88             checkState(currentNode != null, "Current node should not be null for %s",path);
89         }
90         checkState(previous instanceof DataSchemaNode, "Schema node for %s should be instance of DataSchemaNode. Found %s",path,previous);
91         return (DataSchemaNode) previous;
92     }
93
94     private static DataSchemaNode searchInChoices(final DataNodeContainer node, final QName arg) {
95         for (DataSchemaNode child : node.getChildNodes()) {
96             if (child instanceof ChoiceSchemaNode) {
97                 ChoiceSchemaNode choiceNode = (ChoiceSchemaNode) child;
98                 DataSchemaNode potential = searchInCases(choiceNode, arg);
99                 if (potential != null) {
100                     return potential;
101                 }
102             }
103         }
104         return null;
105     }
106
107     private static DataSchemaNode searchInCases(final ChoiceSchemaNode choiceNode, final QName arg) {
108         Set<ChoiceCaseNode> cases = choiceNode.getCases();
109         for (ChoiceCaseNode caseNode : cases) {
110             DataSchemaNode node = caseNode.getDataChildByName(arg);
111             if (node != null) {
112                 return node;
113             }
114         }
115         return null;
116     }
117
118     private static ContainerSchemaNode toRootDataNode(final SchemaContext schema) {
119         return new NetconfDataRootNode(schema);
120     }
121
122     private static final class NetconfDataRootNode implements ContainerSchemaNode {
123
124         public NetconfDataRootNode(final SchemaContext schema) {
125             // TODO Auto-generated constructor stub
126         }
127
128         @Override
129         public Set<TypeDefinition<?>> getTypeDefinitions() {
130             // TODO Auto-generated method stub
131             return null;
132         }
133
134         @Override
135         public Set<DataSchemaNode> getChildNodes() {
136             // TODO Auto-generated method stub
137             return null;
138         }
139
140         @Override
141         public Set<GroupingDefinition> getGroupings() {
142             // TODO Auto-generated method stub
143             return null;
144         }
145
146         @Override
147         public DataSchemaNode getDataChildByName(final QName name) {
148             // TODO Auto-generated method stub
149             return null;
150         }
151
152         @Override
153         public DataSchemaNode getDataChildByName(final String name) {
154             // TODO Auto-generated method stub
155             return null;
156         }
157
158         @Override
159         public Set<UsesNode> getUses() {
160             // TODO Auto-generated method stub
161             return null;
162         }
163
164         @Override
165         public Set<AugmentationSchema> getAvailableAugmentations() {
166             // TODO Auto-generated method stub
167             return null;
168         }
169
170         @Override
171         public boolean isAugmenting() {
172             // TODO Auto-generated method stub
173             return false;
174         }
175
176         @Override
177         public boolean isAddedByUses() {
178             // TODO Auto-generated method stub
179             return false;
180         }
181
182         @Override
183         public boolean isConfiguration() {
184             // TODO Auto-generated method stub
185             return false;
186         }
187
188         @Override
189         public ConstraintDefinition getConstraints() {
190             // TODO Auto-generated method stub
191             return null;
192         }
193
194         @Override
195         public QName getQName() {
196             // TODO Auto-generated method stub
197             return null;
198         }
199
200         @Override
201         public SchemaPath getPath() {
202             // TODO Auto-generated method stub
203             return null;
204         }
205
206         @Override
207         public String getDescription() {
208             // TODO Auto-generated method stub
209             return null;
210         }
211
212         @Override
213         public String getReference() {
214             // TODO Auto-generated method stub
215             return null;
216         }
217
218         @Override
219         public Status getStatus() {
220             // TODO Auto-generated method stub
221             return null;
222         }
223
224         @Override
225         public List<UnknownSchemaNode> getUnknownSchemaNodes() {
226             // TODO Auto-generated method stub
227             return null;
228         }
229
230         @Override
231         public boolean isPresenceContainer() {
232             // TODO Auto-generated method stub
233             return false;
234         }
235
236     }
237
238 }