blob: bb3295893d4e151ad6b8abf8d1b729a07d9b744f [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 /**
Pavlin Radoslavov695f8952014-07-23 16:57:01 -070029 * Attribute "type" value representing that the object belongs to Packet
30 * layer.
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -070031 */
Yuta HIGUCHIdbc33122014-07-10 13:32:32 -070032 public static final String TYPE_PACKET_LAYER = "packet";
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -070033 /**
Pavlin Radoslavov695f8952014-07-23 16:57:01 -070034 * Attribute "type" value representing that the object belongs to Optical
35 * layer.
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -070036 */
Yuta HIGUCHIdbc33122014-07-10 13:32:32 -070037 public static final String TYPE_OPTICAL_LAYER = "optical";
Pavlin Radoslavov695f8952014-07-23 16:57:01 -070038 /**
39 * Attribute "type" value representing that the object belongs to all
40 * layers.
41 */
42 public static final String TYPE_ALL_LAYERS = "AllLayers";
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -070043
Praseed Balakrishnan2aa6c0b2014-07-17 11:42:05 -070044 public static final String ELEMENT_CONFIG_STATE = "ConfigState";
45
46 public static final String ELEMENT_ADMIN_STATUS = "AdminStatus";
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -070047
Praseed Balakrishnanfa21be12014-07-15 14:42:26 -070048 /**
49 * Attribute name for device type.
50 */
51 public static final String ELEMENT_TYPE = "ElementType";
52
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -070053 private boolean isFrozen = false;
54
55 private ConcurrentMap<String, String> stringAttributes;
56
57
58
59 /**
60 * Default constructor for serializer.
61 */
62 protected TopologyElement() {
63 this.isFrozen = false;
64 this.stringAttributes = new ConcurrentHashMap<>();
65 }
66
67 /**
Yuta HIGUCHI7926ba32014-07-09 11:39:32 -070068 * Creates an unfrozen copy of given Object.
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -070069 * <p/>
70 * Sub-classes should do a deep-copies if necessary.
71 *
72 * @param original to make copy of.
73 */
74 public TopologyElement(TopologyElement<T> original) {
75 this.isFrozen = false;
76 this.stringAttributes = new ConcurrentHashMap<>(original.stringAttributes);
Praseed Balakrishnan2aa6c0b2014-07-17 11:42:05 -070077
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -070078 }
79
80
81 /**
82 * Tests if this instance is frozen.
83 *
84 * @return true if frozen.
85 */
86 public boolean isFrozen() {
87 return isFrozen;
88 }
89
90 /**
91 * Freezes this instance to avoid further modifications.
92 *
93 * @return this
94 */
95 @SuppressWarnings("unchecked")
96 public T freeze() {
97 isFrozen = true;
98 return (T) this;
99 }
100
101 @Override
102 public int hashCode() {
103 return stringAttributes.hashCode();
104 }
105
106 /*
107 * (non-Javadoc)
108 * Equality based only on string attributes.
109 *
110 * Subclasses should call super.equals().
111 */
112 @Override
113 public boolean equals(Object obj) {
114 if (this == obj) {
115 return true;
116 }
117 if (obj == null) {
118 return false;
119 }
120 if (getClass() != obj.getClass()) {
121 return false;
122 }
123 @SuppressWarnings("unchecked")
124 TopologyElement<T> other = (TopologyElement<T>) obj;
125 return Objects.equals(stringAttributes, other.stringAttributes);
126 }
127
128 @Override
129 public String getStringAttribute(String attr) {
130 return this.stringAttributes.get(attr);
131 }
132
133 @Override
134 public String getStringAttribute(String attr, String def) {
135 final String v = getStringAttribute(attr);
136 if (v == null) {
137 return def;
138 } else {
139 return v;
140 }
141 }
142
143 @Override
144 public Map<String, String> getAllStringAttributes() {
145 return Collections.unmodifiableMap(this.stringAttributes);
146 }
147
148 @Override
149 public boolean createStringAttribute(String attr, String value) {
150 if (isFrozen) {
151 throw new IllegalStateException("Tried to modify frozen object: " + this);
152 }
153 Validate.notNull(value, "attribute value cannot be null");
154
155 return this.stringAttributes.putIfAbsent(attr, value) == null;
156 }
157
158 @Override
159 public boolean replaceStringAttribute(String attr, String oldValue, String value) {
160 if (isFrozen) {
161 throw new IllegalStateException("Tried to modify frozen object: " + this);
162 }
163 Validate.notNull(value, "attribute value cannot be null");
164
165 return this.stringAttributes.replace(attr, oldValue, value);
166 }
167
168 @Override
169 public boolean deleteStringAttribute(String attr, String expectedValue) {
170 if (isFrozen) {
171 throw new IllegalStateException("Tried to modify frozen object: " + this);
172 }
173
174 return this.stringAttributes.remove(attr, expectedValue);
175 }
176
177 @Override
178 public void deleteStringAttribute(String attr) {
179 if (isFrozen) {
180 throw new IllegalStateException("Tried to modify frozen object: " + this);
181 }
182
183 this.stringAttributes.remove(attr);
184 }
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -0700185
186 @Override
187 public String getType() {
Yuta HIGUCHIdbc33122014-07-10 13:32:32 -0700188 return getStringAttribute(TYPE, TYPE_PACKET_LAYER);
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -0700189 }
Praseed Balakrishnan2aa6c0b2014-07-17 11:42:05 -0700190
191 /**
192 * Returns the config state of topology element.
193 *
194 * @return ConfigState
195 */
196 @Override
197 public ConfigState getConfigState() {
198 return ConfigState.valueOf(getStringAttribute(ELEMENT_CONFIG_STATE));
199 }
200
201 /**
202 * Returns the status of topology element.
203 *
204 * @return AdminStatus
205 */
206 @Override
207 public AdminStatus getStatus() {
208 return AdminStatus.valueOf(getStringAttribute(ELEMENT_ADMIN_STATUS));
209 }
210
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700211}