Migrate openconfig-model-api to bnd-parent
[yangtools.git] / data / yang-data-util / src / main / java / org / opendaylight / yangtools / yang / data / util / ParserStreamUtils.java
1 /*
2  * Copyright (c) 2016 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
9 package org.opendaylight.yangtools.yang.data.util;
10
11 import java.util.ArrayDeque;
12 import java.util.ArrayList;
13 import java.util.Deque;
14 import org.opendaylight.yangtools.yang.common.Revision;
15 import org.opendaylight.yangtools.yang.common.XMLNamespace;
16 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
17 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
18 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
19
20 public final class ParserStreamUtils {
21     private ParserStreamUtils() {
22         // Hidden on purpose
23     }
24
25     /**
26      * Returns stack of schema nodes via which it was necessary to pass to get schema node with specified
27      * {@code childName} and {@code namespace}.
28      *
29      * @return stack of schema nodes via which it was passed through. If found schema node is direct child then stack
30      *         contains only one node. If it is found under choice and case then stack should contains 2*n+1 element
31      *         (where n is number of choices through it was passed)
32      */
33     public static Deque<DataSchemaNode> findSchemaNodeByNameAndNamespace(final DataSchemaNode dataSchemaNode,
34             final String childName, final XMLNamespace namespace) {
35         final var result = new ArrayDeque<DataSchemaNode>();
36         final var childChoices = new ArrayList<ChoiceSchemaNode>();
37         DataSchemaNode potentialChildNode = null;
38         if (dataSchemaNode instanceof DataNodeContainer dataContainer) {
39             for (final var childNode : dataContainer.getChildNodes()) {
40                 if (childNode instanceof ChoiceSchemaNode choice) {
41                     childChoices.add(choice);
42                 } else {
43                     final var childQName = childNode.getQName();
44                     if (childQName.getLocalName().equals(childName) && childQName.getNamespace().equals(namespace)
45                             && (potentialChildNode == null || Revision.compare(childQName.getRevision(),
46                                 potentialChildNode.getQName().getRevision()) > 0)) {
47                         potentialChildNode = childNode;
48                     }
49                 }
50             }
51         }
52         if (potentialChildNode != null) {
53             result.push(potentialChildNode);
54             return result;
55         }
56
57         // try to find data schema node in choice (looking for first match)
58         for (final var choiceNode : childChoices) {
59             for (final var concreteCase : choiceNode.getCases()) {
60                 final var resultFromRecursion = findSchemaNodeByNameAndNamespace(concreteCase, childName, namespace);
61                 if (!resultFromRecursion.isEmpty()) {
62                     resultFromRecursion.push(concreteCase);
63                     resultFromRecursion.push(choiceNode);
64                     return resultFromRecursion;
65                 }
66             }
67         }
68         return result;
69     }
70 }