fb57d63bd4744bd89a5b3ba045258649a4b10f50
[ccsdk/sli/plugins.git] / restconf-client / provider / src / main / java / org / onap / ccsdk / sli / plugins / yangserializers / pnserializer / MdsalPropertiesNodeUtils.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - CCSDK
4  * ================================================================================
5  * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer;
22
23 import org.opendaylight.yangtools.yang.common.QName;
24 import org.opendaylight.yangtools.yang.common.Revision;
25 import org.opendaylight.yangtools.yang.data.impl.schema.SchemaUtils;
26 import org.opendaylight.yangtools.yang.data.util.ParserStreamUtils;
27 import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
28 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
29 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
30 import org.opendaylight.yangtools.yang.model.api.Module;
31 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
32 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
33
34 import java.util.Collection;
35 import java.util.Deque;
36 import java.util.Iterator;
37 import java.util.Optional;
38
39 /**
40  * Represents utilities for properties node tree.
41  */
42 public final class MdsalPropertiesNodeUtils {
43
44     private MdsalPropertiesNodeUtils() {
45     }
46
47     /**
48      * Returns the index from multi instance property name.
49      *
50      * @param name name of the property
51      * @return index from multi instance property name
52      */
53     public static String getIndex(String name) {
54         return name.substring(name.indexOf("[") + 1,
55                               name.indexOf("]"));
56     }
57
58     /**
59      * Returns the multi instance property name.
60      *
61      * @param name name of the property
62      * @return the multi instance property name
63      */
64     public static String getListName(String name) {
65         String[] s = name.split("\\[");
66         return s[0];
67     }
68
69     /**
70      * Returns true if property is multi instance.
71      *
72      * @param name name of the property
73      * @return true if property is multi instance
74      */
75     public static boolean isListEntry(String name) {
76         String s[] = name.split("\\[");
77         return s.length > 1;
78     }
79
80     /**
81      * Returns name of the property after pruning namespace and
82      * index if the property is multi instance.
83      *
84      * @param name name of the property
85      * @return name of the property
86      */
87     public static String resolveName(String name) {
88         String localName = getListName(name);
89         final int lastIndexOfColon = localName.lastIndexOf(":");
90         if (lastIndexOfColon != -1) {
91             localName = localName.substring(lastIndexOfColon + 1);
92         }
93         return localName;
94     }
95
96     /**
97      * Adds current node to parent's augmentation map.
98      *
99      * @param augSchema augment schema
100      * @param parent parent property node
101      * @param curNode current property node
102      */
103     public static void addToAugmentations(AugmentationSchemaNode augSchema,
104                                           PropertiesNode parent,
105                                           PropertiesNode curNode) {
106         Collection<PropertiesNode> childsFromAugmentation = parent
107                 .augmentations().get(augSchema);
108         if (!childsFromAugmentation.isEmpty()) {
109             for (PropertiesNode pNode : childsFromAugmentation) {
110                 if (pNode.name().equals(curNode.name())) {
111                     return;
112                 }
113             }
114         }
115         parent.augmentations().put(augSchema, curNode);
116     }
117
118
119     /**
120      * Returns augmented properties node if it is already
121      * added in properties tree.
122      *
123      * @param augSchema augmented schema node
124      * @param parent parent properties node
125      * @param name name of the properties
126      * @return augmented properties node if it is already added
127      */
128     public static PropertiesNode getAugmentationNode(
129             AugmentationSchemaNode augSchema,
130             PropertiesNode parent, String name) {
131         if (augSchema != null) {
132             Collection<PropertiesNode> childsFromAugmentation = parent
133                     .augmentations().get(augSchema);
134             if (!childsFromAugmentation.isEmpty()) {
135                 for (PropertiesNode pNode : childsFromAugmentation) {
136                     if (pNode.name().equals(name)) {
137                         return pNode;
138                     }
139                 }
140             }
141         }
142         return null;
143     }
144
145     /**
146      * Creates uri with specified name and namespace.
147      *
148      * @param parent parent properties node
149      * @param name name of the node
150      * @param ns namespace of the node
151      * @return uri with specified name and namespace
152      */
153     public static String getUri(PropertiesNode parent, String name,
154                                 Namespace ns) {
155         String uri = name;
156         if (!(parent.namespace().moduleNs().equals(ns.moduleNs()))) {
157             uri = ns.moduleName() + ":" + name;
158         }
159         return parent.uri() + "." + uri;
160     }
161
162     /**
163      * Creates new properties with specified parameters.
164      *
165      * @param name name of the properties node
166      * @param namespace namespace of the properties node
167      * @param uri uri of the properties node
168      * @param parent parent node
169      * @param appInfo application info
170      * @param type node type
171      * @return new properties node
172      */
173     public static PropertiesNode createNode(String name, Namespace namespace,
174                                             String uri, PropertiesNode parent,
175                                             Object appInfo, NodeType type) {
176         switch (type) {
177             case SINGLE_INSTANCE_NODE:
178                 return new SingleInstanceNode(name, namespace, uri, parent, appInfo, type);
179             case MULTI_INSTANCE_HOLDER_NODE:
180                 return new ListHolderNode(name, namespace, uri, parent, appInfo, type);
181             case MULTI_INSTANCE_LEAF_HOLDER_NODE:
182                 return new LeafListHolderNode(name, namespace, uri, parent, appInfo, type);
183             default:
184                 throw new RuntimeException("Invalid node type");
185         }
186     }
187
188     /**
189      * Returns true if namespace is same as parent's namespace.
190      *
191      * @param parent parent property node
192      * @param curNode current property node
193      * @return true if namespace is same as parent namespace
194      */
195     public static boolean isNamespaceAsParent(PropertiesNode parent,
196                                               PropertiesNode curNode) {
197         return parent.namespace().moduleNs().equals(curNode.namespace().moduleNs());
198     }
199
200     /**
201      * Returns namespace.
202      *
203      * @param childName name of the property
204      * @param ctx schema context
205      * @param parent parent property node
206      * @return namespace
207      */
208     public static Namespace getNamespace(String childName,
209                                          SchemaContext ctx,
210                                          PropertiesNode parent) {
211         int lastIndexOfColon = childName.lastIndexOf(":");
212         if (lastIndexOfColon != -1) {
213             String moduleName = childName.substring(0, lastIndexOfColon);
214             Iterator<Module> it = ctx.findModules(moduleName).iterator();
215             if (!it.hasNext()) {
216                 // module is not present in context
217                 return null;
218             }
219             Module m = it.next();
220             return new Namespace(moduleName, m.getQNameModule().getNamespace(),
221                                  getRevision(m.getRevision()));
222         }
223         Namespace parentNs = parent.namespace();
224         return new Namespace(parentNs.moduleName(), parentNs.moduleNs(),
225                              parentNs.revision());
226     }
227
228     /**
229      * Returns child schema node.
230      *
231      * @param curSchema current schema node
232      * @param name name of the property
233      * @param namespace namespace of the property
234      * @return child schema node
235      */
236     public static SchemaNode getChildSchemaNode(SchemaNode curSchema,
237                                                      String name,
238                                                 Namespace namespace) {
239         if (namespace == null) {
240             return null;
241         }
242
243         QName qname =  QName.create(namespace.moduleNs(),
244                                     Revision.of(namespace.revision()), name);
245
246         // YANG RPC will not be instance of DataSchemaNode
247         if (curSchema instanceof DataSchemaNode) {
248             Deque<DataSchemaNode> schemaNodeDeque = ParserStreamUtils.
249                     findSchemaNodeByNameAndNamespace(((DataSchemaNode)
250                             curSchema), name, namespace.moduleNs());
251             if (schemaNodeDeque.isEmpty()) {
252                 // could not find schema node
253                 return null;
254             }
255
256             DataSchemaNode schemaNode = schemaNodeDeque.pop();
257             if (schemaNodeDeque.isEmpty()){
258                 // Simple node
259                 return schemaNode;
260             }
261
262             // node is child of Choice/case
263             return SchemaUtils.findSchemaForChild(((ChoiceSchemaNode) schemaNode),
264                                                   qname);
265         } else {
266             return SchemaUtils.findDataChildSchemaByQName(curSchema, qname);
267         }
268     }
269
270     /**
271      * Returns the property node type.
272      *
273      * @param index current index
274      * @param length length of the properties
275      * @param name name of the property
276      * @return the property node type
277      */
278     public static NodeType getNodeType(int index, int length, String name) {
279         if (index == length-1) {
280             return (isListEntry(name) ? NodeType.MULTI_INSTANCE_LEAF_NODE :
281                     NodeType.SINGLE_INSTANCE_LEAF_NODE);
282         } else {
283             return (isListEntry(name) ? NodeType.MULTI_INSTANCE_NODE :
284                     NodeType.SINGLE_INSTANCE_NODE);
285         }
286     }
287
288     /**
289      * Returns revision in string.
290      *
291      * @param r YANG revision
292      * @return revision in string
293      */
294     public static String getRevision(Optional<Revision> r) {
295         return (r.isPresent()) ? r.get().toString() : null;
296     }
297 }