+ /**
+ * 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 AugmentationSchema findCorrespondingAugment(final DataSchemaNode parent, final DataSchemaNode child) {
+ if (parent instanceof AugmentationTarget && !(parent instanceof ChoiceSchemaNode)) {
+ for (final AugmentationSchema augmentation : ((AugmentationTarget) parent).getAvailableAugmentations()) {
+ final DataSchemaNode childInAugmentation = augmentation.getDataChildByName(child.getQName());
+ if (childInAugmentation != null) {
+ return augmentation;
+ }
+ }
+ }
+ return null;
+ }
+
+ public static AugmentationIdentifier getNodeIdentifierForAugmentation(final AugmentationSchema schema) {
+ final Collection<QName> qnames = Collections2.transform(schema.getChildNodes(), DataSchemaNode::getQName);
+ return new AugmentationIdentifier(ImmutableSet.copyOf(qnames));
+ }
+
+ /**
+ * 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 = Preconditions.checkNotNull(schemaContext);
+ for (final QName qname : path.getPathFromRoot()) {
+ current = findDataChildSchemaByQName(current, qname);
+ }
+ return current;
+ }
+
+ /**
+ * Finds schema node for given path in schema context. This method performs
+ * lookup in both the namespace of groupings and the namespace of all leafs,
+ * leaf-lists, lists, containers, choices, rpcs, actions, notifications,
+ * anydatas, and anyxmls according to Rfc6050/Rfc7950 section 6.2.1.
+ *
+ * This method is deprecated, because name conflicts can occur between the
+ * namespace of groupings and namespace of data nodes and in consequence
+ * lookup could be ambiguous.
+ *
+ * @param schemaContext
+ * schema context
+ * @param path
+ * path
+ * @return schema node on path
+ *
+ * @deprecated use
+ * {@link #findParentSchemaNodesOnPath(SchemaContext, SchemaPath)}
+ * instead.
+ */
+ @Deprecated
+ public static SchemaNode findParentSchemaOnPath(final SchemaContext schemaContext, final SchemaPath path) {
+ SchemaNode current = Preconditions.checkNotNull(schemaContext);
+ for (final QName qname : path.getPathFromRoot()) {
+ current = findChildSchemaByQName(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 java.lang.IllegalArgumentException
+ * if the schema node does not allow children
+ */
+ @Nullable
+ public static SchemaNode findDataChildSchemaByQName(final SchemaNode node, final QName qname) {
+ SchemaNode child = null;
+ if (node instanceof DataNodeContainer) {
+ child = ((DataNodeContainer) node).getDataChildByName(qname);
+ if (child == null && node instanceof SchemaContext) {
+ child = tryFindRpc((SchemaContext) node, qname).orNull();
+ }
+ if (child == null && node instanceof NotificationNodeContainer) {
+ child = tryFindNotification((NotificationNodeContainer) node, qname).orNull();
+ }
+ if (child == null && node instanceof ActionNodeContainer) {
+ child = tryFindAction((ActionNodeContainer) node, qname).orNull();
+ }
+ } else if (node instanceof ChoiceSchemaNode) {
+ child = ((ChoiceSchemaNode) node).getCaseNodeByName(qname);
+ } else if (node instanceof RpcDefinition) {
+ switch (qname.getLocalName()) {
+ case "input":
+ child = ((RpcDefinition) node).getInput();
+ break;
+ case "output":
+ child = ((RpcDefinition) node).getOutput();
+ break;
+ default:
+ child = null;
+ break;
+ }
+ } else {
+ throw new IllegalArgumentException(String.format("Schema node %s does not allow children.", node));
+ }
+
+ return child;
+ }
+
+ /**
+ * Find child schema node identified by its QName within a provided schema
+ * node. This method performs lookup in both the namespace of groupings and
+ * the namespace of all leafs, leaf-lists, lists, containers, choices, rpcs,
+ * actions, notifications, anydatas, and anyxmls according to
+ * Rfc6050/Rfc7950 section 6.2.1.
+ *
+ * This method is deprecated, because name conflicts can occur between the
+ * namespace of groupings and namespace of data nodes and in consequence
+ * lookup could be ambiguous.
+ *
+ * @param node
+ * schema node
+ * @param qname
+ * QName
+ * @return child schema node
+ * @throws java.lang.IllegalArgumentException
+ * if the schema node does not allow children
+ *
+ * @deprecated use
+ * {@link #findChildSchemaNodesByQName(SchemaNode, QName)}
+ * instead.
+ */
+ @Deprecated
+ public static SchemaNode findChildSchemaByQName(final SchemaNode node, final QName qname) {
+ SchemaNode child = findDataChildSchemaByQName(node, qname);
+ if (child == null && node instanceof DataNodeContainer) {
+ child = tryFindGroupings((DataNodeContainer) node, qname).orNull();
+ }
+
+ return child;
+ }
+
+ /**
+ * Finds schema node for given path in schema context. This method performs
+ * lookup in both the namespace of groupings and the namespace of all leafs,
+ * leaf-lists, lists, containers, choices, rpcs, actions, notifications,
+ * anydatas, and anyxmls according to Rfc6050/Rfc7950 section 6.2.1.
+ *
+ * This method returns collection of SchemaNodes, because name conflicts can
+ * occur between the namespace of groupings and namespace of data nodes.
+ * This method finds and collects all schema nodes that matches supplied
+ * SchemaPath and returns them all as collection of schema nodes.
+ *
+ * @param schemaContext
+ * schema context
+ * @param path
+ * path
+ * @return collection of schema nodes on path
+ *
+ */
+ public static Collection<SchemaNode> findParentSchemaNodesOnPath(final SchemaContext schemaContext,
+ final SchemaPath path) {
+ final Collection<SchemaNode> currentNodes = new ArrayList<>();
+ final Collection<SchemaNode> childNodes = new ArrayList<>();
+ currentNodes.add(Preconditions.checkNotNull(schemaContext));
+ for (final QName qname : path.getPathFromRoot()) {
+ for (final SchemaNode current : currentNodes) {
+ childNodes.addAll(findChildSchemaNodesByQName(current, qname));
+ }
+ currentNodes.clear();
+ currentNodes.addAll(childNodes);
+ childNodes.clear();
+ }
+
+ return currentNodes;
+ }
+
+ /**
+ * Find child schema node identified by its QName within a provided schema
+ * node. This method performs lookup in both the namespace of groupings and
+ * the namespace of all leafs, leaf-lists, lists, containers, choices, rpcs,
+ * actions, notifications, anydatas, and anyxmls according to
+ * Rfc6050/Rfc7950 section 6.2.1.
+ *
+ * This method returns collection of SchemaNodes, because name conflicts can
+ * occur between the namespace of groupings and namespace of data nodes.
+ * This method finds and collects all schema nodes with supplied QName and
+ * returns them all as collection of schema nodes.
+ *
+ * @param node
+ * schema node
+ * @param qname
+ * QName
+ * @return collection of child schema nodes
+ * @throws java.lang.IllegalArgumentException
+ * if the schema node does not allow children
+ *
+ */
+ public static Collection<SchemaNode> findChildSchemaNodesByQName(final SchemaNode node, final QName qname) {
+ final List<SchemaNode> childNodes = new ArrayList<>();
+ final SchemaNode dataNode = findDataChildSchemaByQName(node, qname);
+ if (dataNode != null) {
+ childNodes.add(dataNode);
+ }
+ if (node instanceof DataNodeContainer) {
+ final SchemaNode groupingNode = tryFindGroupings((DataNodeContainer) node, qname).orNull();
+ if (groupingNode != null) {
+ childNodes.add(groupingNode);
+ }
+ }
+ return childNodes.isEmpty() ? Collections.emptyList() : ImmutableList.copyOf(childNodes);
+ }
+
+ private static Optional<SchemaNode> tryFindGroupings(final DataNodeContainer dataNodeContainer, final QName qname) {
+ return Optional
+ .fromNullable(Iterables.find(dataNodeContainer.getGroupings(), new SchemaNodePredicate(qname), null));