Improve TreeNode and Version documentation
[yangtools.git] / data / yang-data-tree-ri / src / main / java / org / opendaylight / yangtools / yang / data / tree / impl / node / TreeNode.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.tree.impl.node;
9
10 import static java.util.Objects.requireNonNull;
11
12 import com.google.common.base.MoreObjects;
13 import com.google.common.base.MoreObjects.ToStringHelper;
14 import org.eclipse.jdt.annotation.NonNullByDefault;
15 import org.opendaylight.yangtools.concepts.Identifiable;
16 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
17 import org.opendaylight.yangtools.yang.data.api.schema.DistinctNodeContainer;
18 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
19 import org.opendaylight.yangtools.yang.data.api.schema.OrderedNodeContainer;
20 import org.opendaylight.yangtools.yang.data.api.schema.tree.StoreTreeNode;
21
22 /**
23  * A very basic data tree node. It has a {@link #getVersion()} (when it was last modified),
24  * a {@link #getSubtreeVersion()} (when any of its children were modified) and some read-only data. In terms of
25  * <a href="https://en.wikipedia.org/wiki/Multiversion_concurrency_control#Implementation">MVCC</a>, the former
26  * corresponds to the this node's current Read Timestamp (RTS(P), where P is this node). The latter is the most recent
27  * Read Timestamp in this node's accessible children.
28  *
29  * <p>
30  * Semantic difference between these two is important when dealing with modifications involving parent/child
31  * relationships and what operations can be execute concurrently without creating a data dependency conflict.
32  *
33  * <p>
34  * A replace/delete operation cannot be applied to this node if the subtree version does not match. This mismatch
35  * still allows modifications to its descendants.
36  *
37  * <p>
38  * A mismatch in node version indicates a replacement, preventing a modification of descendants or itself.
39  */
40 // FIXME: BUG-2399: clarify that versioning rules are not enforced for non-presence containers, as they are not
41 //                  considered to be data nodes.
42 @NonNullByDefault
43 public abstract class TreeNode implements Identifiable<PathArgument>, StoreTreeNode<TreeNode> {
44     private final NormalizedNode data;
45     private final Version version;
46
47     TreeNode(final NormalizedNode data, final Version version) {
48         this.data = requireNonNull(data);
49         this.version = requireNonNull(version);
50     }
51
52     /**
53      * Create a new AbstractTreeNode from a data node.
54      *
55      * @param data data node
56      * @param version data node version
57      * @return new AbstractTreeNode instance, covering the data tree provided
58      */
59     public static final TreeNode of(final NormalizedNode data, final Version version) {
60         if (data instanceof DistinctNodeContainer) {
61             @SuppressWarnings("unchecked")
62             final DistinctNodeContainer<?, NormalizedNode> container = (DistinctNodeContainer<?, NormalizedNode>) data;
63             return new SimpleContainerNode(container, version);
64         } else if (data instanceof OrderedNodeContainer) {
65             return new SimpleContainerNode(data, version);
66         } else {
67             return new ValueNode(data, version);
68         }
69     }
70
71     @Override
72     public final PathArgument getIdentifier() {
73         return data.getIdentifier();
74     }
75
76     /**
77      * Get the data node version. This version is updated whenever the data representation of this particular node
78      * changes as a result of a direct write to this node or to its parent nodes -- thus indicating that this node
79      * was logically replaced.
80      *
81      * @return Current data node version.
82      */
83     public final Version getVersion() {
84         return version;
85     }
86
87     /**
88      * Get the subtree version. This version is updated whenever the data representation of this particular node
89      * changes as the result of a direct or indirect child node being created, replaced or removed.
90      *
91      * @return Current subtree version.
92      */
93     public abstract Version getSubtreeVersion();
94
95     /**
96      * Get a read-only view of the underlying data.
97      *
98      * @return Unmodifiable view of the underlying data.
99      */
100     public final NormalizedNode getData() {
101         return data;
102     }
103
104     /**
105      * Get a mutable, isolated copy of the node.
106      *
107      * @return Mutable copy
108      */
109     public abstract MutableTreeNode mutable();
110
111     @Override
112     public final String toString() {
113         return addToStringAttributes(MoreObjects.toStringHelper(this).add("version", version)).toString();
114     }
115
116     abstract ToStringHelper addToStringAttributes(ToStringHelper helper);
117 }