X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;ds=sidebyside;f=yang%2Fyang-data-util%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fdata%2Futil%2FDataSchemaContextNode.java;h=7f2117fcc5b41d87433455a1d19670a5d2ee771d;hb=ca61467e9c4e802584a1475da15c01cc5ea8e83a;hp=07d223346b0204332799800b9660a84a9fdcb96d;hpb=f924c20549d1b3bd10e8359e2588e19560464933;p=yangtools.git diff --git a/yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/DataSchemaContextNode.java b/yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/DataSchemaContextNode.java index 07d223346b..7f2117fcc5 100644 --- a/yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/DataSchemaContextNode.java +++ b/yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/DataSchemaContextNode.java @@ -7,22 +7,23 @@ */ package org.opendaylight.yangtools.yang.data.util; - -import com.google.common.collect.FluentIterable; import com.google.common.collect.ImmutableSet; -import java.util.Collections; -import java.util.HashSet; +import com.google.common.collect.Iterables; import java.util.List; +import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; import javax.annotation.Nullable; +import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.yangtools.concepts.Identifiable; import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode; -import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; +import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode; import org.opendaylight.yangtools.yang.model.api.AugmentationTarget; -import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode; +import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode; import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; @@ -35,26 +36,17 @@ import org.opendaylight.yangtools.yang.model.api.SchemaNode; import org.opendaylight.yangtools.yang.model.util.EffectiveAugmentationSchema; /** - * Schema derived data providing necessary information for mapping - * between {@link org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode} - * and serialization format defined in RFC6020, since the mapping - * is not one-to-one. + * Schema derived data providing necessary information for mapping between + * {@link org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode} and serialization format defined in RFC6020, + * since the mapping is not one-to-one. * * @param Path Argument type - * */ public abstract class DataSchemaContextNode implements Identifiable { - - private final T identifier; private final DataSchemaNode dataSchemaNode; - - @Override - public T getIdentifier() { - return identifier; - } + private final T identifier; protected DataSchemaContextNode(final T identifier, final SchemaNode schema) { - super(); this.identifier = identifier; if (schema instanceof DataSchemaNode) { this.dataSchemaNode = (DataSchemaNode) schema; @@ -63,6 +55,11 @@ public abstract class DataSchemaContextNode implements I } } + @Override + public T getIdentifier() { + return identifier; + } + public boolean isMixin() { return false; } @@ -71,88 +68,113 @@ public abstract class DataSchemaContextNode implements I return false; } + public abstract boolean isLeaf(); + protected Set getQNameIdentifiers() { - return Collections.singleton(identifier.getNodeType()); + return ImmutableSet.of(identifier.getNodeType()); } - public abstract @Nullable DataSchemaContextNode getChild(final PathArgument child); - - public abstract @Nullable DataSchemaContextNode getChild(QName child); - - public abstract boolean isLeaf(); + /** + * Find a child node identifier by its {@link PathArgument}. + * + * @param child Child path argument + * @return A child node, or null if not found + */ + @Nullable public abstract DataSchemaContextNode getChild(PathArgument child); + @Nullable public abstract DataSchemaContextNode getChild(QName child); - public @Nullable DataSchemaNode getDataSchemaNode() { + @Nullable public DataSchemaNode getDataSchemaNode() { return dataSchemaNode; } - static final DataSchemaNode findChildSchemaNode(final DataNodeContainer parent, final QName child) { - DataSchemaNode potential = parent.getDataChildByName(child); - if (potential == null) { - Iterable choices = FluentIterable.from( - parent.getChildNodes()).filter(ChoiceSchemaNode.class); - potential = findChoice(choices, child); + /** + * Find a child node as identified by a {@link YangInstanceIdentifier} relative to this node. + * + * @param path Path towards the child node + * @return Child node if present, or empty when corresponding child is not found. + * @throws NullPointerException if {@code path} is null + */ + public final @NonNull Optional<@NonNull DataSchemaContextNode> findChild( + final @NonNull YangInstanceIdentifier path) { + DataSchemaContextNode currentOp = this; + for (PathArgument arg : path.getPathArguments()) { + currentOp = currentOp.getChild(arg); + if (currentOp == null) { + return Optional.empty(); + } } - return potential; + return Optional.of(currentOp); + } + + static DataSchemaNode findChildSchemaNode(final DataNodeContainer parent, final QName child) { + final DataSchemaNode potential = parent.getDataChildByName(child); + return potential == null ? findChoice(Iterables.filter(parent.getChildNodes(), ChoiceSchemaNode.class), child) + : potential; } static DataSchemaContextNode fromSchemaAndQNameChecked(final DataNodeContainer schema, final QName child) { - DataSchemaNode result = findChildSchemaNode(schema, child); + final DataSchemaNode result = findChildSchemaNode(schema, child); // We try to look up if this node was added by augmentation - if ((schema instanceof DataSchemaNode) && result.isAugmenting()) { + if (result != null && schema instanceof DataSchemaNode && result.isAugmenting()) { return fromAugmentation(schema, (AugmentationTarget) schema, result); } return fromDataSchemaNode(result); } + // FIXME: this looks like it should be a Predicate on a stream with findFirst() private static ChoiceSchemaNode findChoice(final Iterable choices, final QName child) { - ChoiceSchemaNode foundChoice = null; - choiceLoop: for (ChoiceSchemaNode choice : choices) { - for (ChoiceCaseNode caze : choice.getCases()) { + for (ChoiceSchemaNode choice : choices) { + // FIXME: this looks weird: what are we looking for again? + for (CaseSchemaNode caze : choice.getCases().values()) { if (findChildSchemaNode(caze, child) != null) { - foundChoice = choice; - break choiceLoop; + return choice; } } } - return foundChoice; + return null; } - public static AugmentationIdentifier augmentationIdentifierFrom(final AugmentationSchema augmentation) { - ImmutableSet.Builder potentialChildren = ImmutableSet.builder(); - for (DataSchemaNode child : augmentation.getChildNodes()) { - potentialChildren.add(child.getQName()); - } - return new AugmentationIdentifier(potentialChildren.build()); + /** + * Create AugmentationIdentifier from an AugmentationSchemaNode. + * + * @param schema Augmentation schema + * @return AugmentationIdentifier for the schema + * @throws NullPointerException if {@code schema} is null + */ + public static AugmentationIdentifier augmentationIdentifierFrom(final AugmentationSchemaNode schema) { + return new AugmentationIdentifier(schema.getChildNodes().stream().map(DataSchemaNode::getQName) + .collect(Collectors.toSet())); } - static DataNodeContainer augmentationProxy(final AugmentationSchema augmentation, - final DataNodeContainer schema) { - Set children = new HashSet<>(); - for (DataSchemaNode augNode : augmentation.getChildNodes()) { - children.add(schema.getDataChildByName(augNode.getQName())); - } - return new EffectiveAugmentationSchema(augmentation, children); + /** + * Returns an AugmentationSchemaNode as effective in a parent node. + * + * @param schema Augmentation schema + * @param parent Parent schema + * @return Adjusted Augmentation schema + * @throws NullPointerException if any of the arguments is null + * @deprecated Use {@link EffectiveAugmentationSchema#create(AugmentationSchemaNode, DataNodeContainer)} instead. + */ + @Deprecated + public static AugmentationSchemaNode augmentationProxy(final AugmentationSchemaNode schema, + final DataNodeContainer parent) { + return EffectiveAugmentationSchema.create(schema, parent); } /** * Returns a DataContextNodeOperation for provided child node * + *

* If supplied child is added by Augmentation this operation returns a * DataContextNodeOperation for augmentation, otherwise returns a * DataContextNodeOperation for child as call for * {@link #fromDataSchemaNode(DataSchemaNode)}. - * - * - * @param parent - * @param parentAug - * @param child - * @return */ - static @Nullable DataSchemaContextNode fromAugmentation(final DataNodeContainer parent, + @Nullable static DataSchemaContextNode fromAugmentation(final DataNodeContainer parent, final AugmentationTarget parentAug, final DataSchemaNode child) { - AugmentationSchema augmentation = null; - for (AugmentationSchema aug : parentAug.getAvailableAugmentations()) { + AugmentationSchemaNode augmentation = null; + for (AugmentationSchemaNode aug : parentAug.getAvailableAugmentations()) { DataSchemaNode potential = aug.getDataChildByName(child.getQName()); if (potential != null) { augmentation = aug; @@ -165,7 +187,7 @@ public abstract class DataSchemaContextNode implements I return fromDataSchemaNode(child); } - public static @Nullable DataSchemaContextNode fromDataSchemaNode(final DataSchemaNode potential) { + @Nullable public static DataSchemaContextNode fromDataSchemaNode(final DataSchemaNode potential) { if (potential instanceof ContainerSchemaNode) { return new ContainerContextNode((ContainerSchemaNode) potential); } else if (potential instanceof ListSchemaNode) {