+ /**
+ * Tries to find in {@code parent} which is dealed as augmentation target node with QName as {@code child}. If such
+ * node is found then it is returned, else null.
+ *
+ * @param parent parent node
+ * @param child child node
+ * @return augmentation schema
+ */
+ public static AugmentationSchemaNode findCorrespondingAugment(final DataSchemaNode parent,
+ final DataSchemaNode child) {
+ if (!(parent instanceof AugmentationTarget) || parent instanceof ChoiceSchemaNode) {
+ return null;
+ }
+
+ for (final AugmentationSchemaNode augmentation : ((AugmentationTarget) parent).getAvailableAugmentations()) {
+ final Optional<DataSchemaNode> childInAugmentation = augmentation.findDataChildByName(child.getQName());
+ if (childInAugmentation.isPresent()) {
+ return augmentation;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Finds schema node for given path in schema context. This method performs
+ * lookup in the namespace of all leafs, leaf-lists, lists, containers,
+ * choices, rpcs, actions, notifications, anydatas, and anyxmls according to
+ * Rfc6050/Rfc7950 section 6.2.1.
+ *
+ * @param schemaContext
+ * schema context
+ * @param path
+ * path
+ * @return schema node on path
+ */
+ public static SchemaNode findDataParentSchemaOnPath(final SchemaContext schemaContext, final SchemaPath path) {
+ SchemaNode current = requireNonNull(schemaContext);
+ for (final QName qname : path.getPathFromRoot()) {
+ current = findDataChildSchemaByQName(current, qname);
+ }
+ return current;
+ }
+
+ /**
+ * Find child data schema node identified by its QName within a provided schema node. This method performs lookup
+ * in the namespace of all leafs, leaf-lists, lists, containers, choices, rpcs, actions, notifications, anydatas
+ * and anyxmls according to RFC6050/RFC7950 section 6.2.1.
+ *
+ * @param node
+ * schema node
+ * @param qname
+ * QName
+ * @return data child schema node
+ * @throws IllegalArgumentException
+ * if the schema node does not allow children
+ */
+ public static @Nullable SchemaNode findDataChildSchemaByQName(final SchemaNode node, final QName qname) {
+ if (node instanceof DataNodeContainer) {
+ SchemaNode child = ((DataNodeContainer) node).dataChildByName(qname);
+ if (child == null && node instanceof SchemaContext) {
+ child = tryFind(((SchemaContext) node).getOperations(), qname).orElse(null);
+ }
+ if (child == null && node instanceof NotificationNodeContainer) {
+ child = tryFind(((NotificationNodeContainer) node).getNotifications(), qname).orElse(null);
+ }
+ if (child == null && node instanceof ActionNodeContainer) {
+ child = tryFind(((ActionNodeContainer) node).getActions(), qname).orElse(null);
+ }
+
+ return child;
+ }
+ if (node instanceof ChoiceSchemaNode) {
+ return ((ChoiceSchemaNode) node).findCase(qname).orElse(null);
+ }
+ if (node instanceof OperationDefinition) {
+ switch (qname.getLocalName()) {
+ case "input":
+ return ((OperationDefinition) node).getInput();
+ case "output":
+ return ((OperationDefinition) node).getOutput();
+ default:
+ return null;
+ }
+ }
+
+ throw new IllegalArgumentException(String.format("Schema node %s does not allow children.", node));