blob: f70e7f53ab064fe721c7ed9f580b82a9288fb8d2 [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>>
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -070021 implements ITopologyElement, StringAttributes, UpdateStringAttributes {
22
23 // TODO: Where should the attribute names be defined?
24 /**
25 * Attribute name for type.
26 */
27 public static final String TYPE = "type";
28 /**
29 * Attribute "type" value representing that the object belongs to Packet layer.
30 */
Yuta HIGUCHIdbc33122014-07-10 13:32:32 -070031 public static final String TYPE_PACKET_LAYER = "packet";
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -070032 /**
33 * Attribute "type" value representing that the object belongs to Optical layer.
34 */
Yuta HIGUCHIdbc33122014-07-10 13:32:32 -070035 public static final String TYPE_OPTICAL_LAYER = "optical";
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -070036
Praseed Balakrishnan2aa6c0b2014-07-17 11:42:05 -070037 public static final String ELEMENT_CONFIG_STATE = "ConfigState";
38
39 public static final String ELEMENT_ADMIN_STATUS = "AdminStatus";
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -070040
Praseed Balakrishnanfa21be12014-07-15 14:42:26 -070041 /**
42 * Attribute name for device type.
43 */
44 public static final String ELEMENT_TYPE = "ElementType";
45
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -070046 private boolean isFrozen = false;
47
48 private ConcurrentMap<String, String> stringAttributes;
49
50
51
52 /**
53 * Default constructor for serializer.
54 */
55 protected TopologyElement() {
56 this.isFrozen = false;
57 this.stringAttributes = new ConcurrentHashMap<>();
58 }
59
60 /**
Yuta HIGUCHI7926ba32014-07-09 11:39:32 -070061 * Creates an unfrozen copy of given Object.
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -070062 * <p/>
63 * Sub-classes should do a deep-copies if necessary.
64 *
65 * @param original to make copy of.
66 */
67 public TopologyElement(TopologyElement<T> original) {
68 this.isFrozen = false;
69 this.stringAttributes = new ConcurrentHashMap<>(original.stringAttributes);
Praseed Balakrishnan2aa6c0b2014-07-17 11:42:05 -070070
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -070071 }
72
73
74 /**
75 * Tests if this instance is frozen.
76 *
77 * @return true if frozen.
78 */
79 public boolean isFrozen() {
80 return isFrozen;
81 }
82
83 /**
84 * Freezes this instance to avoid further modifications.
85 *
86 * @return this
87 */
88 @SuppressWarnings("unchecked")
89 public T freeze() {
90 isFrozen = true;
91 return (T) this;
92 }
93
94 @Override
95 public int hashCode() {
96 return stringAttributes.hashCode();
97 }
98
99 /*
100 * (non-Javadoc)
101 * Equality based only on string attributes.
102 *
103 * Subclasses should call super.equals().
104 */
105 @Override
106 public boolean equals(Object obj) {
107 if (this == obj) {
108 return true;
109 }
110 if (obj == null) {
111 return false;
112 }
113 if (getClass() != obj.getClass()) {
114 return false;
115 }
116 @SuppressWarnings("unchecked")
117 TopologyElement<T> other = (TopologyElement<T>) obj;
118 return Objects.equals(stringAttributes, other.stringAttributes);
119 }
120
121 @Override
122 public String getStringAttribute(String attr) {
123 return this.stringAttributes.get(attr);
124 }
125
126 @Override
127 public String getStringAttribute(String attr, String def) {
128 final String v = getStringAttribute(attr);
129 if (v == null) {
130 return def;
131 } else {
132 return v;
133 }
134 }
135
136 @Override
137 public Map<String, String> getAllStringAttributes() {
138 return Collections.unmodifiableMap(this.stringAttributes);
139 }
140
141 @Override
142 public boolean createStringAttribute(String attr, String value) {
143 if (isFrozen) {
144 throw new IllegalStateException("Tried to modify frozen object: " + this);
145 }
146 Validate.notNull(value, "attribute value cannot be null");
147
148 return this.stringAttributes.putIfAbsent(attr, value) == null;
149 }
150
151 @Override
152 public boolean replaceStringAttribute(String attr, String oldValue, String value) {
153 if (isFrozen) {
154 throw new IllegalStateException("Tried to modify frozen object: " + this);
155 }
156 Validate.notNull(value, "attribute value cannot be null");
157
158 return this.stringAttributes.replace(attr, oldValue, value);
159 }
160
161 @Override
162 public boolean deleteStringAttribute(String attr, String expectedValue) {
163 if (isFrozen) {
164 throw new IllegalStateException("Tried to modify frozen object: " + this);
165 }
166
167 return this.stringAttributes.remove(attr, expectedValue);
168 }
169
170 @Override
171 public void deleteStringAttribute(String attr) {
172 if (isFrozen) {
173 throw new IllegalStateException("Tried to modify frozen object: " + this);
174 }
175
176 this.stringAttributes.remove(attr);
177 }
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -0700178
179 @Override
180 public String getType() {
Yuta HIGUCHIdbc33122014-07-10 13:32:32 -0700181 return getStringAttribute(TYPE, TYPE_PACKET_LAYER);
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -0700182 }
Praseed Balakrishnan2aa6c0b2014-07-17 11:42:05 -0700183
184 /**
185 * Returns the config state of topology element.
186 *
187 * @return ConfigState
188 */
189 @Override
190 public ConfigState getConfigState() {
191 return ConfigState.valueOf(getStringAttribute(ELEMENT_CONFIG_STATE));
192 }
193
194 /**
195 * Returns the status of topology element.
196 *
197 * @return AdminStatus
198 */
199 @Override
200 public AdminStatus getStatus() {
201 return AdminStatus.valueOf(getStringAttribute(ELEMENT_ADMIN_STATUS));
202 }
203
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700204}