Merge "Bug:1238 - Revert changes to SshClientAdapter."
[controller.git] / opendaylight / md-sal / sal-dom-broker / src / main / java / org / opendaylight / controller / md / sal / dom / store / impl / tree / spi / ContainerNode.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.controller.md.sal.dom.store.impl.tree.spi;
9
10 import java.util.HashMap;
11 import java.util.Map;
12
13 import org.opendaylight.yangtools.util.MapAdaptor;
14 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
15 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
16 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
17 import org.opendaylight.yangtools.yang.data.api.schema.OrderedNodeContainer;
18
19 import com.google.common.base.Optional;
20 import com.google.common.base.Preconditions;
21
22 /**
23  * A TreeNode capable of holding child nodes. The fact that any of the children
24  * changed is tracked by the subtree version.
25  */
26 final class ContainerNode extends AbstractTreeNode {
27     private final Map<PathArgument, TreeNode> children;
28     private final Version subtreeVersion;
29
30     protected ContainerNode(final NormalizedNode<?, ?> data, final Version version,
31             final Map<PathArgument, TreeNode> children, final Version subtreeVersion) {
32         super(data, version);
33         this.children = Preconditions.checkNotNull(children);
34         this.subtreeVersion = Preconditions.checkNotNull(subtreeVersion);
35     }
36
37     @Override
38     public Version getSubtreeVersion() {
39         return subtreeVersion;
40     }
41
42     @Override
43     public Optional<TreeNode> getChild(final PathArgument key) {
44         return Optional.fromNullable(children.get(key));
45     }
46
47     @Override
48     public MutableTreeNode mutable() {
49         return new Mutable(this);
50     }
51
52     private static final class Mutable implements MutableTreeNode {
53         private final Version version;
54         private Map<PathArgument, TreeNode> children;
55         private NormalizedNode<?, ?> data;
56         private Version subtreeVersion;
57
58         private Mutable(final ContainerNode parent) {
59             this.data = parent.getData();
60             this.children = MapAdaptor.getDefaultInstance().takeSnapshot(parent.children);
61             this.subtreeVersion = parent.getSubtreeVersion();
62             this.version = parent.getVersion();
63         }
64
65         @Override
66         public Optional<TreeNode> getChild(final PathArgument child) {
67             return Optional.fromNullable(children.get(child));
68         }
69
70         @Override
71         public void setSubtreeVersion(final Version subtreeVersion) {
72             this.subtreeVersion = Preconditions.checkNotNull(subtreeVersion);
73         }
74
75         @Override
76         public void addChild(final TreeNode child) {
77             children.put(child.getIdentifier(), child);
78         }
79
80         @Override
81         public void removeChild(final PathArgument id) {
82             children.remove(id);
83         }
84
85         @Override
86         public TreeNode seal() {
87             final TreeNode ret = new ContainerNode(data, version, MapAdaptor.getDefaultInstance().optimize(children), subtreeVersion);
88
89             // This forces a NPE if this class is accessed again. Better than corruption.
90             children = null;
91             return ret;
92         }
93
94         @Override
95         public void setData(final NormalizedNode<?, ?> data) {
96             this.data = Preconditions.checkNotNull(data);
97         }
98     }
99
100     private static ContainerNode create(final Version version, final NormalizedNode<?, ?> data,
101             final Iterable<NormalizedNode<?, ?>> children) {
102
103         final Map<PathArgument, TreeNode> map = new HashMap<>();
104         for (NormalizedNode<?, ?> child : children) {
105             map.put(child.getIdentifier(), TreeNodeFactory.createTreeNode(child, version));
106         }
107
108         return new ContainerNode(data, version, map, version);
109     }
110
111     public static ContainerNode create(final Version version, final NormalizedNodeContainer<?, ?, NormalizedNode<?, ?>> container) {
112         return create(version, container, container.getValue());
113     }
114
115     public static ContainerNode create(final Version version, final OrderedNodeContainer<NormalizedNode<?, ?>> container) {
116         return create(version, container, container.getValue());
117     }
118 }