693ace4df2759b44f0b380ab70bd67d2bf6aa2e9
[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, final Optional<TreeNode> current)
71             throws DataValidationFailedException {
72         getDelegate().checkApplicable(path, modification, current);
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     final ChildTrackingPolicy getChildPolicy() {
104         return getDelegate().getChildPolicy();
105     }
106
107     /**
108      * Return the underlying delegate.
109      *
110      * @return Underlying delegate.
111      */
112     abstract ModificationApplyOperation getDelegate();
113
114     /**
115      * Creates a snapshot from this modification, which may have separate
116      * upgrade lifecycle and is not affected by upgrades
117      * <p>
118      * Newly created snapshot uses backing implementation of this modi
119      *
120      * @return Derived {@link RootModificationApplyOperation} with separate
121      *         upgrade lifecycle.
122      */
123     abstract RootModificationApplyOperation snapshot();
124
125     /**
126      * Upgrades backing implementation to latest available, if possible.
127      * <p>
128      * Latest implementation of {@link RootModificationApplyOperation} is
129      * managed by {@link LatestOperationHolder} which was used to construct this
130      * operation and latest operation is updated by
131      * {@link LatestOperationHolder#setCurrent(ModificationApplyOperation)}.
132      */
133     abstract void upgradeIfPossible();
134
135     static RootModificationApplyOperation from(final ModificationApplyOperation resolver) {
136         if (resolver instanceof RootModificationApplyOperation) {
137             return ((RootModificationApplyOperation) resolver).snapshot();
138         }
139         return new NotUpgradableModificationApplyOperation(resolver);
140     }
141 }