import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableAugmentationNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.tree.NormalizedNodeContainerSupport.Single;
import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode;
import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
final class AugmentationModificationStrategy
extends DataNodeContainerModificationStrategy<AugmentationSchemaNode> {
- private static final Single<AugmentationIdentifier, AugmentationNode> SUPPORT = new Single<>(AugmentationNode.class,
- ImmutableAugmentationNodeBuilder::create, ImmutableAugmentationNodeBuilder::create);
+ private static final NormalizedNodeContainerSupport<AugmentationIdentifier, AugmentationNode> SUPPORT =
+ new NormalizedNodeContainerSupport<>(AugmentationNode.class, ImmutableAugmentationNodeBuilder::create,
+ ImmutableAugmentationNodeBuilder::create);
private final AugmentationNode emptyNode;
import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableChoiceNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.tree.NormalizedNodeContainerSupport.Single;
import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
final class ChoiceModificationStrategy extends AbstractNodeContainerModificationStrategy {
- private static final Single<NodeIdentifier, ChoiceNode> SUPPORT = new Single<>(ChoiceNode.class,
- ImmutableChoiceNodeBuilder::create, ImmutableChoiceNodeBuilder::create);
+ private static final NormalizedNodeContainerSupport<NodeIdentifier, ChoiceNode> SUPPORT =
+ new NormalizedNodeContainerSupport<>(ChoiceNode.class, ImmutableChoiceNodeBuilder::create,
+ ImmutableChoiceNodeBuilder::create);
private final ImmutableMap<PathArgument, ModificationApplyOperation> childNodes;
// FIXME: enforce leaves not coming from two case statements at the same time
import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.tree.NormalizedNodeContainerSupport.Single;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
/**
}
}
- private static final Single<NodeIdentifier, ContainerNode> SUPPORT = new Single<>(ContainerNode.class,
- ImmutableContainerNodeBuilder::create, ImmutableContainerNodeBuilder::create);
+ private static final NormalizedNodeContainerSupport<NodeIdentifier, ContainerNode> SUPPORT =
+ new NormalizedNodeContainerSupport<>(ContainerNode.class, ImmutableContainerNodeBuilder::create,
+ ImmutableContainerNodeBuilder::create);
ContainerModificationStrategy(final ContainerSchemaNode schemaNode, final DataTreeConfiguration treeConfig) {
super(SUPPORT, schemaNode, treeConfig);
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
import javax.annotation.Nonnull;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
}
private ModificationApplyOperation getOperation(final DataSchemaNode rootSchemaNode) {
- if (maskMandatory && rootSchemaNode instanceof ContainerSchemaNode) {
+ if (rootSchemaNode instanceof ContainerSchemaNode && maskMandatory) {
return new ContainerModificationStrategy((ContainerSchemaNode) rootSchemaNode, treeConfig);
}
+ if (rootSchemaNode instanceof ListSchemaNode) {
+ final PathArgument arg = treeConfig.getRootPath().getLastPathArgument();
+ if (arg instanceof NodeIdentifierWithPredicates) {
+ return maskMandatory ? new ListEntryModificationStrategy((ListSchemaNode) rootSchemaNode, treeConfig)
+ : ListEntryModificationStrategy.of((ListSchemaNode) rootSchemaNode, treeConfig);
+ }
+ }
return SchemaAwareApplyOperation.from(rootSchemaNode, treeConfig);
}
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableOrderedLeafSetNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.tree.NormalizedNodeContainerSupport.Single;
import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
final class LeafSetModificationStrategy extends AbstractNodeContainerModificationStrategy {
@SuppressWarnings({ "unchecked", "rawtypes" })
- private static final Single<NodeIdentifier, OrderedLeafSetNode<?>> ORDERED_SUPPORT =
- new Single(OrderedLeafSetNode.class, ChildTrackingPolicy.ORDERED,
+ private static final NormalizedNodeContainerSupport<NodeIdentifier, OrderedLeafSetNode<?>> ORDERED_SUPPORT =
+ new NormalizedNodeContainerSupport(OrderedLeafSetNode.class, ChildTrackingPolicy.ORDERED,
foo -> ImmutableOrderedLeafSetNodeBuilder.create((OrderedLeafSetNode<?>)foo),
ImmutableOrderedLeafSetNodeBuilder::create);
@SuppressWarnings({ "unchecked", "rawtypes" })
- private static final Single<NodeIdentifier, LeafSetNode<?>> UNORDERED_SUPPORT =
- new Single(LeafSetNode.class,
+ private static final NormalizedNodeContainerSupport<NodeIdentifier, LeafSetNode<?>> UNORDERED_SUPPORT =
+ new NormalizedNodeContainerSupport(LeafSetNode.class,
foo -> ImmutableLeafSetNodeBuilder.create((LeafSetNode<?>)foo),
ImmutableLeafSetNodeBuilder::create);
import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.tree.NormalizedNodeContainerSupport.Single;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
class ListEntryModificationStrategy extends DataNodeContainerModificationStrategy<ListSchemaNode> {
}
}
- private static final Single<NodeIdentifierWithPredicates, MapEntryNode> SUPPORT = new Single<>(MapEntryNode.class,
- ImmutableMapEntryNodeBuilder::create, ImmutableMapEntryNodeBuilder::create);
+ private static final NormalizedNodeContainerSupport<NodeIdentifierWithPredicates, MapEntryNode> SUPPORT =
+ new NormalizedNodeContainerSupport<>(MapEntryNode.class, ImmutableMapEntryNodeBuilder::create,
+ ImmutableMapEntryNodeBuilder::create);
ListEntryModificationStrategy(final ListSchemaNode schema, final DataTreeConfiguration treeConfig) {
super(SUPPORT, schema, treeConfig);
import com.google.common.base.MoreObjects.ToStringHelper;
import java.util.Optional;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableOrderedMapNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.tree.NormalizedNodeContainerSupport.MapEntry;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
final class MapModificationStrategy extends AbstractNodeContainerModificationStrategy {
- private static final MapEntry<OrderedMapNode> ORDERED_SUPPORT = new MapEntry<>(OrderedMapNode.class,
- ChildTrackingPolicy.ORDERED, ImmutableOrderedMapNodeBuilder::create,
- ImmutableOrderedMapNodeBuilder::create);
- private static final MapEntry<MapNode> UNORDERED_SUPPORT = new MapEntry<>(MapNode.class,
- ChildTrackingPolicy.UNORDERED, ImmutableMapNodeBuilder::create, ImmutableMapNodeBuilder::create);
+ private static final NormalizedNodeContainerSupport<NodeIdentifier, OrderedMapNode> ORDERED_SUPPORT =
+ new NormalizedNodeContainerSupport<>(OrderedMapNode.class, ChildTrackingPolicy.ORDERED,
+ ImmutableOrderedMapNodeBuilder::create, ImmutableOrderedMapNodeBuilder::create);
+ private static final NormalizedNodeContainerSupport<NodeIdentifier, MapNode> UNORDERED_SUPPORT =
+ new NormalizedNodeContainerSupport<>(MapNode.class, ImmutableMapNodeBuilder::create,
+ ImmutableMapNodeBuilder::create);
private final Optional<ModificationApplyOperation> entryStrategy;
private final MapNode emptyNode;
- private MapModificationStrategy(final MapEntry<?> support, final ListSchemaNode schema,
+ private MapModificationStrategy(final NormalizedNodeContainerSupport<?, ?> support, final ListSchemaNode schema,
final DataTreeConfiguration treeConfig, final MapNode emptyNode) {
super(support, treeConfig);
this.emptyNode = requireNonNull(emptyNode);
}
static MapModificationStrategy of(final ListSchemaNode schema, final DataTreeConfiguration treeConfig) {
- final MapEntry<?> support;
+ final NormalizedNodeContainerSupport<?, ?> support;
final MapNode emptyNode;
if (schema.isUserOrdered()) {
support = ORDERED_SUPPORT;
return new MapModificationStrategy(support, schema, treeConfig, emptyNode);
}
- // FIXME: this is a hack, originally introduced in
- // Change-Id: I9dc02a1917f38e8a0d62279843974b9869c48693. DataTreeRoot needs to be fixed up to properly
- // handle the lookup of through maps.
@Override
public Optional<ModificationApplyOperation> getChild(final YangInstanceIdentifier.PathArgument identifier) {
- if (identifier instanceof NodeIdentifierWithPredicates) {
- return entryStrategy;
- }
- // In case we already are in a MapEntry node(for example DataTree rooted at MapEntry)
- // try to retrieve the child that the identifier should be pointing to from our entryStrategy
- // if we have one. If the entryStrategy cannot find this child we just return the absent
- // we get from it.
- return entryStrategy.get().getChild(identifier);
+ return identifier instanceof NodeIdentifierWithPredicates ? entryStrategy : Optional.empty();
}
@Override
import com.google.common.base.MoreObjects;
import java.util.function.Function;
import java.util.function.Supplier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
-
-abstract class NormalizedNodeContainerSupport<K extends PathArgument, T extends NormalizedNode<K, ?>> {
- static final class Single<K extends PathArgument, T extends NormalizedNode<K, ?>>
- extends NormalizedNodeContainerSupport<K, T> {
- Single(final Class<T> requiredClass,
- final Function<T, NormalizedNodeContainerBuilder<K, ?, ?, T>> copyBuilder,
- final Supplier<NormalizedNodeContainerBuilder<K, ?, ?, T>> emptyBuilder) {
- this(requiredClass, ChildTrackingPolicy.UNORDERED, copyBuilder, emptyBuilder);
- }
-
- Single(final Class<T> requiredClass, final ChildTrackingPolicy childPolicy,
- final Function<T, NormalizedNodeContainerBuilder<K, ?, ?, T>> copyBuilder,
- final Supplier<NormalizedNodeContainerBuilder<K, ?, ?, T>> emptyBuilder) {
- super(requiredClass, childPolicy, copyBuilder, emptyBuilder);
- }
-
- @Override
- NormalizedNodeContainerBuilder<?, ?, ?, T> createBuilder(final NormalizedNode<?, ?> original) {
- return copyBuilder.apply(cast(original));
- }
-
- @Override
- NormalizedNode<?, ?> createEmptyValue(final NormalizedNode<?, ?> original) {
- return emptyBuilder.get().withNodeIdentifier(cast(original).getIdentifier()).build();
- }
-
- private T cast(final NormalizedNode<?, ?> original) {
- checkArgument(requiredClass.isInstance(original), "Require %s, got %s", requiredClass, original);
- return requiredClass.cast(original);
- }
- }
-
- // FIXME: MapEntry a refactor of a hack, originally introduced in
- // Change-Id: I9dc02a1917f38e8a0d62279843974b9869c48693. DataTreeRoot needs to be fixed up to properly
- // handle the lookup of through maps.
- static final class MapEntry<T extends NormalizedNode<NodeIdentifier, ?>>
- extends NormalizedNodeContainerSupport<NodeIdentifier, T> {
- MapEntry(final Class<T> requiredClass, final ChildTrackingPolicy childPolicy,
- final Function<T, NormalizedNodeContainerBuilder<NodeIdentifier, ?, ?, T>> copyBuilder,
- final Supplier<NormalizedNodeContainerBuilder<NodeIdentifier, ?, ?, T>> emptyBuilder) {
- super(requiredClass, childPolicy, copyBuilder, emptyBuilder);
- }
-
- @Override
- NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final NormalizedNode<?, ?> original) {
- if (requiredClass.isInstance(original)) {
- return copyBuilder.apply(requiredClass.cast(original));
- }
- if (original instanceof MapEntryNode) {
- return ImmutableMapEntryNodeBuilder.create((MapEntryNode) original);
- }
- throw new IllegalArgumentException("Expected either MapEntryNode or " + requiredClass + ", offending node: "
- + original);
- }
-
- @Override
- NormalizedNode<?, ?> createEmptyValue(final NormalizedNode<?, ?> original) {
- if (requiredClass.isInstance(original)) {
- return emptyBuilder.get().withNodeIdentifier(requiredClass.cast(original).getIdentifier()).build();
- }
- if (original instanceof MapEntryNode) {
- return ImmutableMapEntryNodeBuilder.create()
- .withNodeIdentifier(((MapEntryNode) original).getIdentifier()).build();
- }
- throw new IllegalArgumentException("Expected either MapEntryNode or " + requiredClass + ", offending node: "
- + original);
- }
- }
+final class NormalizedNodeContainerSupport<K extends PathArgument, T extends NormalizedNode<K, ?>> {
final Function<T, NormalizedNodeContainerBuilder<K, ?, ?, T>> copyBuilder;
final Supplier<NormalizedNodeContainerBuilder<K, ?, ?, T>> emptyBuilder;
final ChildTrackingPolicy childPolicy;
this.emptyBuilder = requireNonNull(emptyBuilder);
}
- @SuppressWarnings("rawtypes")
- abstract NormalizedNodeContainerBuilder createBuilder(NormalizedNode<?, ?> original);
+ NormalizedNodeContainerSupport(final Class<T> requiredClass,
+ final Function<T, NormalizedNodeContainerBuilder<K, ?, ?, T>> copyBuilder,
+ final Supplier<NormalizedNodeContainerBuilder<K, ?, ?, T>> emptyBuilder) {
+ this(requiredClass, ChildTrackingPolicy.UNORDERED, copyBuilder, emptyBuilder);
+ }
- abstract NormalizedNode<?, ?> createEmptyValue(NormalizedNode<?, ?> original);
+ NormalizedNodeContainerBuilder<?, ?, ?, T> createBuilder(final NormalizedNode<?, ?> original) {
+ return copyBuilder.apply(cast(original));
+ }
+
+ NormalizedNode<?, ?> createEmptyValue(final NormalizedNode<?, ?> original) {
+ return emptyBuilder.get().withNodeIdentifier(cast(original).getIdentifier()).build();
+ }
+
+ private T cast(final NormalizedNode<?, ?> original) {
+ checkArgument(requiredClass.isInstance(original), "Require %s, got %s", requiredClass, original);
+ return requiredClass.cast(original);
+ }
@Override
- public final String toString() {
+ public String toString() {
return MoreObjects.toStringHelper(this).add("requiredClass", requiredClass).toString();
}
}
import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUnkeyedListEntryNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.tree.NormalizedNodeContainerSupport.Single;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
final class UnkeyedListModificationStrategy extends SchemaAwareApplyOperation {
- private static final Single<NodeIdentifier, UnkeyedListEntryNode> ITEM_SUPPORT =
- new Single<>(UnkeyedListEntryNode.class, ImmutableUnkeyedListEntryNodeBuilder::create,
- ImmutableUnkeyedListEntryNodeBuilder::create);
+ private static final NormalizedNodeContainerSupport<NodeIdentifier, UnkeyedListEntryNode> ITEM_SUPPORT =
+ new NormalizedNodeContainerSupport<>(UnkeyedListEntryNode.class,
+ ImmutableUnkeyedListEntryNodeBuilder::create, ImmutableUnkeyedListEntryNodeBuilder::create);
private final Optional<ModificationApplyOperation> entryStrategy;
private final UnkeyedListNode emptyNode;
--- /dev/null
+/*
+ * Copyright (c) 2019 Pantheon Technologies, 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.impl.schema.tree;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.TreeType;
+
+public class MapEntryRootTest extends AbstractTestModelTest {
+
+ @Test
+ public void testMapEntryRoot() {
+ final DataTreeConfiguration treeConfig = DataTreeConfiguration.builder(TreeType.OPERATIONAL).setRootPath(
+ TestModel.TEST_PATH.node(TestModel.OUTER_LIST_QNAME).node(
+ new NodeIdentifierWithPredicates(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, (short) 12))).build();
+ final DataTree dataTree = new InMemoryDataTreeFactory().create(treeConfig, SCHEMA_CONTEXT);
+ assertTrue(dataTree instanceof InMemoryDataTree);
+
+ final InMemoryDataTree imdt = (InMemoryDataTree) dataTree;
+ final InMemoryDataTreeModification mod = imdt.takeSnapshot().newModification();
+ final ModificationApplyOperation strategy = mod.getStrategy();
+ assertThat(strategy, instanceOf(ListEntryModificationStrategy.class));
+ }
+}