BUG-4684: validate changes against effective state
[yangtools.git] / yang / yang-data-impl / src / main / java / org / opendaylight / yangtools / yang / data / impl / schema / tree / RootModificationApplyOperation.java
1 /*
2  * Copyright (c) 2014 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 com.google.common.base.Optional;
11 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
12 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
13 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
14 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
15 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
16 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
17
18 /**
19  * Represents a {@link ModificationApplyOperation} which is rooted at conceptual
20  * top of data tree.
21  *
22  * <p>
23  * This implementation differs from other implementations in this package that
24  * is not immutable, but may be upgraded to newer state if available by
25  * explicitly invoking {@link #upgradeIfPossible()} and also serves as factory
26  * for deriving snapshot {@link RootModificationApplyOperation} which will not
27  * be affected by upgrade of original one.
28  *
29  * <p>
30  * There are two variations of this {@link ModificationApplyOperation}:
31  * <ul>
32  * <li>
33  * <b>Upgradable</b> - operation may be upgraded to different backing
34  * implementation by invoking {@link #upgradeIfPossible()}.</li>
35  * <li><b>Not Upgradable</b> - operation is immutable, invocation of
36  * {@link #upgradeIfPossible()} is no-op and method {@link #snapshot()} returns
37  * pointer on same object.
38  *
39  * <h3>Upgradable Root Modification Operation</h3>
40  *
41  * Upgradable Root Modification Operation may be created using:
42  * <ul>
43  * <li> {@link #from(ModificationApplyOperation)} with other upgradable root
44  * modification as an argument
45  * <li>using factory {@link LatestOperationHolder} which instantiates Upgradable
46  * Root Modification Operations and provides an option to set latest
47  * implementation.
48  * </ul>
49  * <p>
50  * Upgradable root operation is never upgraded to latest operation
51  * automatically, but client code must explicitly invoke
52  * {@link #upgradeIfPossible()} to get latest implementation.
53  *
54  * Note: This is helpful for implementing
55  * {@link org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification}
56  * which may be derived from
57  * {@link org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree} before
58  * update of schema and user actually writes data after schema update. During
59  * update user did not invoked any operation.
60  *
61  */
62 abstract class RootModificationApplyOperation extends ModificationApplyOperation {
63
64     @Override
65     public final Optional<ModificationApplyOperation> getChild(final PathArgument child) {
66         return getDelegate().getChild(child);
67     }
68
69     @Override
70     final void checkApplicable(final YangInstanceIdentifier path, final NodeModification modification,
71             final Optional<TreeNode> current, final Version version) throws DataValidationFailedException {
72         getDelegate().checkApplicable(path, modification, current, version);
73     }
74
75     @Override
76     final Optional<TreeNode> apply(final ModifiedNode modification, final Optional<TreeNode> currentMeta,
77             final Version version) {
78         return getDelegate().apply(modification, currentMeta, version);
79     }
80
81     @Override
82     public final boolean equals(final Object obj) {
83         return getDelegate().equals(obj);
84     }
85
86     @Override
87     public final int hashCode() {
88         return getDelegate().hashCode();
89     }
90
91     @Override
92     public final String toString() {
93         return getDelegate().toString();
94     }
95
96     @Override
97     final void verifyStructure(final NormalizedNode<?, ?> modification, final boolean verifyChildren)
98             throws IllegalArgumentException {
99         getDelegate().verifyStructure(modification, verifyChildren);
100     }
101
102     @Override
103     void recursivelyVerifyStructure(NormalizedNode<?, ?> value) {
104         getDelegate().recursivelyVerifyStructure(value);
105     }
106
107     @Override
108     final ChildTrackingPolicy getChildPolicy() {
109         return getDelegate().getChildPolicy();
110     }
111
112     @Override
113     final void mergeIntoModifiedNode(final ModifiedNode node, final NormalizedNode<?, ?> value, final Version version) {
114         getDelegate().mergeIntoModifiedNode(node, value, version);
115     }
116
117     /**
118      * Return the underlying delegate.
119      *
120      * @return Underlying delegate.
121      */
122     abstract ModificationApplyOperation getDelegate();
123
124     /**
125      * Creates a snapshot from this modification, which may have separate
126      * upgrade lifecycle and is not affected by upgrades
127      * <p>
128      * Newly created snapshot uses backing implementation of this modi
129      *
130      * @return Derived {@link RootModificationApplyOperation} with separate
131      *         upgrade lifecycle.
132      */
133     abstract RootModificationApplyOperation snapshot();
134
135     /**
136      * Upgrades backing implementation to latest available, if possible.
137      * <p>
138      * Latest implementation of {@link RootModificationApplyOperation} is
139      * managed by {@link LatestOperationHolder} which was used to construct this
140      * operation and latest operation is updated by
141      * {@link LatestOperationHolder#setCurrent(ModificationApplyOperation)}.
142      */
143     abstract void upgradeIfPossible();
144
145     static RootModificationApplyOperation from(final ModificationApplyOperation resolver) {
146         if (resolver instanceof RootModificationApplyOperation) {
147             return ((RootModificationApplyOperation) resolver).snapshot();
148         }
149         return new NotUpgradableModificationApplyOperation(resolver);
150     }
151 }