X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-data-util%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fdata%2Futil%2FDataSchemaContextNode.java;h=8070db3c3170e30fa8c917e5408d2be5fb65fabc;hb=bb60da5fe2d1928defb46ed92b290cfff93dcd81;hp=050255e921b5ddac6595328afcde71c507b09a36;hpb=052bd27d118a2addb3eae2253515890369a60182;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 050255e921..8070db3c31 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,55 +7,46 @@ */ 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 javax.annotation.Nullable; -import org.opendaylight.yangtools.concepts.Identifiable; +import java.util.stream.Collectors; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.opendaylight.yangtools.concepts.AbstractIdentifiable; 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.AnydataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.AnyxmlSchemaNode; +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.ChoiceNode; -import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ContainerLike; import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; -import org.opendaylight.yangtools.yang.model.api.SchemaContext; 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; +public abstract class DataSchemaContextNode extends AbstractIdentifiable { private final DataSchemaNode dataSchemaNode; - @Override - public T getIdentifier() { - return identifier; - }; - protected DataSchemaContextNode(final T identifier, final SchemaNode schema) { - super(); - this.identifier = identifier; + super(identifier); if (schema instanceof DataSchemaNode) { this.dataSchemaNode = (DataSchemaNode) schema; } else { @@ -71,114 +62,119 @@ public abstract class DataSchemaContextNode implements I return false; } + public abstract boolean isLeaf(); + protected Set getQNameIdentifiers() { - return Collections.singleton(identifier.getNodeType()); + return ImmutableSet.of(getIdentifier().getNodeType()); } - public abstract @Nullable DataSchemaContextNode getChild(final PathArgument child); + /** + * Find a child node identifier by its {@link PathArgument}. + * + * @param child Child path argument + * @return A child node, or null if not found + */ + public abstract @Nullable DataSchemaContextNode getChild(PathArgument child); public abstract @Nullable DataSchemaContextNode getChild(QName child); - public abstract boolean isLeaf(); - - public @Nullable 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(ChoiceNode.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.dataChildByName(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); } - private static org.opendaylight.yangtools.yang.model.api.ChoiceNode findChoice( - final Iterable choices, final QName child) { - org.opendaylight.yangtools.yang.model.api.ChoiceNode foundChoice = null; - choiceLoop: for (org.opendaylight.yangtools.yang.model.api.ChoiceNode choice : choices) { - for (ChoiceCaseNode caze : choice.getCases()) { + // FIXME: this looks like it should be a Predicate on a stream with findFirst() + private static ChoiceSchemaNode findChoice(final Iterable choices, final QName child) { + for (ChoiceSchemaNode choice : choices) { + // FIXME: this looks weird: what are we looking for again? + for (CaseSchemaNode caze : choice.getCases()) { if (findChildSchemaNode(caze, child) != null) { - foundChoice = choice; - break choiceLoop; + return choice; } } } - return foundChoice; - } - - 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()); + return null; } - 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); + /** + * 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())); } /** * 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, final AugmentationTarget parentAug, final DataSchemaNode child) { - AugmentationSchema augmentation = null; - for (AugmentationSchema aug : parentAug.getAvailableAugmentations()) { - DataSchemaNode potential = aug.getDataChildByName(child.getQName()); - if (potential != null) { - augmentation = aug; - break; + for (AugmentationSchemaNode aug : parentAug.getAvailableAugmentations()) { + if (aug.findDataChildByName(child.getQName()).isPresent()) { + return new AugmentationContextNode(aug, parent); } } - if (augmentation != null) { - return new AugmentationContextNode(augmentation, parent); - } return fromDataSchemaNode(child); } public static @Nullable DataSchemaContextNode fromDataSchemaNode(final DataSchemaNode potential) { - if (potential instanceof ContainerSchemaNode) { - return new ContainerContextNode((ContainerSchemaNode) potential); + if (potential instanceof ContainerLike) { + return new ContainerContextNode((ContainerLike) potential); } else if (potential instanceof ListSchemaNode) { return fromListSchemaNode((ListSchemaNode) potential); } else if (potential instanceof LeafSchemaNode) { return new LeafContextNode((LeafSchemaNode) potential); - } else if (potential instanceof org.opendaylight.yangtools.yang.model.api.ChoiceNode) { - return new ChoiceNodeContextNode((org.opendaylight.yangtools.yang.model.api.ChoiceNode) potential); + } else if (potential instanceof ChoiceSchemaNode) { + return new ChoiceNodeContextNode((ChoiceSchemaNode) potential); } else if (potential instanceof LeafListSchemaNode) { return fromLeafListSchemaNode((LeafListSchemaNode) potential); - } else if (potential instanceof AnyXmlSchemaNode) { - return new AnyXmlContextNode((AnyXmlSchemaNode) potential); + } else if (potential instanceof AnydataSchemaNode) { + return new AnydataContextNode((AnydataSchemaNode) potential); + } else if (potential instanceof AnyxmlSchemaNode) { + return new AnyXmlContextNode((AnyxmlSchemaNode) potential); } return null; } @@ -201,7 +197,7 @@ public abstract class DataSchemaContextNode implements I return new UnorderedLeafListMixinContextNode(potential); } - public static DataSchemaContextNode from(final SchemaContext ctx) { + public static DataSchemaContextNode from(final EffectiveModelContext ctx) { return new ContainerContextNode(ctx); } }