blob: 0f5d66a7587416de221b2a6a64330b1ce0e369b2 [file] [log] [blame]
Madan Jampaniad5b8c72016-09-12 15:05:01 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Madan Jampaniad5b8c72016-09-12 15:05:01 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.store.primitives.resources.impl;
18
19import static com.google.common.base.Preconditions.checkNotNull;
20
21import java.util.Iterator;
Jordan Haltermand0d80352017-08-10 15:08:27 -070022import java.util.Map;
Madan Jampaniad5b8c72016-09-12 15:05:01 -070023import java.util.Objects;
Madan Jampaniad5b8c72016-09-12 15:05:01 -070024
25import org.onosproject.store.service.DocumentPath;
26import org.onosproject.store.service.DocumentTreeNode;
Jordan Haltermand0d80352017-08-10 15:08:27 -070027import org.onosproject.store.service.Ordering;
Madan Jampaniad5b8c72016-09-12 15:05:01 -070028import org.onosproject.store.service.Versioned;
29
30import com.google.common.base.MoreObjects;
31import com.google.common.collect.ImmutableList;
32import com.google.common.collect.Maps;
33import com.google.common.collect.Sets;
34
35/**
36 * A {@code DocumentTree} node.
37 */
38public class DefaultDocumentTreeNode<V> implements DocumentTreeNode<V> {
39 private final DocumentPath key;
40 private Versioned<V> value;
Jordan Haltermand0d80352017-08-10 15:08:27 -070041 private final Map<String, DocumentTreeNode<V>> children;
42 private final Ordering ordering;
Madan Jampaniad5b8c72016-09-12 15:05:01 -070043 private final DocumentTreeNode<V> parent;
44
45 public DefaultDocumentTreeNode(DocumentPath key,
Jordan Halterman2bf177c2017-06-29 01:49:08 -070046 V value,
47 long version,
Jordan Haltermand0d80352017-08-10 15:08:27 -070048 Ordering ordering,
Jordan Halterman2bf177c2017-06-29 01:49:08 -070049 DocumentTreeNode<V> parent) {
Madan Jampaniad5b8c72016-09-12 15:05:01 -070050 this.key = checkNotNull(key);
51 this.value = new Versioned<>(value, version);
Jordan Haltermand0d80352017-08-10 15:08:27 -070052 this.ordering = ordering;
Madan Jampaniad5b8c72016-09-12 15:05:01 -070053 this.parent = parent;
Jordan Haltermand0d80352017-08-10 15:08:27 -070054
55 switch (ordering) {
56 case INSERTION:
57 children = Maps.newLinkedHashMap();
58 break;
59 case NATURAL:
60 default:
61 children = Maps.newTreeMap();
62 break;
63 }
Madan Jampaniad5b8c72016-09-12 15:05:01 -070064 }
65
66 @Override
67 public DocumentPath path() {
68 return key;
69 }
70
71 @Override
72 public Versioned<V> value() {
73 return value;
74 }
75
76 @Override
77 public Iterator<DocumentTreeNode<V>> children() {
78 return ImmutableList.copyOf(children.values()).iterator();
79 }
80
81 @Override
82 public DocumentTreeNode<V> child(String name) {
83 return children.get(name);
84 }
85
86
87 public DocumentTreeNode<V> parent() {
88 return parent;
89 }
90
91 /**
92 * Adds a new child only if one does not exist with the name.
93 * @param name relative path name of the child node
94 * @param newValue new value to set
95 * @param newVersion new version to set
96 * @return previous value; can be {@code null} if no child currently exists with that relative path name.
Frank Wangd8ab0962017-08-11 11:09:30 +080097 * a non null return value indicates child already exists and no modification occurred.
Madan Jampaniad5b8c72016-09-12 15:05:01 -070098 */
99 public Versioned<V> addChild(String name, V newValue, long newVersion) {
100 DefaultDocumentTreeNode<V> child = (DefaultDocumentTreeNode<V>) children.get(name);
101 if (child != null) {
102 return child.value();
103 }
Jordan Haltermand0d80352017-08-10 15:08:27 -0700104 children.put(name, new DefaultDocumentTreeNode<>(
105 new DocumentPath(name, path()), newValue, newVersion, ordering, this));
Madan Jampaniad5b8c72016-09-12 15:05:01 -0700106 return null;
107 }
108
109 /**
110 * Updates the node value.
111 *
112 * @param newValue new value to set
113 * @param newVersion new version to set
114 * @return previous value
115 */
116 public Versioned<V> update(V newValue, long newVersion) {
117 Versioned<V> previousValue = value;
118 value = new Versioned<>(newValue, newVersion);
119 return previousValue;
120 }
121
122
123 /**
124 * Removes a child node.
125 *
126 * @param name the name of child node to be removed
127 * @return {@code true} if the child set was modified as a result of this call, {@code false} otherwise
128 */
129 public boolean removeChild(String name) {
130 return children.remove(name) != null;
131 }
132
133 @Override
134 public int hashCode() {
135 return Objects.hash(this.key);
136 }
137
138 @Override
139 public boolean equals(Object obj) {
140 if (obj instanceof DefaultDocumentTreeNode) {
141 DefaultDocumentTreeNode<V> that = (DefaultDocumentTreeNode<V>) obj;
142 if (this.parent.equals(that.parent)) {
143 if (this.children.size() == that.children.size()) {
144 return Sets.symmetricDifference(this.children.keySet(), that.children.keySet()).isEmpty();
145 }
146 }
147 }
148 return false;
149 }
150
151 @Override
152 public String toString() {
153 MoreObjects.ToStringHelper helper =
154 MoreObjects.toStringHelper(getClass())
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700155 .add("parent", this.parent)
156 .add("key", this.key)
157 .add("value", this.value);
Madan Jampaniad5b8c72016-09-12 15:05:01 -0700158 for (DocumentTreeNode<V> child : children.values()) {
Aaron Kruglikov9e11b582016-10-20 17:04:55 -0700159 helper = helper.add("child", "\n" + child.path().pathElements()
160 .get(child.path().pathElements().size() - 1) +
161 " : " + child.value());
Madan Jampaniad5b8c72016-09-12 15:05:01 -0700162 }
163 return helper.toString();
164 }
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700165}