20bf61914f57af53e98a9250a3be0877611e9767
[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.Collections;
11 import java.util.HashMap;
12 import java.util.Map;
13
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 import com.google.common.primitives.UnsignedLong;
22
23 /**
24  * A TreeNode capable of holding child nodes. The fact that any of the children
25  * changed is tracked by the subtree version.
26  */
27 final class ContainerNode extends AbstractTreeNode {
28     private final Map<PathArgument, TreeNode> children;
29     private final UnsignedLong subtreeVersion;
30
31     protected ContainerNode(final NormalizedNode<?, ?> data, final UnsignedLong version,
32             final Map<PathArgument, TreeNode> children, final UnsignedLong subtreeVersion) {
33         super(data, version);
34         this.children = Preconditions.checkNotNull(children);
35         this.subtreeVersion = Preconditions.checkNotNull(subtreeVersion);
36     }
37
38     @Override
39     public UnsignedLong getSubtreeVersion() {
40         return subtreeVersion;
41     }
42
43     @Override
44     public Optional<TreeNode> getChild(final PathArgument key) {
45         return Optional.fromNullable(children.get(key));
46     }
47
48     @Override
49     public MutableTreeNode mutable() {
50         return new Mutable(this);
51     }
52
53     private static final class Mutable implements MutableTreeNode {
54         private final Map<PathArgument, TreeNode> children;
55         private final UnsignedLong version;
56         private NormalizedNode<?, ?> data;
57         private UnsignedLong subtreeVersion;
58
59         private Mutable(final ContainerNode parent) {
60             this.data = parent.getData();
61             this.children = new HashMap<>(parent.children);
62             this.subtreeVersion = parent.getSubtreeVersion();
63             this.version = parent.getVersion();
64         }
65
66         @Override
67         public Optional<TreeNode> getChild(final PathArgument child) {
68             return Optional.fromNullable(children.get(child));
69         }
70
71         @Override
72         public void setSubtreeVersion(final UnsignedLong subtreeVersion) {
73             this.subtreeVersion = Preconditions.checkNotNull(subtreeVersion);
74         }
75
76         @Override
77         public void addChild(final TreeNode child) {
78             children.put(child.getIdentifier(), child);
79         }
80
81         @Override
82         public void removeChild(final PathArgument id) {
83             children.remove(id);
84         }
85
86         @Override
87         public TreeNode seal() {
88             final Map<PathArgument, TreeNode> realChildren;
89
90             if (children.isEmpty()) {
91                 realChildren = Collections.emptyMap();
92             } else {
93                 realChildren = children;
94             }
95
96             return new ContainerNode(data, version, realChildren, subtreeVersion);
97         }
98
99         @Override
100         public void setData(final NormalizedNode<?, ?> data) {
101             this.data = Preconditions.checkNotNull(data);
102         }
103     }
104
105     private static ContainerNode create(final UnsignedLong version, final NormalizedNode<?, ?> data, final Iterable<NormalizedNode<?, ?>> children) {
106         final Map<PathArgument, TreeNode> map = new HashMap<>();
107
108         for (NormalizedNode<?, ?> child : children) {
109             map.put(child.getIdentifier(), TreeNodeFactory.createTreeNode(child, version));
110         }
111
112         return new ContainerNode(data, version, map, version);
113     }
114
115     public static ContainerNode create(final UnsignedLong version, final NormalizedNodeContainer<?, ?, NormalizedNode<?, ?>> container) {
116         return create(version, container, container.getValue());
117     }
118
119     public static ContainerNode create(final UnsignedLong version, final OrderedNodeContainer<NormalizedNode<?, ?>> container) {
120         return create(version, container, container.getValue());
121     }
122 }