Fix checkstyle warnings in netconf-cli
[controller.git] / third-party / openflowj / src / main / java / org / openflow / protocol / factory / BasicFactory.java
1 package org.openflow.protocol.factory;
2
3 import java.nio.ByteBuffer;
4 import java.util.ArrayList;
5 import java.util.List;
6
7 import org.openflow.protocol.OFMessage;
8 import org.openflow.protocol.OFType;
9 import org.openflow.protocol.action.OFAction;
10 import org.openflow.protocol.action.OFActionType;
11 import org.openflow.protocol.queue.OFQueueProperty;
12 import org.openflow.protocol.queue.OFQueuePropertyType;
13 import org.openflow.protocol.statistics.OFStatistics;
14 import org.openflow.protocol.statistics.OFStatisticsType;
15 import org.openflow.protocol.statistics.OFVendorStatistics;
16
17
18 /**
19  * A basic OpenFlow factory that supports naive creation of both Messages and
20  * Actions.
21  *
22  * @author David Erickson (daviderickson@cs.stanford.edu)
23  * @author Rob Sherwood (rob.sherwood@stanford.edu)
24  *
25  */
26 public class BasicFactory implements OFMessageFactory, OFActionFactory,
27         OFQueuePropertyFactory, OFStatisticsFactory {
28     @Override
29     public OFMessage getMessage(OFType t) {
30         return t.newInstance();
31     }
32
33     @Override
34     public List<OFMessage> parseMessages(ByteBuffer data) {
35         return parseMessages(data, 0);
36     }
37
38     @Override
39     public List<OFMessage> parseMessages(ByteBuffer data, int limit) {
40         List<OFMessage> results = new ArrayList<OFMessage>();
41         OFMessage demux = new OFMessage();
42         OFMessage ofm;
43
44         while (limit == 0 || results.size() <= limit) {
45             if (data.remaining() < OFMessage.MINIMUM_LENGTH)
46                 return results;
47
48             data.mark();
49             demux.readFrom(data);
50             data.reset();
51
52             if (demux.getLengthU() > data.remaining())
53                 return results;
54
55             ofm = getMessage(demux.getType());
56             if (ofm instanceof OFActionFactoryAware) {
57                 ((OFActionFactoryAware)ofm).setActionFactory(this);
58             }
59             if (ofm instanceof OFMessageFactoryAware) {
60                 ((OFMessageFactoryAware)ofm).setMessageFactory(this);
61             }
62             if (ofm instanceof OFQueuePropertyFactoryAware) {
63                 ((OFQueuePropertyFactoryAware)ofm).setQueuePropertyFactory(this);
64             }
65             if (ofm instanceof OFStatisticsFactoryAware) {
66                 ((OFStatisticsFactoryAware)ofm).setStatisticsFactory(this);
67             }
68             ofm.readFrom(data);
69             if (OFMessage.class.equals(ofm.getClass())) {
70                 // advance the position for un-implemented messages
71                 data.position(data.position()+(ofm.getLengthU() -
72                         OFMessage.MINIMUM_LENGTH));
73             }
74             results.add(ofm);
75         }
76
77         return results;
78     }
79
80     @Override
81     public OFAction getAction(OFActionType t) {
82         return t.newInstance();
83     }
84
85     @Override
86     public List<OFAction> parseActions(ByteBuffer data, int length) {
87         return parseActions(data, length, 0);
88     }
89
90     @Override
91     public List<OFAction> parseActions(ByteBuffer data, int length, int limit) {
92         List<OFAction> results = new ArrayList<OFAction>();
93         OFAction demux = new OFAction();
94         OFAction ofa;
95         int end = data.position() + length;
96
97         while (limit == 0 || results.size() <= limit) {
98             if (data.remaining() < OFAction.MINIMUM_LENGTH ||
99                     (data.position() + OFAction.MINIMUM_LENGTH) > end)
100                 return results;
101
102             data.mark();
103             demux.readFrom(data);
104             data.reset();
105
106             if (demux.getLengthU() > data.remaining() ||
107                     (data.position() + demux.getLengthU()) > end)
108                 return results;
109
110             ofa = getAction(demux.getType());
111             ofa.readFrom(data);
112             if (OFAction.class.equals(ofa.getClass())) {
113                 // advance the position for un-implemented messages
114                 data.position(data.position()+(ofa.getLengthU() -
115                         OFAction.MINIMUM_LENGTH));
116             }
117             results.add(ofa);
118         }
119
120         return results;
121     }
122
123     @Override
124     public OFActionFactory getActionFactory() {
125         return this;
126     }
127
128     @Override
129     public OFStatistics getStatistics(OFType t, OFStatisticsType st) {
130         return st.newInstance(t);
131     }
132
133     @Override
134     public List<OFStatistics> parseStatistics(OFType t, OFStatisticsType st,
135             ByteBuffer data, int length) {
136         return parseStatistics(t, st, data, length, 0);
137     }
138
139     /**
140      * @param t
141      *            OFMessage type: should be one of stats_request or stats_reply
142      * @param st
143      *            statistics type of this message, e.g., DESC, TABLE
144      * @param data
145      *            buffer to read from
146      * @param length
147      *            length of statistics
148      * @param limit
149      *            number of statistics to grab; 0 == all
150      * 
151      * @return list of statistics
152      */
153
154     @Override
155     public List<OFStatistics> parseStatistics(OFType t, OFStatisticsType st,
156             ByteBuffer data, int length, int limit) {
157         List<OFStatistics> results = new ArrayList<OFStatistics>();
158         OFStatistics statistics = getStatistics(t, st);
159
160         int start = data.position();
161         int count = 0;
162
163         while (limit == 0 || results.size() <= limit) {
164             // TODO Create a separate MUX/DEMUX path for vendor stats
165             if (statistics instanceof OFVendorStatistics)
166                 ((OFVendorStatistics)statistics).setLength(length);
167
168             /**
169              * can't use data.remaining() here, b/c there could be other data
170              * buffered past this message
171              */
172             if ((length - count) >= statistics.getLength()) {
173                 if (statistics instanceof OFActionFactoryAware)
174                     ((OFActionFactoryAware)statistics).setActionFactory(this);
175                 statistics.readFrom(data);
176                 results.add(statistics);
177                 count += statistics.getLength();
178                 statistics = getStatistics(t, st);
179             } else {
180                 if (count < length) {
181                     /**
182                      * Nasty case: partial/incomplete statistic found even
183                      * though we have a full message. Found when NOX sent
184                      * agg_stats request with wrong agg statistics length (52
185                      * instead of 56)
186                      * 
187                      * just throw the rest away, or we will break framing
188                      */
189                     data.position(start + length);
190                 }
191                 return results;
192             }
193         }
194         return results; // empty; no statistics at all
195     }
196
197     @Override
198     public OFQueueProperty getQueueProperty(OFQueuePropertyType t) {
199         return t.newInstance();
200     }
201
202     @Override
203     public List<OFQueueProperty> parseQueueProperties(ByteBuffer data,
204             int length) {
205         return parseQueueProperties(data, length, 0);
206     }
207
208     @Override
209     public List<OFQueueProperty> parseQueueProperties(ByteBuffer data,
210             int length, int limit) {
211         List<OFQueueProperty> results = new ArrayList<OFQueueProperty>();
212         OFQueueProperty demux = new OFQueueProperty();
213         OFQueueProperty ofqp;
214         int end = data.position() + length;
215
216         while (limit == 0 || results.size() <= limit) {
217             if (data.remaining() < OFQueueProperty.MINIMUM_LENGTH ||
218                     (data.position() + OFQueueProperty.MINIMUM_LENGTH) > end)
219                 return results;
220
221             data.mark();
222             demux.readFrom(data);
223             data.reset();
224
225             if (demux.getLengthU() > data.remaining() ||
226                     (data.position() + demux.getLengthU()) > end)
227                 return results;
228
229             ofqp = getQueueProperty(demux.getType());
230             ofqp.readFrom(data);
231             if (OFQueueProperty.class.equals(ofqp.getClass())) {
232                 // advance the position for un-implemented messages
233                 data.position(data.position()+(ofqp.getLengthU() -
234                         OFQueueProperty.MINIMUM_LENGTH));
235             }
236             results.add(ofqp);
237         }
238
239         return results;
240     }
241 }