Eliminate no-op MandatoryLeafEnforcer
[yangtools.git] / yang / yang-data-impl / src / main / java / org / opendaylight / yangtools / yang / data / impl / schema / tree / ContainerModificationStrategy.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.yangtools.yang.data.impl.schema.tree;
9
10 import static com.google.common.base.Preconditions.checkArgument;
11 import static java.util.Objects.requireNonNull;
12
13 import com.google.common.base.Preconditions;
14 import java.util.Optional;
15 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
16 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
17 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
18 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
19 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
20 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
21 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
22 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
23
24 /**
25  * General container modification strategy. This is used by {@link EnforcingMandatory} in case of presence containers
26  * with mandatory nodes, as it needs to tap into {@link SchemaAwareApplyOperation}'s operations, or subclassed
27  * for the purposes of {@link StructuralContainerModificationStrategy}'s automatic lifecycle.
28  */
29 class ContainerModificationStrategy extends AbstractDataNodeContainerModificationStrategy<ContainerSchemaNode> {
30     private static final class EnforcingMandatory extends ContainerModificationStrategy {
31         private final MandatoryLeafEnforcer enforcer;
32
33         EnforcingMandatory(final ContainerSchemaNode schemaNode, final DataTreeConfiguration treeConfig,
34                 final MandatoryLeafEnforcer enforcer) {
35             super(schemaNode, treeConfig);
36             this.enforcer = requireNonNull(enforcer);
37         }
38
39         @Override
40         void verifyStructure(final NormalizedNode<?, ?> writtenValue, final boolean verifyChildren) {
41             super.verifyStructure(writtenValue, verifyChildren);
42             if (verifyChildren) {
43                 enforcer.enforceOnData(writtenValue);
44             }
45         }
46
47         @Override
48         protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta,
49                 final Version version) {
50             final TreeNode ret = super.applyMerge(modification, currentMeta, version);
51             enforcer.enforceOnTreeNode(ret);
52             return ret;
53         }
54
55         @Override
56         protected TreeNode applyWrite(final ModifiedNode modification, final NormalizedNode<?, ?> newValue,
57                 final Optional<TreeNode> currentMeta, final Version version) {
58             final TreeNode ret = super.applyWrite(modification, newValue, currentMeta, version);
59             enforcer.enforceOnTreeNode(ret);
60             return ret;
61         }
62
63         @Override
64         protected TreeNode applyTouch(final ModifiedNode modification, final TreeNode currentMeta,
65                 final Version version) {
66             final TreeNode ret = super.applyTouch(modification, currentMeta, version);
67             enforcer.enforceOnTreeNode(ret);
68             return ret;
69         }
70     }
71
72     ContainerModificationStrategy(final ContainerSchemaNode schemaNode, final DataTreeConfiguration treeConfig) {
73         super(schemaNode, ContainerNode.class, treeConfig);
74     }
75
76     static ModificationApplyOperation of(final ContainerSchemaNode schema, final DataTreeConfiguration treeConfig) {
77         if (schema.isPresenceContainer()) {
78             final Optional<MandatoryLeafEnforcer> enforcer = MandatoryLeafEnforcer.forContainer(schema, treeConfig);
79             return enforcer.isPresent() ? new EnforcingMandatory(schema, treeConfig, enforcer.get())
80                     : new ContainerModificationStrategy(schema, treeConfig);
81         }
82
83         return new StructuralContainerModificationStrategy(schema, treeConfig);
84     }
85
86     @Override
87     @SuppressWarnings("rawtypes")
88     protected final DataContainerNodeBuilder createBuilder(final NormalizedNode<?, ?> original) {
89         checkArgument(original instanceof ContainerNode);
90         return ImmutableContainerNodeBuilder.create((ContainerNode) original);
91     }
92
93     @Override
94     protected NormalizedNode<?, ?> createEmptyValue(final NormalizedNode<?, ?> original) {
95         Preconditions.checkArgument(original instanceof ContainerNode);
96         return ImmutableContainerNodeBuilder.create().withNodeIdentifier(((ContainerNode) original).getIdentifier())
97                 .build();
98     }
99 }