2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.onap.ccsdk.sli.plugins.yangserializers.pnserializer;
23 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
24 import org.opendaylight.yangtools.yang.common.QName;
25 import org.opendaylight.yangtools.yang.common.Revision;
26 import org.opendaylight.yangtools.yang.data.impl.schema.SchemaUtils;
27 import org.opendaylight.yangtools.yang.data.util.ParserStreamUtils;
28 import org.opendaylight.yangtools.yang.data.util.codec.IdentityCodecUtil;
29 import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
30 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
31 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
32 import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
33 import org.opendaylight.yangtools.yang.model.api.Module;
34 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
35 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
37 import java.util.Collection;
38 import java.util.Deque;
39 import java.util.Iterator;
40 import java.util.Optional;
42 import static com.google.common.base.Preconditions.checkArgument;
45 * Represents utilities for properties node tree.
47 public final class MdsalPropertiesNodeUtils {
49 private MdsalPropertiesNodeUtils() {
53 * Returns the index from multi instance property name.
55 * @param name name of the property
56 * @return index from multi instance property name
58 public static String getIndex(String name) {
59 return name.substring(name.indexOf("[") + 1,
64 * Returns the multi instance property name.
66 * @param name name of the property
67 * @return the multi instance property name
69 public static String getListName(String name) {
70 String[] s = name.split("\\[");
75 * Returns true if property is multi instance.
77 * @param name name of the property
78 * @return true if property is multi instance
80 public static boolean isListEntry(String name) {
81 String s[] = name.split("\\[");
86 * Returns name of the property after pruning namespace and
87 * index if the property is multi instance.
89 * @param name name of the property
90 * @return name of the property
92 public static String resolveName(String name) {
93 String localName = getListName(name);
94 final int lastIndexOfColon = localName.lastIndexOf(":");
95 if (lastIndexOfColon != -1) {
96 localName = localName.substring(lastIndexOfColon + 1);
102 * Adds current node to parent's augmentation map.
104 * @param augSchema augment schema
105 * @param parent parent property node
106 * @param curNode current property node
108 public static void addToAugmentations(AugmentationSchemaNode augSchema,
109 PropertiesNode parent,
110 PropertiesNode curNode) {
111 Collection<PropertiesNode> childsFromAugmentation = parent
112 .augmentations().get(augSchema);
113 if (!childsFromAugmentation.isEmpty()) {
114 for (PropertiesNode pNode : childsFromAugmentation) {
115 if (pNode.name().equals(curNode.name())) {
120 parent.augmentations().put(augSchema, curNode);
125 * Returns augmented properties node if it is already
126 * added in properties tree.
128 * @param augSchema augmented schema node
129 * @param parent parent properties node
130 * @param name name of the properties
131 * @return augmented properties node if it is already added
133 public static PropertiesNode getAugmentationNode(
134 AugmentationSchemaNode augSchema,
135 PropertiesNode parent, String name) {
136 if (augSchema != null) {
137 Collection<PropertiesNode> childsFromAugmentation = parent
138 .augmentations().get(augSchema);
139 if (!childsFromAugmentation.isEmpty()) {
140 for (PropertiesNode pNode : childsFromAugmentation) {
141 if (pNode.name().equals(name)) {
151 * Creates uri with specified name and namespace.
153 * @param parent parent properties node
154 * @param name name of the node
155 * @param ns namespace of the node
156 * @return uri with specified name and namespace
158 public static String getUri(PropertiesNode parent, String name,
161 if (!(parent.namespace().moduleNs().equals(ns.moduleNs()))) {
162 uri = ns.moduleName() + ":" + name;
164 return parent.uri() + "." + uri;
168 * Creates new properties with specified parameters.
170 * @param name name of the properties node
171 * @param namespace namespace of the properties node
172 * @param uri uri of the properties node
173 * @param parent parent node
174 * @param appInfo application info
175 * @param type node type
176 * @return new properties node
178 public static PropertiesNode createNode(String name, Namespace namespace,
179 String uri, PropertiesNode parent,
180 Object appInfo, NodeType type) {
182 case SINGLE_INSTANCE_NODE:
183 return new SingleInstanceNode(name, namespace, uri, parent, appInfo, type);
184 case MULTI_INSTANCE_HOLDER_NODE:
185 return new ListHolderNode(name, namespace, uri, parent, appInfo, type);
186 case MULTI_INSTANCE_LEAF_HOLDER_NODE:
187 return new LeafListHolderNode(name, namespace, uri, parent, appInfo, type);
189 throw new RuntimeException("Invalid node type");
194 * Returns true if namespace is same as parent's namespace.
196 * @param parent parent property node
197 * @param curNode current property node
198 * @return true if namespace is same as parent namespace
200 public static boolean isNamespaceAsParent(PropertiesNode parent,
201 PropertiesNode curNode) {
202 return parent.namespace().moduleNs().equals(curNode.namespace().moduleNs());
208 * @param childName name of the property
209 * @param ctx schema context
210 * @param parent parent property node
213 public static Namespace getNamespace(String childName,
215 PropertiesNode parent) {
216 int lastIndexOfColon = childName.lastIndexOf(":");
217 if (lastIndexOfColon != -1) {
218 String moduleName = childName.substring(0, lastIndexOfColon);
219 Iterator<Module> it = ctx.findModules(moduleName).iterator();
221 // module is not present in context
224 Module m = it.next();
225 return new Namespace(moduleName, m.getQNameModule().getNamespace(),
226 getRevision(m.getRevision()));
228 Namespace parentNs = parent.namespace();
229 return new Namespace(parentNs.moduleName(), parentNs.moduleNs(),
230 parentNs.revision());
234 * Returns child schema node.
236 * @param curSchema current schema node
237 * @param name name of the property
238 * @param namespace namespace of the property
239 * @return child schema node
241 public static SchemaNode getChildSchemaNode(SchemaNode curSchema,
243 Namespace namespace) {
244 if (namespace == null) {
248 QName qname = QName.create(namespace.moduleNs(),
249 Revision.of(namespace.revision()), name);
251 // YANG RPC will not be instance of DataSchemaNode
252 if (curSchema instanceof DataSchemaNode) {
253 Deque<DataSchemaNode> schemaNodeDeque = ParserStreamUtils.
254 findSchemaNodeByNameAndNamespace(((DataSchemaNode)
255 curSchema), name, namespace.moduleNs());
256 if (schemaNodeDeque.isEmpty()) {
257 // could not find schema node
261 DataSchemaNode schemaNode = schemaNodeDeque.pop();
262 if (schemaNodeDeque.isEmpty()){
267 // node is child of Choice/case
268 return SchemaUtils.findSchemaForChild(((ChoiceSchemaNode) schemaNode),
271 return SchemaUtils.findDataChildSchemaByQName(curSchema, qname);
276 * Returns the property node type.
278 * @param index current index
279 * @param length length of the properties
280 * @param name name of the property
281 * @return the property node type
283 public static NodeType getNodeType(int index, int length, String name) {
284 if (index == length-1) {
285 return (isListEntry(name) ? NodeType.MULTI_INSTANCE_LEAF_NODE :
286 NodeType.SINGLE_INSTANCE_LEAF_NODE);
288 return (isListEntry(name) ? NodeType.MULTI_INSTANCE_NODE :
289 NodeType.SINGLE_INSTANCE_NODE);
294 * Returns revision in string.
296 * @param r YANG revision
297 * @return revision in string
299 public static String getRevision(Optional<Revision> r) {
300 return (r.isPresent()) ? r.get().toString() : null;
304 * Returns value namespace for leaf value.
306 * @param value value of the leaf
307 * @param ctx schema context
308 * @return value namespace
309 * @throws SvcLogicException if identity/module could not be found
311 static Namespace getValueNamespace(String value,
313 throws SvcLogicException {
314 String prefix = getPrefixFromValue(value);
315 if (prefix == null) {
319 IdentitySchemaNode id = IdentityCodecUtil.parseIdentity(value,
322 final Iterator<Module> modules = ctx.findModules(prefix).iterator();
323 checkArgument(modules.hasNext(), "Could not find " +
324 "module %s", prefix);
325 return modules.next().getQNameModule();
329 throw new SvcLogicException("Could not find identity");
332 return getModuleNamespace(id.getQName(), ctx);
335 private static String getPrefixFromValue(String value) {
336 int lastIndexOfColon = value.lastIndexOf(":");
337 if (lastIndexOfColon != -1) {
338 return value.substring(0, lastIndexOfColon);
344 * Returns module namespace from a given qName.
346 * @param qName qName of a node
347 * @param ctx schema context
348 * @return module namespace of the node
349 * @throws SvcLogicException when the module is not available
351 public static Namespace getModuleNamespace(QName qName, SchemaContext ctx)
352 throws SvcLogicException {
353 Optional<Module> module = ctx.findModule(qName.getModule());
354 if (!module.isPresent()) {
355 throw new SvcLogicException("Could not find module node");
357 Module m = module.get();
358 return new Namespace(m.getName(), m.getQNameModule().getNamespace(),
359 getRevision(m.getRevision()));
362 static String getParsedValue(Namespace valNs, String value) {
363 if (valNs != null && value.contains(":")) {
364 String[] valArr = value.split(":");