blob: ceaf0fc5c2b111577a2b9e56010bc4cc6e346401 [file] [log] [blame]
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -07001package net.onrc.onos.core.topology;
2
3import java.util.Collections;
4import java.util.Map;
5import java.util.Objects;
6import java.util.concurrent.ConcurrentHashMap;
7import java.util.concurrent.ConcurrentMap;
8
9import org.apache.commons.lang.Validate;
10
11/**
12 * Base class for Topology Elements.
13 * <p/>
14 * Self-contained element, it is expected to be used as if it is an immutable
15 * object.
16 *
17 * @param <T> Sub-class' type.
18 * (Required to define a method returning itself's type)
19 */
20public class TopologyElement<T extends TopologyElement<T>>
21 implements StringAttributes, UpdateStringAttributes {
22
23 private boolean isFrozen = false;
24
25 private ConcurrentMap<String, String> stringAttributes;
26
27
28
29 /**
30 * Default constructor for serializer.
31 */
32 protected TopologyElement() {
33 this.isFrozen = false;
34 this.stringAttributes = new ConcurrentHashMap<>();
35 }
36
37 /**
Yuta HIGUCHI7926ba32014-07-09 11:39:32 -070038 * Creates an unfrozen copy of given Object.
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -070039 * <p/>
40 * Sub-classes should do a deep-copies if necessary.
41 *
42 * @param original to make copy of.
43 */
44 public TopologyElement(TopologyElement<T> original) {
45 this.isFrozen = false;
46 this.stringAttributes = new ConcurrentHashMap<>(original.stringAttributes);
47 }
48
49
50 /**
51 * Tests if this instance is frozen.
52 *
53 * @return true if frozen.
54 */
55 public boolean isFrozen() {
56 return isFrozen;
57 }
58
59 /**
60 * Freezes this instance to avoid further modifications.
61 *
62 * @return this
63 */
64 @SuppressWarnings("unchecked")
65 public T freeze() {
66 isFrozen = true;
67 return (T) this;
68 }
69
70 @Override
71 public int hashCode() {
72 return stringAttributes.hashCode();
73 }
74
75 /*
76 * (non-Javadoc)
77 * Equality based only on string attributes.
78 *
79 * Subclasses should call super.equals().
80 */
81 @Override
82 public boolean equals(Object obj) {
83 if (this == obj) {
84 return true;
85 }
86 if (obj == null) {
87 return false;
88 }
89 if (getClass() != obj.getClass()) {
90 return false;
91 }
92 @SuppressWarnings("unchecked")
93 TopologyElement<T> other = (TopologyElement<T>) obj;
94 return Objects.equals(stringAttributes, other.stringAttributes);
95 }
96
97 @Override
98 public String getStringAttribute(String attr) {
99 return this.stringAttributes.get(attr);
100 }
101
102 @Override
103 public String getStringAttribute(String attr, String def) {
104 final String v = getStringAttribute(attr);
105 if (v == null) {
106 return def;
107 } else {
108 return v;
109 }
110 }
111
112 @Override
113 public Map<String, String> getAllStringAttributes() {
114 return Collections.unmodifiableMap(this.stringAttributes);
115 }
116
117 @Override
118 public boolean createStringAttribute(String attr, String value) {
119 if (isFrozen) {
120 throw new IllegalStateException("Tried to modify frozen object: " + this);
121 }
122 Validate.notNull(value, "attribute value cannot be null");
123
124 return this.stringAttributes.putIfAbsent(attr, value) == null;
125 }
126
127 @Override
128 public boolean replaceStringAttribute(String attr, String oldValue, String value) {
129 if (isFrozen) {
130 throw new IllegalStateException("Tried to modify frozen object: " + this);
131 }
132 Validate.notNull(value, "attribute value cannot be null");
133
134 return this.stringAttributes.replace(attr, oldValue, value);
135 }
136
137 @Override
138 public boolean deleteStringAttribute(String attr, String expectedValue) {
139 if (isFrozen) {
140 throw new IllegalStateException("Tried to modify frozen object: " + this);
141 }
142
143 return this.stringAttributes.remove(attr, expectedValue);
144 }
145
146 @Override
147 public void deleteStringAttribute(String attr) {
148 if (isFrozen) {
149 throw new IllegalStateException("Tried to modify frozen object: " + this);
150 }
151
152 this.stringAttributes.remove(attr);
153 }
154}