AbstractMapModificationStrategy(final Class<? extends MapNode> nodeClass, final ListSchemaNode schema,
final DataTreeConfiguration treeConfig) {
super(nodeClass, treeConfig);
- entryStrategy = Optional.of(new ListEntryModificationStrategy(schema, treeConfig));
+ entryStrategy = Optional.of(ListEntryModificationStrategy.of(schema, treeConfig));
}
@Override
*/
package org.opendaylight.yangtools.yang.data.impl.schema.tree;
-import com.google.common.base.Preconditions;
+import static java.util.Objects.requireNonNull;
+
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.collect.Sets;
-import java.util.Map;
import java.util.Map.Entry;
+import java.util.Optional;
import java.util.Set;
import org.opendaylight.yangtools.concepts.Immutable;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-final class CaseEnforcer implements Immutable {
- private final Map<NodeIdentifier, DataSchemaNode> children;
- private final Map<AugmentationIdentifier, AugmentationSchemaNode> augmentations;
- private final MandatoryLeafEnforcer enforcer;
+class CaseEnforcer implements Immutable {
+ private static final class EnforcingMandatory extends CaseEnforcer {
+ private final MandatoryLeafEnforcer enforcer;
+
+ EnforcingMandatory(final ImmutableMap<NodeIdentifier, DataSchemaNode> children,
+ final ImmutableMap<AugmentationIdentifier, AugmentationSchemaNode> augmentations,
+ final MandatoryLeafEnforcer enforcer) {
+ super(children, augmentations);
+ this.enforcer = requireNonNull(enforcer);
+ }
+
+ @Override
+ void enforceOnTreeNode(final NormalizedNode<?, ?> normalizedNode) {
+ enforcer.enforceOnData(normalizedNode);
+ }
+ }
- private CaseEnforcer(final Map<NodeIdentifier, DataSchemaNode> children,
- final Map<AugmentationIdentifier, AugmentationSchemaNode> augmentations,
- final MandatoryLeafEnforcer enforcer) {
- this.children = Preconditions.checkNotNull(children);
- this.augmentations = Preconditions.checkNotNull(augmentations);
- this.enforcer = Preconditions.checkNotNull(enforcer);
+ private final ImmutableMap<NodeIdentifier, DataSchemaNode> children;
+ private final ImmutableMap<AugmentationIdentifier, AugmentationSchemaNode> augmentations;
+
+ CaseEnforcer(final ImmutableMap<NodeIdentifier, DataSchemaNode> children,
+ final ImmutableMap<AugmentationIdentifier, AugmentationSchemaNode> augmentations) {
+ this.children = requireNonNull(children);
+ this.augmentations = requireNonNull(augmentations);
}
static CaseEnforcer forTree(final CaseSchemaNode schema, final DataTreeConfiguration treeConfig) {
}
}
- final Map<NodeIdentifier, DataSchemaNode> children = childrenBuilder.build();
- final Map<AugmentationIdentifier, AugmentationSchemaNode> augmentations = augmentationsBuilder.build();
- return children.isEmpty() ? null
- : new CaseEnforcer(children, augmentations, MandatoryLeafEnforcer.forContainer(schema, treeConfig));
+ final ImmutableMap<NodeIdentifier, DataSchemaNode> children = childrenBuilder.build();
+ if (children.isEmpty()) {
+ return null;
+ }
+ final ImmutableMap<AugmentationIdentifier, AugmentationSchemaNode> augmentations = augmentationsBuilder.build();
+ final Optional<MandatoryLeafEnforcer> enforcer = MandatoryLeafEnforcer.forContainer(schema, treeConfig);
+ return enforcer.isPresent() ? new EnforcingMandatory(children, augmentations, enforcer.get())
+ : new CaseEnforcer(children, augmentations);
}
- Set<Entry<NodeIdentifier, DataSchemaNode>> getChildEntries() {
+ final Set<Entry<NodeIdentifier, DataSchemaNode>> getChildEntries() {
return children.entrySet();
}
- Set<NodeIdentifier> getChildIdentifiers() {
+ final Set<NodeIdentifier> getChildIdentifiers() {
return children.keySet();
}
- Set<Entry<AugmentationIdentifier, AugmentationSchemaNode>> getAugmentationEntries() {
+ final Set<Entry<AugmentationIdentifier, AugmentationSchemaNode>> getAugmentationEntries() {
return augmentations.entrySet();
}
- Set<AugmentationIdentifier> getAugmentationIdentifiers() {
+ final Set<AugmentationIdentifier> getAugmentationIdentifiers() {
return augmentations.keySet();
}
- Set<PathArgument> getAllChildIdentifiers() {
+ final Set<PathArgument> getAllChildIdentifiers() {
return Sets.union(children.keySet(), augmentations.keySet());
}
void enforceOnTreeNode(final NormalizedNode<?, ?> normalizedNode) {
- enforcer.enforceOnData(normalizedNode);
+ // Default is no-op
}
}
package org.opendaylight.yangtools.yang.data.impl.schema.tree;
import static com.google.common.base.Preconditions.checkArgument;
+import static java.util.Objects.requireNonNull;
import com.google.common.base.Preconditions;
+import java.util.Optional;
import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
+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.api.DataContainerNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
/**
- * General container modification strategy. Used by {@link PresenceContainerModificationStrategy} via subclassing
- * and by {@link StructuralContainerModificationStrategy} as a delegate.
+ * General container modification strategy. This is used by {@link EnforcingMandatory} in case of presence containers
+ * with mandatory nodes, as it needs to tap into {@link SchemaAwareApplyOperation}'s operations, or subclassed
+ * for the purposes of {@link StructuralContainerModificationStrategy}'s automatic lifecycle.
*/
class ContainerModificationStrategy extends AbstractDataNodeContainerModificationStrategy<ContainerSchemaNode> {
+ private static final class EnforcingMandatory extends ContainerModificationStrategy {
+ private final MandatoryLeafEnforcer enforcer;
+
+ EnforcingMandatory(final ContainerSchemaNode schemaNode, final DataTreeConfiguration treeConfig,
+ final MandatoryLeafEnforcer enforcer) {
+ super(schemaNode, treeConfig);
+ this.enforcer = requireNonNull(enforcer);
+ }
+
+ @Override
+ void verifyStructure(final NormalizedNode<?, ?> writtenValue, final boolean verifyChildren) {
+ super.verifyStructure(writtenValue, verifyChildren);
+ if (verifyChildren) {
+ enforcer.enforceOnData(writtenValue);
+ }
+ }
+
+ @Override
+ protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta,
+ final Version version) {
+ final TreeNode ret = super.applyMerge(modification, currentMeta, version);
+ enforcer.enforceOnTreeNode(ret);
+ return ret;
+ }
+
+ @Override
+ protected TreeNode applyWrite(final ModifiedNode modification, final NormalizedNode<?, ?> newValue,
+ final Optional<TreeNode> currentMeta, final Version version) {
+ final TreeNode ret = super.applyWrite(modification, newValue, currentMeta, version);
+ enforcer.enforceOnTreeNode(ret);
+ return ret;
+ }
+
+ @Override
+ protected TreeNode applyTouch(final ModifiedNode modification, final TreeNode currentMeta,
+ final Version version) {
+ final TreeNode ret = super.applyTouch(modification, currentMeta, version);
+ enforcer.enforceOnTreeNode(ret);
+ return ret;
+ }
+ }
+
ContainerModificationStrategy(final ContainerSchemaNode schemaNode, final DataTreeConfiguration treeConfig) {
super(schemaNode, ContainerNode.class, treeConfig);
}
+ static ModificationApplyOperation of(final ContainerSchemaNode schema, final DataTreeConfiguration treeConfig) {
+ if (schema.isPresenceContainer()) {
+ final Optional<MandatoryLeafEnforcer> enforcer = MandatoryLeafEnforcer.forContainer(schema, treeConfig);
+ return enforcer.isPresent() ? new EnforcingMandatory(schema, treeConfig, enforcer.get())
+ : new ContainerModificationStrategy(schema, treeConfig);
+ }
+
+ return new StructuralContainerModificationStrategy(schema, treeConfig);
+ }
+
@Override
@SuppressWarnings("rawtypes")
protected final DataContainerNodeBuilder createBuilder(final NormalizedNode<?, ?> original) {
package org.opendaylight.yangtools.yang.data.impl.schema.tree;
import static com.google.common.base.Preconditions.checkArgument;
+import static java.util.Objects.requireNonNull;
import java.util.Optional;
import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-final class ListEntryModificationStrategy extends AbstractDataNodeContainerModificationStrategy<ListSchemaNode> {
- private final MandatoryLeafEnforcer enforcer;
+class ListEntryModificationStrategy extends AbstractDataNodeContainerModificationStrategy<ListSchemaNode> {
+ private static final class EnforcingMandatory extends ListEntryModificationStrategy {
+ private final MandatoryLeafEnforcer enforcer;
- ListEntryModificationStrategy(final ListSchemaNode schema, final DataTreeConfiguration treeConfig) {
- super(schema, MapEntryNode.class, treeConfig);
- enforcer = MandatoryLeafEnforcer.forContainer(schema, treeConfig);
- }
+ EnforcingMandatory(final ListSchemaNode schemaNode, final DataTreeConfiguration treeConfig,
+ final MandatoryLeafEnforcer enforcer) {
+ super(schemaNode, treeConfig);
+ this.enforcer = requireNonNull(enforcer);
+ }
- @Override
- void verifyStructure(final NormalizedNode<?, ?> writtenValue, final boolean verifyChildren) {
- super.verifyStructure(writtenValue, verifyChildren);
- if (verifyChildren) {
- enforcer.enforceOnData(writtenValue);
+ @Override
+ void verifyStructure(final NormalizedNode<?, ?> writtenValue, final boolean verifyChildren) {
+ super.verifyStructure(writtenValue, verifyChildren);
+ if (verifyChildren) {
+ enforcer.enforceOnData(writtenValue);
+ }
}
- }
- @Override
- protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta, final Version version) {
- final TreeNode ret = super.applyMerge(modification, currentMeta, version);
- enforcer.enforceOnTreeNode(ret);
- return ret;
+ @Override
+ protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta,
+ final Version version) {
+ final TreeNode ret = super.applyMerge(modification, currentMeta, version);
+ enforcer.enforceOnTreeNode(ret);
+ return ret;
+ }
+
+ @Override
+ protected TreeNode applyWrite(final ModifiedNode modification, final NormalizedNode<?, ?> newValue,
+ final Optional<TreeNode> currentMeta, final Version version) {
+ final TreeNode ret = super.applyWrite(modification, newValue, currentMeta, version);
+ enforcer.enforceOnTreeNode(ret);
+ return ret;
+ }
+
+ @Override
+ protected TreeNode applyTouch(final ModifiedNode modification, final TreeNode currentMeta,
+ final Version version) {
+ final TreeNode ret = super.applyTouch(modification, currentMeta, version);
+ enforcer.enforceOnTreeNode(ret);
+ return ret;
+ }
}
- @Override
- protected TreeNode applyWrite(final ModifiedNode modification, final NormalizedNode<?, ?> newValue,
- final Optional<TreeNode> currentMeta, final Version version) {
- final TreeNode ret = super.applyWrite(modification, newValue, currentMeta, version);
- enforcer.enforceOnTreeNode(ret);
- return ret;
+ ListEntryModificationStrategy(final ListSchemaNode schema, final DataTreeConfiguration treeConfig) {
+ super(schema, MapEntryNode.class, treeConfig);
}
- @Override
- protected TreeNode applyTouch(final ModifiedNode modification, final TreeNode currentMeta, final Version version) {
- final TreeNode ret = super.applyTouch(modification, currentMeta, version);
- enforcer.enforceOnTreeNode(ret);
- return ret;
+ static ListEntryModificationStrategy of(final ListSchemaNode schema, final DataTreeConfiguration treeConfig) {
+ final Optional<MandatoryLeafEnforcer> enforcer = MandatoryLeafEnforcer.forContainer(schema, treeConfig);
+ return enforcer.isPresent() ? new EnforcingMandatory(schema, treeConfig, enforcer.get())
+ : new ListEntryModificationStrategy(schema, treeConfig);
}
@Override
*/
package org.opendaylight.yangtools.yang.data.impl.schema.tree;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableCollection.Builder;
+import static com.google.common.base.Preconditions.checkArgument;
+import static java.util.Objects.requireNonNull;
+
import com.google.common.collect.ImmutableList;
-import java.util.Collection;
+import com.google.common.collect.ImmutableList.Builder;
import java.util.Optional;
import org.opendaylight.yangtools.concepts.Immutable;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.slf4j.LoggerFactory;
// TODO: would making this Serializable be useful (for Functions and similar?)
-abstract class MandatoryLeafEnforcer implements Immutable {
- private static final class Strict extends MandatoryLeafEnforcer {
- private final Collection<YangInstanceIdentifier> mandatoryNodes;
+final class MandatoryLeafEnforcer implements Immutable {
+ private static final Logger LOG = LoggerFactory.getLogger(MandatoryLeafEnforcer.class);
- Strict(final Collection<YangInstanceIdentifier> mandatoryNodes) {
- this.mandatoryNodes = Preconditions.checkNotNull(mandatoryNodes);
- }
+ private final ImmutableList<YangInstanceIdentifier> mandatoryNodes;
- @Override
- void enforceOnData(final NormalizedNode<?, ?> data) {
- for (final YangInstanceIdentifier id : mandatoryNodes) {
- final Optional<NormalizedNode<?, ?>> descandant = NormalizedNodes.findNode(data, id);
- Preconditions.checkArgument(descandant.isPresent(), "Node %s is missing mandatory descendant %s",
- data.getIdentifier(), id);
- }
+ private MandatoryLeafEnforcer(final ImmutableList<YangInstanceIdentifier> mandatoryNodes) {
+ this.mandatoryNodes = requireNonNull(mandatoryNodes);
+ }
+
+ static Optional<MandatoryLeafEnforcer> forContainer(final DataNodeContainer schema,
+ final DataTreeConfiguration treeConfig) {
+ if (!treeConfig.isMandatoryNodesValidationEnabled()) {
+ return Optional.empty();
}
+
+ final Builder<YangInstanceIdentifier> builder = ImmutableList.builder();
+ findMandatoryNodes(builder, YangInstanceIdentifier.EMPTY, schema, treeConfig.getTreeType());
+ final ImmutableList<YangInstanceIdentifier> mandatoryNodes = builder.build();
+ return mandatoryNodes.isEmpty() ? Optional.empty() : Optional.of(new MandatoryLeafEnforcer(mandatoryNodes));
}
- private static final Logger LOG = LoggerFactory.getLogger(MandatoryLeafEnforcer.class);
- private static final MandatoryLeafEnforcer NOOP_ENFORCER = new MandatoryLeafEnforcer() {
- @Override
- void enforceOnData(final NormalizedNode<?, ?> normalizedNode) {
- // Intentional no-op
+ void enforceOnData(final NormalizedNode<?, ?> data) {
+ for (final YangInstanceIdentifier id : mandatoryNodes) {
+ checkArgument(NormalizedNodes.findNode(data, id).isPresent(),
+ "Node %s is missing mandatory descendant %s", data.getIdentifier(), id);
}
- };
+ }
- final void enforceOnTreeNode(final TreeNode tree) {
+ void enforceOnTreeNode(final TreeNode tree) {
enforceOnData(tree.getData());
}
- abstract void enforceOnData(NormalizedNode<?, ?> normalizedNode);
-
private static void findMandatoryNodes(final Builder<YangInstanceIdentifier> builder,
final YangInstanceIdentifier id, final DataNodeContainer schema, final TreeType type) {
for (final DataSchemaNode child : schema.getChildNodes()) {
}
}
}
-
- static MandatoryLeafEnforcer forContainer(final DataNodeContainer schema, final DataTreeConfiguration treeConfig) {
- if (!treeConfig.isMandatoryNodesValidationEnabled()) {
- return NOOP_ENFORCER;
- }
-
- final Builder<YangInstanceIdentifier> builder = ImmutableList.builder();
- findMandatoryNodes(builder, YangInstanceIdentifier.EMPTY, schema, treeConfig.getTreeType());
- final Collection<YangInstanceIdentifier> mandatoryNodes = builder.build();
- return mandatoryNodes.isEmpty() ? NOOP_ENFORCER : new Strict(mandatoryNodes);
- }
}
+++ /dev/null
-/*
- * Copyright (c) 2014 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.impl.schema.tree;
-
-import java.util.Optional;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
-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.model.api.ContainerSchemaNode;
-
-/**
- * Presence container modification strategy. In addition to {@link ContainerModificationStrategy} it also enforces
- * presence of mandatory leaves.
- */
-final class PresenceContainerModificationStrategy extends ContainerModificationStrategy {
- private final MandatoryLeafEnforcer enforcer;
-
- PresenceContainerModificationStrategy(final ContainerSchemaNode schemaNode,
- final DataTreeConfiguration treeConfig) {
- super(schemaNode, treeConfig);
- enforcer = MandatoryLeafEnforcer.forContainer(schemaNode, treeConfig);
- }
-
- @Override
- void verifyStructure(final NormalizedNode<?, ?> writtenValue, final boolean verifyChildren) {
- super.verifyStructure(writtenValue, verifyChildren);
- if (verifyChildren) {
- enforcer.enforceOnData(writtenValue);
- }
- }
-
- @Override
- protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta, final Version version) {
- final TreeNode ret = super.applyMerge(modification, currentMeta, version);
- enforcer.enforceOnTreeNode(ret);
- return ret;
- }
-
- @Override
- protected TreeNode applyWrite(final ModifiedNode modification, final NormalizedNode<?, ?> newValue,
- final Optional<TreeNode> currentMeta, final Version version) {
- final TreeNode ret = super.applyWrite(modification, newValue, currentMeta, version);
- enforcer.enforceOnTreeNode(ret);
- return ret;
- }
-
- @Override
- protected TreeNode applyTouch(final ModifiedNode modification, final TreeNode currentMeta, final Version version) {
- final TreeNode ret = super.applyTouch(modification, currentMeta, version);
- enforcer.enforceOnTreeNode(ret);
- return ret;
- }
-}
"Supplied %s does not belongs to configuration tree.", schemaNode.getPath());
}
if (schemaNode instanceof ContainerSchemaNode) {
- final ContainerSchemaNode containerSchema = (ContainerSchemaNode) schemaNode;
- if (containerSchema.isPresenceContainer()) {
- return new PresenceContainerModificationStrategy(containerSchema, treeConfig);
- }
-
- return new StructuralContainerModificationStrategy(containerSchema, treeConfig);
+ return ContainerModificationStrategy.of((ContainerSchemaNode) schemaNode, treeConfig);
} else if (schemaNode instanceof ListSchemaNode) {
return fromListSchemaNode((ListSchemaNode) schemaNode, treeConfig);
} else if (schemaNode instanceof ChoiceSchemaNode) {