import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
import org.opendaylight.yangtools.yang.data.api.codec.InstanceIdentifierCodec;
+import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode.Composite;
import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode.PathMixin;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.util.LeafrefResolver;
DataSchemaContextNode current = getDataContextTree().getRoot();
QNameModule lastModule = null;
for (var arg : data.getPathArguments()) {
- current = current.getChild(arg);
+ current = current instanceof Composite composite ? composite.getChild(arg) : null;
checkArgument(current != null, "Invalid input %s: schema for argument %s (after %s) not found", data, arg,
sb);
import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
+import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode.Composite;
import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode.PathMixin;
import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode.SimpleValue;
+import org.opendaylight.yangtools.yang.data.util.impl.legacy.AbstractCompositeContextNode;
import org.opendaylight.yangtools.yang.data.util.impl.legacy.AbstractDataSchemaContextNode;
import org.opendaylight.yangtools.yang.data.util.impl.legacy.AbstractMixinContextNode;
import org.opendaylight.yangtools.yang.data.util.impl.legacy.LeafContextNode;
* {@link org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode} and serialization format defined in RFC6020,
* since the mapping is not one-to-one.
*/
-public sealed interface DataSchemaContextNode permits AbstractDataSchemaContextNode, PathMixin, SimpleValue {
+public sealed interface DataSchemaContextNode permits AbstractDataSchemaContextNode, Composite, PathMixin, SimpleValue {
+ /**
+ * A {@link DataSchemaContextNode} containing other {@link DataSchemaContextNode}s.
+ */
+ sealed interface Composite extends DataSchemaContextNode permits AbstractCompositeContextNode {
+ /**
+ * Find a child node identifier by its {@link PathArgument}.
+ *
+ * @param child Child path argument
+ * @return A child node, or null if not found
+ */
+ // FIXME: YANGTOOLS-1413: document PathArgument type mismatch, nullness and also rename it to 'childForArg'
+ @Nullable DataSchemaContextNode getChild(PathArgument child);
+
+ /**
+ * Find a child node identifier by its {code data tree} {@link QName}. This method returns intermediate nodes
+ * significant from {@link YangInstanceIdentifier} hierarchy of {@link PathArgument}s. If the returned node
+ * indicates is also a {@link PathMixin}, it represents a {@link NormalizedNode} encapsulation which is not
+ * visible in RFC7950 XML encoding, and a further call to this method with the same {@code child} argument will
+ * provide the next step.
+ *
+ * @param child Child data tree QName
+ * @return A child node, or null if not found
+ */
+ // FIXME: YANGTOOLS-1413: document child == null, also rename to 'childForQName'
+ @Nullable DataSchemaContextNode getChild(QName 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
+ */
+ // FIXME: YANGTOOLS-1413: rename add a childForPath() method and rename this to 'findChildForPath'
+ default @NonNull Optional<@NonNull DataSchemaContextNode> findChild(
+ final @NonNull YangInstanceIdentifier path) {
+ final var it = path.getPathArguments().iterator();
+ if (!it.hasNext()) {
+ return Optional.of(this);
+ }
+
+ var current = this;
+ while (true) {
+ final var child = current.getChild(it.next());
+ if (child == null) {
+ return Optional.empty();
+ }
+ if (!it.hasNext()) {
+ return Optional.of(child);
+ }
+ if (!(child instanceof Composite compositeChild)) {
+ return Optional.empty();
+ }
+ current = compositeChild;
+ }
+ }
+
+ /**
+ * Attempt to enter a child {@link DataSchemaContextNode} towards the {@link DataSchemaNode} child identified by
+ * specified {@code data tree} {@link QName}, adjusting provided {@code stack} with inference steps
+ * corresponding to the transition to the returned node. The stack is expected to be correctly pointing at this
+ * node's schema, otherwise the results of this method are undefined.
+ *
+ * @param stack {@link SchemaInferenceStack} to update
+ * @param child Child QName
+ * @return A DataSchemaContextNode on the path towards the specified child
+ * @throws NullPointerException if any argument is {@code null}
+ */
+ @Nullable DataSchemaContextNode enterChild(SchemaInferenceStack stack, QName child);
+
+ /**
+ * Attempt to enter a child {@link DataSchemaContextNode} towards the {@link DataSchemaNode} child identified by
+ * specified {@link PathArgument}, adjusting provided {@code stack} with inference steps corresponding to
+ * the transition to the returned node. The stack is expected to be correctly pointing at this node's schema,
+ * otherwise the results of this method are undefined.
+ *
+ * @param stack {@link SchemaInferenceStack} to update
+ * @param child Child path argument
+ * @return A DataSchemaContextNode for the specified child
+ * @throws NullPointerException if any argument is {@code null}
+ */
+ @Nullable DataSchemaContextNode enterChild(SchemaInferenceStack stack, PathArgument child);
+ }
+
/**
* This node is a {@link NormalizedNode} intermediate, not represented in RFC7950 XML encoding. This is typically
* one of
}
throw new UnsupportedOperationException(this + " does not have a fixed path step");
}
-
- /**
- * Find a child node identifier by its {@link PathArgument}.
- *
- * @param child Child path argument
- * @return A child node, or null if not found
- */
- // FIXME: YANGTOOLS-1413: document PathArgument type mismatch, nullness and also rename it to 'childForArg'
- @Nullable DataSchemaContextNode getChild(PathArgument child);
-
- /**
- * Find a child node identifier by its {code data tree} {@link QName}. This method returns intermediate nodes
- * significant from {@link YangInstanceIdentifier} hierarchy of {@link PathArgument}s. If the returned node
- * indicates is also a {@link PathMixin}, it represents a {@link NormalizedNode} encapsulation which is not visible
- * in RFC7950 XML encoding, and a further call to this method with the same {@code child} argument will provide the
- * next step.
- *
- * @param child Child data tree QName
- * @return A child node, or null if not found
- */
- // FIXME: YANGTOOLS-1413: document child == null, also rename to 'childForQName'
- @Nullable DataSchemaContextNode getChild(QName 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
- */
- // FIXME: YANGTOOLS-1413: rename add a childForPath() method and rename this to 'findChildForPath'
- default @NonNull Optional<@NonNull DataSchemaContextNode> findChild(final @NonNull YangInstanceIdentifier path) {
- var currentOp = this;
- for (var arg : path.getPathArguments()) {
- currentOp = currentOp.getChild(arg);
- if (currentOp == null) {
- return Optional.empty();
- }
- }
- return Optional.of(currentOp);
- }
-
- /**
- * Attempt to enter a child {@link DataSchemaContextNode} towards the {@link DataSchemaNode} child identified by
- * specified {@code data tree} {@link QName}, adjusting provided {@code stack} with inference steps corresponding to
- * the transition to the returned node. The stack is expected to be correctly pointing at this node's schema,
- * otherwise the results of this method are undefined.
- *
- * @param stack {@link SchemaInferenceStack} to update
- * @param child Child QName
- * @return A DataSchemaContextNode on the path towards the specified child
- * @throws NullPointerException if any argument is {@code null}
- */
- @Nullable DataSchemaContextNode enterChild(SchemaInferenceStack stack, QName child);
-
- /**
- * Attempt to enter a child {@link DataSchemaContextNode} towards the {@link DataSchemaNode} child identified by
- * specified {@link PathArgument}, adjusting provided {@code stack} with inference steps corresponding to
- * the transition to the returned node. The stack is expected to be correctly pointing at this node's schema,
- * otherwise the results of this method are undefined.
- *
- * @param stack {@link SchemaInferenceStack} to update
- * @param child Child path argument
- * @return A DataSchemaContextNode for the specified child
- * @throws NullPointerException if any argument is {@code null}
- */
- @Nullable DataSchemaContextNode enterChild(SchemaInferenceStack stack, PathArgument child);
}
import org.opendaylight.yangtools.concepts.CheckedValue;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode.Composite;
import org.opendaylight.yangtools.yang.data.util.impl.legacy.ContainerContextNode;
import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
import org.opendaylight.yangtools.yang.model.spi.AbstractEffectiveModelContextProvider;
final var stack = SchemaInferenceStack.of((EffectiveModelContext) root.getDataSchemaNode());
DataSchemaContextNode node = root;
for (var arg : path.getPathArguments()) {
- final var child = node.enterChild(stack, arg);
+ final var child = node instanceof Composite composite ? composite.enterChild(stack, arg) : null;
if (child == null) {
return CheckedValue.ofException(new IllegalArgumentException("Failed to find " + arg + " in " + node));
}
return CheckedValue.ofValue(new NodeAndStack(node, stack));
}
- public @NonNull DataSchemaContextNode getRoot() {
+ public DataSchemaContextNode.@NonNull Composite getRoot() {
return root;
}
}
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode.Composite;
import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode.PathMixin;
import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode.SimpleValue;
import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
}
private DataSchemaContextNode nextContextNode(final QName name) {
- current = current.getChild(name);
+ current = getChild(current, name);
checkValid(current != null, "%s is not correct schema node identifier.", name);
while (current instanceof PathMixin mixin) {
product.add(mixin.mixinPathStep());
- current = current.getChild(name);
+ current = getChild(current, name);
}
stack.enterDataTree(name);
return current;
}
+ private static DataSchemaContextNode getChild(final DataSchemaContextNode parent, final QName name) {
+ return parent instanceof Composite composite ? composite.getChild(name) : null;
+ }
+
/**
* Creates path argument with predicates and sets offset
* to end of path argument.
type -> resolveLeafref(currentSchema.getQName(), type), keyValue);
return new NodeWithValue<>(name, value);
}
- final DataSchemaContextNode keyNode = currentNode.getChild(key);
- checkValid(keyNode != null, "%s is not correct schema node identifier.", key);
+ final var keyNode = currentNode instanceof Composite composite ? composite.getChild(key) : null;
+ if (keyNode == null) {
+ throw iae("%s is not correct schema node identifier.", key);
+ }
+
final Object value = codec.deserializeKeyValue(keyNode.getDataSchemaNode(),
type -> resolveLeafref(key, type), keyValue);
keyValues.put(key, value);
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.util.impl.legacy;
+
+import static java.util.Objects.requireNonNull;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode;
+import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode.Composite;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
+
+public abstract sealed class AbstractCompositeContextNode extends AbstractDataSchemaContextNode implements Composite
+ permits AbstractMixinContextNode, DataContainerContextNode {
+ AbstractCompositeContextNode(final NodeIdentifier pathStep, final DataSchemaNode schema) {
+ super(pathStep, schema);
+ }
+
+ @Override
+ public final DataSchemaContextNode enterChild(final SchemaInferenceStack stack, final QName child) {
+ return enterChild(requireNonNull(child), requireNonNull(stack));
+ }
+
+ @Override
+ public final DataSchemaContextNode enterChild(final SchemaInferenceStack stack,
+ final PathArgument child) {
+ return enterChild(requireNonNull(child), requireNonNull(stack));
+ }
+
+ abstract @Nullable DataSchemaContextNode enterChild(@NonNull QName child, @NonNull SchemaInferenceStack stack);
+
+ abstract @Nullable DataSchemaContextNode enterChild(@NonNull PathArgument child,
+ @NonNull SchemaInferenceStack stack);
+}
\ No newline at end of file
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode;
import org.opendaylight.yangtools.yang.model.api.AnydataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.AnyxmlSchemaNode;
* since the mapping is not one-to-one.
*/
public abstract sealed class AbstractDataSchemaContextNode implements DataSchemaContextNode
- permits AbstractInteriorContextNode, AbstractLeafContextNode {
+ permits AbstractCompositeContextNode, LeafContextNode, LeafListEntryContextNode, OpaqueContextNode {
private final @Nullable NodeIdentifier pathStep;
final @NonNull DataSchemaNode dataSchemaNode;
return ImmutableSet.of(dataSchemaNode.getQName());
}
- @Override
- public final @Nullable DataSchemaContextNode enterChild(final SchemaInferenceStack stack, final QName child) {
- return enterChild(requireNonNull(child), requireNonNull(stack));
- }
-
- @Override
- public final @Nullable DataSchemaContextNode enterChild(final SchemaInferenceStack stack,
- final PathArgument child) {
- return enterChild(requireNonNull(child), requireNonNull(stack));
- }
-
- abstract @Nullable DataSchemaContextNode enterChild(@NonNull QName child, @NonNull SchemaInferenceStack stack);
-
- abstract @Nullable DataSchemaContextNode enterChild(@NonNull PathArgument child,
- @NonNull SchemaInferenceStack stack);
-
/**
* Push this node into specified {@link SchemaInferenceStack}.
*
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.data.util.impl.legacy;
-
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-
-abstract sealed class AbstractInteriorContextNode extends AbstractDataSchemaContextNode
- permits AbstractMixinContextNode, DataContainerContextNode {
- AbstractInteriorContextNode(final NodeIdentifier pathStep, final DataSchemaNode schema) {
- super(pathStep, schema);
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2019 PANTHEON.tech, s.r.o. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.data.util.impl.legacy;
-
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
-
-abstract sealed class AbstractLeafContextNode extends AbstractDataSchemaContextNode
- permits LeafContextNode, LeafListEntryContextNode, OpaqueContextNode {
- AbstractLeafContextNode(final NodeIdentifier pathStep, final DataSchemaNode schema) {
- super(pathStep, schema);
- }
-
- @Override
- public final DataSchemaContextNode getChild(final PathArgument child) {
- return null;
- }
-
- @Override
- public final DataSchemaContextNode getChild(final QName child) {
- return null;
- }
-
- @Override
- protected final DataSchemaContextNode enterChild(final QName child, final SchemaInferenceStack stack) {
- return null;
- }
-
- @Override
- protected final DataSchemaContextNode enterChild(final PathArgument child, final SchemaInferenceStack stack) {
- return null;
- }
-}
import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode.PathMixin;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-public abstract sealed class AbstractMixinContextNode extends AbstractInteriorContextNode implements PathMixin
+public abstract sealed class AbstractMixinContextNode extends AbstractCompositeContextNode implements PathMixin
permits AbstractListLikeContextNode, ChoiceNodeContextNode {
AbstractMixinContextNode(final DataSchemaNode schema) {
super(NodeIdentifier.create(schema.getQName()), schema);
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
-abstract sealed class DataContainerContextNode extends AbstractInteriorContextNode
+abstract sealed class DataContainerContextNode extends AbstractCompositeContextNode
permits AbstractListItemContextNode, ContainerContextNode {
private final ConcurrentMap<PathArgument, AbstractDataSchemaContextNode> byArg = new ConcurrentHashMap<>();
private final ConcurrentMap<QName, AbstractDataSchemaContextNode> byQName = new ConcurrentHashMap<>();
import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode.SimpleValue;
import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-public final class LeafContextNode extends AbstractLeafContextNode implements SimpleValue {
+public final class LeafContextNode extends AbstractDataSchemaContextNode implements SimpleValue {
LeafContextNode(final LeafSchemaNode schema) {
super(NodeIdentifier.create(schema.getQName()), schema);
}
import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
-public final class LeafListEntryContextNode extends AbstractLeafContextNode implements SimpleValue {
+public final class LeafListEntryContextNode extends AbstractDataSchemaContextNode implements SimpleValue {
LeafListEntryContextNode(final LeafListSchemaNode schema) {
super(null, schema);
}
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-final class OpaqueContextNode extends AbstractLeafContextNode {
+final class OpaqueContextNode extends AbstractDataSchemaContextNode {
OpaqueContextNode(final DataSchemaNode schema) {
super(NodeIdentifier.create(schema.getQName()), schema);
}