2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.yangtools.yang.data.api.schema.tree.spi;
10 import java.util.HashMap;
13 import org.opendaylight.yangtools.util.MapAdaptor;
14 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.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;
19 import com.google.common.base.Optional;
20 import com.google.common.base.Preconditions;
23 * A TreeNode capable of holding child nodes. The fact that any of the children
24 * changed is tracked by the subtree version.
26 final class ContainerNode extends AbstractTreeNode {
27 private final Map<PathArgument, TreeNode> children;
28 private final Version subtreeVersion;
30 protected ContainerNode(final NormalizedNode<?, ?> data, final Version version,
31 final Map<PathArgument, TreeNode> children, final Version subtreeVersion) {
33 this.children = Preconditions.checkNotNull(children);
34 this.subtreeVersion = Preconditions.checkNotNull(subtreeVersion);
38 public Version getSubtreeVersion() {
39 return subtreeVersion;
43 public Optional<TreeNode> getChild(final PathArgument key) {
44 return Optional.fromNullable(children.get(key));
48 public MutableTreeNode mutable() {
49 return new Mutable(this);
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;
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();
66 public Optional<TreeNode> getChild(final PathArgument child) {
67 return Optional.fromNullable(children.get(child));
71 public void setSubtreeVersion(final Version subtreeVersion) {
72 this.subtreeVersion = Preconditions.checkNotNull(subtreeVersion);
76 public void addChild(final TreeNode child) {
77 children.put(child.getIdentifier(), child);
81 public void removeChild(final PathArgument id) {
86 public TreeNode seal() {
87 final TreeNode ret = new ContainerNode(data, version, MapAdaptor.getDefaultInstance().optimize(children), subtreeVersion);
89 // This forces a NPE if this class is accessed again. Better than corruption.
95 public void setData(final NormalizedNode<?, ?> data) {
96 this.data = Preconditions.checkNotNull(data);
100 private static ContainerNode create(final Version version, final NormalizedNode<?, ?> data,
101 final Iterable<NormalizedNode<?, ?>> children) {
103 final Map<PathArgument, TreeNode> map = new HashMap<>();
104 for (NormalizedNode<?, ?> child : children) {
105 map.put(child.getIdentifier(), TreeNodeFactory.createTreeNode(child, version));
108 return new ContainerNode(data, version, map, version);
111 public static ContainerNode create(final Version version, final NormalizedNodeContainer<?, ?, NormalizedNode<?, ?>> container) {
112 return create(version, container, container.getValue());
115 public static ContainerNode create(final Version version, final OrderedNodeContainer<NormalizedNode<?, ?>> container) {
116 return create(version, container, container.getValue());