d5d0fdc2f93b40e63b03079d7f7d17e293eb2a7c
[openflowjava.git] / third-party / openflow-codec / src / main / java / org / openflow / codec / protocol / statistics / OFPMultipartTypes.java
1 package org.openflow.codec.protocol.statistics;
2
3 import java.lang.reflect.Constructor;
4 import java.util.HashMap;
5 import java.util.Map;
6
7 import org.openflow.codec.protocol.Instantiable;
8 import org.openflow.codec.protocol.OFPType;
9 import org.openflow.codec.util.U16;
10
11 /**
12  * Represents an ofp_multipart_types enum
13  * 
14  * @author AnilGujele
15  * 
16  */
17 public enum OFPMultipartTypes {
18     DESC(0, OFPDescriptionStatistics.class, OFPDescriptionStatistics.class, new Instantiable<OFPStatistics>() {
19         @Override
20         public OFPStatistics instantiate() {
21             return new OFPDescriptionStatistics();
22         }
23     }, new Instantiable<OFPStatistics>() {
24         @Override
25         public OFPStatistics instantiate() {
26             return new OFPDescriptionStatistics();
27         }
28     }), FLOW(1, OFPFlowStatisticsRequest.class, OFPFlowStatisticsReply.class, new Instantiable<OFPStatistics>() {
29         @Override
30         public OFPStatistics instantiate() {
31             return new OFPFlowStatisticsRequest();
32         }
33     }, new Instantiable<OFPStatistics>() {
34         @Override
35         public OFPStatistics instantiate() {
36             return new OFPFlowStatisticsReply();
37         }
38     }), AGGREGATE(2, OFPAggregateStatisticsRequest.class, OFPAggregateStatisticsReply.class,
39             new Instantiable<OFPStatistics>() {
40                 @Override
41                 public OFPStatistics instantiate() {
42                     return new OFPAggregateStatisticsRequest();
43                 }
44             }, new Instantiable<OFPStatistics>() {
45                 @Override
46                 public OFPStatistics instantiate() {
47                     return new OFPAggregateStatisticsReply();
48                 }
49             }), TABLE(3, OFPTableStatistics.class, OFPTableStatistics.class, new Instantiable<OFPStatistics>() {
50         @Override
51         public OFPStatistics instantiate() {
52             return new OFPTableStatistics();
53         }
54     }, new Instantiable<OFPStatistics>() {
55         @Override
56         public OFPStatistics instantiate() {
57             return new OFPTableStatistics();
58         }
59     }), PORT_STATS(4, OFPPortStatisticsRequest.class, OFPPortStatisticsReply.class, new Instantiable<OFPStatistics>() {
60         @Override
61         public OFPStatistics instantiate() {
62             return new OFPPortStatisticsRequest();
63         }
64     }, new Instantiable<OFPStatistics>() {
65         @Override
66         public OFPStatistics instantiate() {
67             return new OFPPortStatisticsReply();
68         }
69     }), QUEUE(5, OFPQueueStatisticsRequest.class, OFPQueueStatisticsReply.class, new Instantiable<OFPStatistics>() {
70         @Override
71         public OFPStatistics instantiate() {
72             return new OFPQueueStatisticsRequest();
73         }
74     }, new Instantiable<OFPStatistics>() {
75         @Override
76         public OFPStatistics instantiate() {
77             return new OFPQueueStatisticsReply();
78         }
79     }), GROUP_DESC(7, OFPGroupDescription.class, OFPGroupDescription.class, new Instantiable<OFPStatistics>() {
80         @Override
81         public OFPStatistics instantiate() {
82             return new OFPGroupDescription();
83         }
84     }, new Instantiable<OFPStatistics>() {
85         @Override
86         public OFPStatistics instantiate() {
87             return new OFPGroupDescription();
88         }
89     }), GROUP_FEATURES(8, OFPGroupFeatures.class, OFPGroupFeatures.class, new Instantiable<OFPStatistics>() {
90         @Override
91         public OFPStatistics instantiate() {
92             return new OFPGroupFeatures();
93         }
94     }, new Instantiable<OFPStatistics>() {
95         @Override
96         public OFPStatistics instantiate() {
97             return new OFPGroupFeatures();
98         }
99     }), TABLE_FEATURES(12, OFPTableFeatures.class, OFPTableFeatures.class, new Instantiable<OFPStatistics>() {
100         @Override
101         public OFPStatistics instantiate() {
102             return new OFPTableFeatures();
103         }
104     }, new Instantiable<OFPStatistics>() {
105         @Override
106         public OFPStatistics instantiate() {
107             return new OFPTableFeatures();
108         }
109     }), PORT_DESC(13, OFPPortDescriptionStatistics.class, OFPPortDescriptionStatistics.class,
110             new Instantiable<OFPStatistics>() {
111                 @Override
112                 public OFPStatistics instantiate() {
113                     return new OFPPortDescriptionStatistics();
114                 }
115             }, new Instantiable<OFPStatistics>() {
116                 @Override
117                 public OFPStatistics instantiate() {
118                     return new OFPPortDescriptionStatistics();
119                 }
120             }),
121
122     EXPERIMENTER(0xffff, OFPExperimenterMultipartHeader.class, OFPExperimenterMultipartHeader.class,
123             new Instantiable<OFPStatistics>() {
124                 @Override
125                 public OFPStatistics instantiate() {
126                     return new OFPExperimenterMultipartHeader();
127                 }
128             }, new Instantiable<OFPStatistics>() {
129                 @Override
130                 public OFPStatistics instantiate() {
131                     return new OFPExperimenterMultipartHeader();
132                 }
133             });
134
135     private static Map<Integer, OFPMultipartTypes> requestMapping;
136     private static Map<Integer, OFPMultipartTypes> replyMapping;
137
138     private Class<? extends OFPStatistics> requestClass;
139     private Constructor<? extends OFPStatistics> requestConstructor;
140     private Instantiable<OFPStatistics> requestInstantiable;
141     private Class<? extends OFPStatistics> replyClass;
142     private Constructor<? extends OFPStatistics> replyConstructor;
143     private Instantiable<OFPStatistics> replyInstantiable;
144     private int type;
145
146     /**
147      * Store some information about the OpenFlow Statistic type, including wire
148      * protocol type number, and derived class
149      * 
150      * @param type
151      *            Wire protocol number associated with this OFPMultipartType
152      * @param requestClass
153      *            The Multipart Java class to return when the containing OFPType
154      *            is MULTIPART_REQUEST
155      * @param replyClass
156      *            The Multipart Java class to return when the containing OFPType
157      *            is MULTIPART_REPLY
158      */
159     OFPMultipartTypes(int type, Class<? extends OFPStatistics> requestClass, Class<? extends OFPStatistics> replyClass,
160             Instantiable<OFPStatistics> requestInstantiable, Instantiable<OFPStatistics> replyInstantiable) {
161         this.type = type;
162         this.requestClass = requestClass;
163         try {
164             this.requestConstructor = requestClass.getConstructor(new Class[] {});
165         } catch (Exception e) {
166             throw new RuntimeException("Failure getting constructor for class: " + requestClass, e);
167         }
168
169         this.replyClass = replyClass;
170         try {
171             this.replyConstructor = replyClass.getConstructor(new Class[] {});
172         } catch (Exception e) {
173             throw new RuntimeException("Failure getting constructor for class: " + replyClass, e);
174         }
175         this.requestInstantiable = requestInstantiable;
176         this.replyInstantiable = replyInstantiable;
177         OFPMultipartTypes.addMapping(this.type, OFPType.MULTIPART_REQUEST, this);
178         OFPMultipartTypes.addMapping(this.type, OFPType.MULTIPART_REPLY, this);
179     }
180
181     /**
182      * Adds a mapping from type value to OFStatisticsType enum
183      * 
184      * @param i
185      *            OpenFlow wire protocol type
186      * @param t
187      *            type of containing OFPMessage, only accepts MULTIPART_REQUEST
188      *            or MULTIPART_REPLY
189      * @param st
190      *            type
191      */
192     public static void addMapping(int i, OFPType t, OFPMultipartTypes st) {
193
194         if (t == OFPType.MULTIPART_REQUEST) {
195             if (requestMapping == null)
196                 requestMapping = new HashMap<Integer, OFPMultipartTypes>();
197             OFPMultipartTypes.requestMapping.put(i, st);
198         } else if (t == OFPType.MULTIPART_REPLY) {
199             if (replyMapping == null)
200                 replyMapping = new HashMap<Integer, OFPMultipartTypes>();
201             OFPMultipartTypes.replyMapping.put(i, st);
202         } else {
203             throw new RuntimeException(t.toString() + " is an invalid OFPType");
204         }
205     }
206
207     /**
208      * Remove a mapping from type value to OFPMultipartType enum
209      * 
210      * @param i
211      *            OpenFlow wire protocol type
212      * @param t
213      *            type of containing OFPMessage, only accepts MULTIPART_REQUEST
214      *            or MULTIPART_REPLY
215      */
216     public static void removeMapping(int i, OFPType t) {
217         if (t == OFPType.MULTIPART_REQUEST) {
218             requestMapping.remove(i);
219         } else if (t == OFPType.MULTIPART_REPLY) {
220             replyMapping.remove(i);
221         } else {
222             throw new RuntimeException(t.toString() + " is an invalid OFPType");
223         }
224     }
225
226     /**
227      * Given a wire protocol OpenFlow type number, return the OFPMultipartType
228      * associated with it
229      * 
230      * @param i
231      *            wire protocol number
232      * @param t
233      *            type of containing OFPMessage, only accepts MULTIPART_REQUEST
234      *            or MULTIPART_REPLY
235      * @return OFPMultipartType enum type
236      */
237     public static OFPMultipartTypes valueOf(short i, OFPType t) {
238         if (t == OFPType.MULTIPART_REQUEST) {
239             return requestMapping.get(U16.f(i));
240         } else if (t == OFPType.MULTIPART_REPLY) {
241             return replyMapping.get(U16.f(i));
242         } else {
243             throw new RuntimeException(t.toString() + " is an invalid OFPType");
244         }
245     }
246
247     /**
248      * @return Returns the wire protocol value corresponding to this
249      *         OFPMultipartType
250      */
251     public short getTypeValue() {
252         return U16.t(this.type);
253     }
254
255     /**
256      * @return Returns the wire protocol unsigned value corresponding to this
257      *         OFPMultipartType
258      */
259     public int getTypeValueU() {
260         return this.type;
261     }
262
263     /**
264      * @param t
265      *            type of containing OFPMessage, only accepts MULTIPART_REQUEST
266      *            or MULTIPART_REPLY
267      * @return return the OFPMessage subclass corresponding to this
268      *         OFPMultipartType
269      */
270     public Class<? extends OFPStatistics> toClass(OFPType t) {
271         if (t == OFPType.MULTIPART_REQUEST) {
272             return requestClass;
273         } else if (t == OFPType.MULTIPART_REPLY) {
274             return replyClass;
275         } else {
276             throw new RuntimeException(t.toString() + " is an invalid OFPType");
277         }
278     }
279
280     /**
281      * Returns the no-argument Constructor of the implementation class for this
282      * OFPMultipartType, either request or reply based on the supplied OFPType
283      * 
284      * @param t
285      * @return
286      */
287     public Constructor<? extends OFPStatistics> getConstructor(OFPType t) {
288         if (t == OFPType.MULTIPART_REQUEST) {
289             return requestConstructor;
290         } else if (t == OFPType.MULTIPART_REPLY) {
291             return replyConstructor;
292         } else {
293             throw new RuntimeException(t.toString() + " is an invalid OFPType");
294         }
295     }
296
297     /**
298      * @return the requestInstantiable
299      */
300     public Instantiable<OFPStatistics> getRequestInstantiable() {
301         return requestInstantiable;
302     }
303
304     /**
305      * @param requestInstantiable
306      *            the requestInstantiable to set
307      */
308     public void setRequestInstantiable(Instantiable<OFPStatistics> requestInstantiable) {
309         this.requestInstantiable = requestInstantiable;
310     }
311
312     /**
313      * @return the replyInstantiable
314      */
315     public Instantiable<OFPStatistics> getReplyInstantiable() {
316         return replyInstantiable;
317     }
318
319     /**
320      * @param replyInstantiable
321      *            the replyInstantiable to set
322      */
323     public void setReplyInstantiable(Instantiable<OFPStatistics> replyInstantiable) {
324         this.replyInstantiable = replyInstantiable;
325     }
326
327     /**
328      * Returns a new instance of the implementation class for this
329      * OFPMultipartType, either request or reply based on the supplied OFPType
330      * 
331      * @param t
332      * @return
333      */
334     public OFPStatistics newInstance(OFPType t) {
335         if (t == OFPType.MULTIPART_REQUEST) {
336             return requestInstantiable.instantiate();
337         } else if (t == OFPType.MULTIPART_REPLY) {
338             return replyInstantiable.instantiate();
339         } else {
340             throw new RuntimeException(t.toString() + " is an invalid OFPType");
341         }
342     }
343 }