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=2389e503f2f1e81f4cb31515d0d5fe750190a1a5;hpb=e104e4acbc93ca8fc3694ffc4ad794204339b4fe;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 2389e503f2..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.CaseSchemaNode; import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode; -import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +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,68 +62,83 @@ 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()); } - @Nullable public abstract DataSchemaContextNode getChild(final PathArgument child); - - @Nullable public abstract 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 + */ + public abstract @Nullable DataSchemaContextNode getChild(PathArgument child); + public abstract @Nullable DataSchemaContextNode getChild(QName child); - @Nullable public DataSchemaNode getDataSchemaNode() { + public @Nullable DataSchemaNode getDataSchemaNode() { return dataSchemaNode; } - static 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.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 (result != null && (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()) { 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())); } /** @@ -144,25 +150,19 @@ public abstract class DataSchemaContextNode implements I * DataContextNodeOperation for child as call for * {@link #fromDataSchemaNode(DataSchemaNode)}. */ - @Nullable static DataSchemaContextNode fromAugmentation(final DataNodeContainer parent, + 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); } - @Nullable public static DataSchemaContextNode fromDataSchemaNode(final DataSchemaNode potential) { - if (potential instanceof ContainerSchemaNode) { - return new ContainerContextNode((ContainerSchemaNode) potential); + public static @Nullable DataSchemaContextNode fromDataSchemaNode(final DataSchemaNode potential) { + if (potential instanceof ContainerLike) { + return new ContainerContextNode((ContainerLike) potential); } else if (potential instanceof ListSchemaNode) { return fromListSchemaNode((ListSchemaNode) potential); } else if (potential instanceof LeafSchemaNode) { @@ -171,8 +171,10 @@ public abstract class DataSchemaContextNode implements I 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; } @@ -195,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); } }