fc3d51cc1f402551d992f0969c5acd8da8263327
[controller.git] / opendaylight / sal / api / src / main / java / org / opendaylight / controller / sal / core / NodeTable.java
1 /*
2  * Copyright (c) 2013 Big Switch Networks, Inc.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.controller.sal.core;
9
10 import java.io.Serializable;
11 import java.util.Set;
12 import java.util.UUID;
13 import java.util.concurrent.ConcurrentHashMap;
14
15 import javax.xml.bind.annotation.XmlAccessType;
16 import javax.xml.bind.annotation.XmlAccessorType;
17 import javax.xml.bind.annotation.XmlElement;
18 import javax.xml.bind.annotation.XmlRootElement;
19
20 @XmlRootElement
21 @XmlAccessorType(XmlAccessType.NONE)
22 public class NodeTable implements Serializable {
23
24     private static final long serialVersionUID = 1L;
25     public static final Short SPECIALNODETABLEID = (short) 0;
26
27     /**
28      * Enum-like static class created with the purpose of identifing
29      * multiple type of nodes in the SDN network. The type is
30      * necessary to figure out to later on correctly use the
31      * nodeTableID. Using a static class instead of an Enum so we can add
32      * dynamically new types without changing anything in the
33      * surround.
34      */
35     public static final class NodeTableIDType {
36         private static final ConcurrentHashMap<String, Class<? extends Object>> compatibleType =
37                 new ConcurrentHashMap<String, Class<? extends Object>>();
38         /**
39          * These are in compliance with the compatibility types in 'Node'
40          */
41         public static String OPENFLOW = "OF";
42         public static String PCEP = "PE";
43         public static String ONEPK = "PK";
44         public static String PRODUCTION = "PR";
45
46         // Pre-populated types, just here for convenience and ease of
47         // unit-testing, but certainly those could live also outside.
48         // Currently we allow these 4. It can be changed later.
49         static {
50             compatibleType.put(OPENFLOW, Byte.class);
51             compatibleType.put(PCEP, UUID.class);
52             compatibleType.put(ONEPK, String.class);
53             compatibleType.put(PRODUCTION, String.class);
54         }
55
56         /**
57          * Return the type of the class expected for the
58          * NodeTableID, it's used for validity check in the constructor
59          *
60          * @param type, the type of the NodeTable for which we
61          * want to retrieve the compatible class to be used as ID.
62          *
63          * @return The Class which is supposed to instantiate the ID
64          * for the NodeTableID
65          */
66         public static Class<?> getClassType(String type) {
67             return compatibleType.get(type);
68         }
69
70         /**
71          * Returns all the registered nodeTableIDTypes currently available
72          *
73          * @return The current registered NodeTableIDTypes
74          */
75         public static Set<String> values() {
76             return compatibleType.keySet();
77         }
78
79         /**
80          * Register a new ID for which NodeTable can be created
81          *
82          * @param type, the new type being registered
83          * @param compatibleID, the type of class to be accepted as ID
84          *
85          * @return true if registered, false otherwise
86          */
87         public static boolean registerIDType(String type,
88                 Class<? extends Object> compatibleID) {
89             if (compatibleType.get(type) != null) {
90                 return false;
91             }  else {
92                 compatibleType.put(type, compatibleID);
93                 return true;
94             }
95         }
96
97         /**
98          * UNRegister a new ID for which Node can be created
99          *
100          * @param type, the type being UN-registered
101          *
102          */
103         public static void unRegisterIDType(String type) {
104             compatibleType.remove(type);
105         }
106     }
107
108     // Elements that constitute the NodeTable
109     private Object nodeTableID;
110     private String nodeTableType;
111     @XmlElement(name = "node")
112     private Node nodeTableNode;
113
114     // Helper field for JAXB
115     private String nodeTableIDString;
116
117     /**
118      * Private constructor used for JAXB mapping
119      */
120     @SuppressWarnings("unused")
121     private NodeTable() {
122         this.nodeTableIDString = null;
123         this.nodeTableID = null;
124         this.nodeTableType = null;
125         this.nodeTableNode = null;
126     }
127
128     public NodeTable(String nodeTableType, Object id, Node node) throws ConstructionException {
129         if (NodeTableIDType.getClassType(nodeTableType) != null &&
130                 NodeTableIDType.getClassType(nodeTableType).isInstance(id) &&
131                 node.getType().equals(nodeTableType)) {
132             this.nodeTableType = nodeTableType;
133             this.nodeTableID = id;
134             this.nodeTableNode = node;
135         } else {
136             throw new ConstructionException("Type of incoming object:"
137                     + id.getClass() + " not compatible with expected type:"
138                     + NodeTableIDType.getClassType(nodeTableType)
139                     + " or Node type incompatible:" + node.getType());
140         }
141     }
142
143     /**
144      * Copy constructor for NodeTable
145      *
146      * @param src NodeTable to copy from
147      *
148      */
149     public NodeTable(NodeTable src) throws ConstructionException {
150         if (src != null) {
151             this.nodeTableType = src.getType();
152             // Here we can reference the object because that is
153             // supposed to be an immutable identifier as well like a
154             // UUID/Integer and so on, hence no need to create a copy
155             // of it
156             this.nodeTableID = src.getID();
157             this.nodeTableNode = new Node(src.getNode());
158         } else {
159             throw
160             new ConstructionException("Null incoming object to copy from");
161         }
162     }
163
164     /**
165      * @return the nodeTableID
166      */
167     public Object getID() {
168         return this.nodeTableID;
169     }
170
171     /**
172      * @return the nodeTableType
173      */
174     public String getType() {
175         return this.nodeTableType;
176     }
177
178     /**
179      * @param type the nodeTableType to set
180      *
181      * Private setter for nodeConnectorType to be called by JAXB not by anyone
182      * else, NodeConnector is immutable
183      */
184     private void setType(String type) {
185         this.nodeTableType = type;
186         if (this.nodeTableIDString != null) {
187             this.fillmeFromString(type, this.nodeTableIDString);
188         }
189     }
190
191     /**
192      * @return the nodeTableNode
193      */
194     public Node getNode() {
195         return this.nodeTableNode;
196     }
197
198     /**
199      * @param nodeTableNode the nodeTableNode to set
200      */
201     public void setNodeTableNode(Node nodeTableNode) {
202         this.nodeTableNode = nodeTableNode;
203     }
204
205     /**
206      * @return the nodeTableIDString
207      */
208     @XmlElement(name = "id")
209     public String getNodeTableIDString() {
210         return this.nodeTableIDString != null? this.nodeTableIDString : nodeTableID.toString();
211     }
212
213     /**
214      * @param nodeTableIDString the nodeTableIDString to set
215      */
216     @SuppressWarnings("unused")
217     private void setNodeTableIDString(String IDStr) {
218         this.nodeTableIDString = IDStr;
219         if (this.nodeTableType != null) {
220             this.fillmeFromString(this.nodeTableType, IDStr);
221         }
222     }
223
224     /**
225      * fill the current object from the string parameters passed, will
226      * be only used by JAXB
227      *
228      * @param typeStr string representing the type of the Node
229      * @param IDStr String representation of the ID
230      */
231     private void fillmeFromString(String typeStr, String IDStr) {
232         if (typeStr == null) {
233             return;
234         }
235
236         if (IDStr == null) {
237             return;
238         }
239
240         this.nodeTableType = typeStr;
241         this.nodeTableID = (byte) Byte.parseByte(IDStr);
242     }
243
244     @Override
245     public int hashCode() {
246         final int prime = 31;
247         int result = 1;
248         result = prime * result
249                 + ((nodeTableID == null) ? 0 : nodeTableID.hashCode());
250         result = prime
251                 * result
252                 + ((nodeTableNode == null) ? 0 : nodeTableNode
253                         .hashCode());
254         result = prime
255                 * result
256                 + ((nodeTableType == null) ? 0 : nodeTableType
257                         .hashCode());
258         return result;
259     }
260
261     @Override
262     public boolean equals(Object obj) {
263         if (this == obj)
264             return true;
265         if (obj == null)
266             return false;
267         if (getClass() != obj.getClass())
268             return false;
269         NodeTable other = (NodeTable) obj;
270         if (nodeTableID == null) {
271             if (other.nodeTableID != null)
272                 return false;
273         } else if (!nodeTableID.equals(other.nodeTableID))
274             return false;
275         if (nodeTableNode == null) {
276             if (other.nodeTableNode != null)
277                 return false;
278         } else if (!nodeTableNode.equals(other.nodeTableNode))
279             return false;
280         if (nodeTableType == null) {
281             if (other.nodeTableType != null)
282                 return false;
283         } else if (!nodeTableType.equals(other.nodeTableType))
284             return false;
285         return true;
286     }
287
288     @Override
289     public String toString() {
290         return this.getNodeTableIdAsString() + "@" + this.nodeTableNode;
291     }
292
293     public String getNodeTableIdAsString() {
294         return this.nodeTableType + "|"
295                 + this.nodeTableID.toString();
296     }
297
298 }