Merge "Remove "response" from yang."
[packetcable.git] / protocol_plugins.packetcable / src / main / java / org / umu / cops / stack / COPSDecisionMsg.java
1 /*\r
2  * Copyright (c) 2003 University of Murcia.  All rights reserved.\r
3  * --------------------------------------------------------------\r
4  * For more information, please see <http://www.umu.euro6ix.org/>.\r
5  */\r
6 \r
7 package org.umu.cops.stack;\r
8 \r
9 import java.io.IOException;\r
10 import java.io.OutputStream;\r
11 import java.net.Socket;\r
12 import java.util.Enumeration;\r
13 import java.util.Hashtable;\r
14 import java.util.Vector;\r
15 \r
16 /**\r
17  * COPS Decision Message\r
18  *\r
19  * @version COPSDecisionMsg.java, v 1.00 2003\r
20  *\r
21  */\r
22 public class COPSDecisionMsg extends COPSMsg {\r
23 \r
24     /* COPSHeader coming from base class */\r
25     private COPSHandle _clientHandle;\r
26     private COPSError _error;\r
27     private Hashtable _decisions;\r
28     private COPSIntegrity _integrity;\r
29     private COPSContext _decContext;\r
30     private COPSClientSI _decSI;\r
31 \r
32     ///\r
33     public COPSDecisionMsg() {\r
34         _clientHandle = null;\r
35         _error = null;\r
36         _decisions = new Hashtable(20);\r
37         _integrity = null;\r
38         _decContext = null;\r
39         _decSI = null;\r
40     }\r
41 \r
42     /** Checks the sanity of COPS message and throw an\r
43       * COPSBadDataException when data is bad.\r
44       */\r
45     public void checkSanity() throws COPSException {\r
46         if ((_hdr == null) || (_clientHandle == null) || ( (_error == null) && (_decisions.size() == 0))) {\r
47             throw new COPSException("Bad message format");\r
48         }\r
49     }\r
50 \r
51     ///\r
52     protected COPSDecisionMsg(byte[] data) throws COPSException  {\r
53         _decisions = new Hashtable(20);\r
54         _clientHandle = null;\r
55         _error = null;\r
56         _integrity = null;\r
57         _decContext = null;\r
58         _decSI = null;\r
59 \r
60         parse(data);\r
61     }\r
62 \r
63     /**\r
64      * Parses the data and fills COPSDecisionMsg with its constituents\r
65      *\r
66      * @param    data                a  byte[]\r
67      *\r
68      * @throws   COPSException\r
69      *\r
70      */\r
71     protected void parse(byte[] data) throws COPSException {\r
72         super.parseHeader(data);\r
73 \r
74         while (_dataStart < _dataLength) {\r
75             byte[] buf = new byte[data.length - _dataStart];\r
76             System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart);\r
77 \r
78             COPSObjHeader objHdr = new COPSObjHeader (buf);\r
79             switch (objHdr.getCNum()) {\r
80             case COPSObjHeader.COPS_HANDLE: {\r
81                 _clientHandle = new COPSHandle(buf);\r
82                 _dataStart += _clientHandle.getDataLength();\r
83             }\r
84             break;\r
85             case COPSObjHeader.COPS_CONTEXT: {\r
86                 //dec context\r
87                 _decContext = new COPSContext(buf);\r
88                 _dataStart += _decContext.getDataLength();\r
89             }\r
90             break;\r
91             case COPSObjHeader.COPS_ERROR: {\r
92                 _error = new COPSError(buf);\r
93                 _dataStart += _error.getDataLength();\r
94             }\r
95             break;\r
96             case COPSObjHeader.COPS_DEC: {\r
97                 COPSDecision decs = new COPSDecision(buf);\r
98                 _dataStart += decs.getDataLength();\r
99                 addDecision(decs, _decContext);\r
100             }\r
101             break;\r
102             case COPSObjHeader.COPS_MSG_INTEGRITY: {\r
103                 _integrity = new COPSIntegrity(buf);\r
104                 _dataStart += _integrity.getDataLength();\r
105             }\r
106             break;\r
107             default: {\r
108                 throw new COPSException("Bad Message format, unknown object type");\r
109             }\r
110             }\r
111         }\r
112         checkSanity();\r
113     }\r
114 \r
115     /**\r
116      * Parses the data and fills that follows the header hdr and fills COPSDecisionMsg\r
117      *\r
118      * @param    hdr                 a  COPSHeader\r
119      * @param    data                a  byte[]\r
120      *\r
121      * @throws   COPSException\r
122      *\r
123      */\r
124     protected void parse(COPSHeader hdr, byte[] data) throws COPSException {\r
125         _hdr = hdr;\r
126         parse(data);\r
127         setMsgLength();\r
128     }\r
129 \r
130     /**\r
131      * Add message header\r
132      *\r
133      * @param    hdr                 a  COPSHeader\r
134      *\r
135      * @throws   COPSException\r
136      *\r
137      */\r
138     public void add (COPSHeader hdr) throws COPSException {\r
139         if (hdr == null)\r
140             throw new COPSException ("Null Header");\r
141         if (hdr.getOpCode() != COPSHeader.COPS_OP_DEC)\r
142             throw new COPSException ("Error Header (no COPS_OP_DEC)");\r
143         _hdr = hdr;\r
144         setMsgLength();\r
145     }\r
146 \r
147     /**\r
148      * Add client handle to the message\r
149      *\r
150      * @param    handle              a  COPSHandle\r
151      *\r
152      * @throws   COPSException\r
153      *\r
154      */\r
155     public void add (COPSHandle handle) throws COPSException {\r
156         if (handle == null)\r
157             throw new COPSException ("Null Handle");\r
158         _clientHandle = handle;\r
159         setMsgLength();\r
160     }\r
161 \r
162     /**\r
163      * Add an Error object\r
164      *\r
165      * @param    error               a  COPSError\r
166      *\r
167      * @throws   COPSException\r
168      *\r
169      */\r
170     public void add (COPSError error) throws COPSException {\r
171         if (_decisions.size() != 0)\r
172             throw new COPSException ("No null decisions");\r
173         if (_error != null)\r
174             throw new COPSException ("No null error");\r
175         //Message integrity object should be the very last one\r
176         //If it is already added\r
177         if (_integrity != null)\r
178             throw new COPSException ("No null integrity");\r
179         _error = error;\r
180         setMsgLength();\r
181     }\r
182 \r
183     /**\r
184      * Add one or more local decision object for a given decision context\r
185      * the context is optional, if null all decision object are tided to\r
186      * message context\r
187      *\r
188      * @param    decision            a  COPSDecision\r
189      * @param    context             a  COPSContext\r
190      *\r
191      * @throws   COPSException\r
192      *\r
193      */\r
194     public void addDecision(COPSDecision decision, COPSContext context)  throws COPSException {\r
195         //Either error or decision can be added\r
196         //If error is aleady there assert\r
197         if (_error != null)\r
198             throw new COPSException ("No null error");\r
199 \r
200         if (decision.isLocalDecision())\r
201             throw new COPSException ("Is local decision");\r
202 \r
203         Vector v = (Vector) _decisions.get(context);\r
204         if (v == null) v = new Vector();\r
205 \r
206         if (decision.isFlagSet()) {//Commented out as advised by Felix\r
207             //if (v.size() != 0)\r
208             //{\r
209             //Only one set of decision flags is allowed\r
210             //for each context\r
211             //     throw new COPSException ("Bad Message format, only one set of decision flags is allowed.");\r
212             //}\r
213         } else {\r
214             if (v.size() == 0) {\r
215                 //The flags decision must precede any other\r
216                 //decision message, since the decision is not\r
217                 //flags throw exception\r
218                 throw new COPSException ("Bad Message format, flags decision must precede any other decision object.");\r
219             }\r
220         }\r
221         v.add(decision);\r
222         _decisions.put(context,v);\r
223 \r
224         setMsgLength();\r
225     }\r
226 \r
227     /**\r
228      * Add integrity object\r
229      *\r
230      * @param    integrity           a  COPSIntegrity\r
231      *\r
232      * @throws   COPSException\r
233      *\r
234      */\r
235     public void add (COPSIntegrity integrity)  throws COPSException {\r
236         if (integrity == null)\r
237             throw new COPSException ("Null Integrity");\r
238         if (!integrity.isMessageIntegrity())\r
239             throw new COPSException ("Error Integrity");\r
240         _integrity = integrity;\r
241         setMsgLength();\r
242     }\r
243     /**\r
244      * Add clientSI object\r
245      *\r
246      * @param    integrity           a  COPSIntegrity\r
247      *\r
248      * @throws   COPSException\r
249      *\r
250      */\r
251     public void add (COPSClientSI clientSI)  throws COPSException {\r
252         if (clientSI == null)\r
253             throw new COPSException ("Null clientSI");\r
254         /*\r
255                   if (!integrity.isMessageIntegrity())\r
256                        throw new COPSException ("Error Integrity");\r
257         */\r
258         _decSI = clientSI;\r
259         setMsgLength();\r
260     }\r
261 \r
262     /**\r
263      * Writes data to given socket\r
264      *\r
265      * @param    id                  a  Socket\r
266      *\r
267      * @throws   IOException\r
268      *\r
269      */\r
270     public void writeData(Socket id) throws IOException {\r
271         // checkSanity();\r
272         if (_hdr != null) _hdr.writeData(id);\r
273         if (_clientHandle != null) _clientHandle.writeData(id);\r
274         if (_error != null) _error.writeData(id);\r
275 \r
276         //Display decisions\r
277         //Display any local decisions\r
278         for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) {\r
279 \r
280             COPSContext context = (COPSContext) e.nextElement();\r
281             Vector v = (Vector) _decisions.get(context);\r
282             context.writeData(id);\r
283 \r
284             for (Enumeration ee = v.elements() ; ee.hasMoreElements() ;) {\r
285                 COPSDecision decision = (COPSDecision) ee.nextElement();\r
286                 decision.writeData(id);\r
287             }\r
288         }\r
289 \r
290         if (_decSI != null) _decSI.writeData(id);\r
291         if (_integrity != null) _integrity.writeData(id);\r
292     }\r
293 \r
294     /**\r
295      * Method getHeader\r
296      *\r
297      * @return   a COPSHeader\r
298      *\r
299      */\r
300     public COPSHeader getHeader() {\r
301         return _hdr;\r
302     }\r
303 \r
304     /**\r
305      * Method getClientHandle\r
306      *\r
307      * @return   a COPSHandle\r
308      *\r
309      */\r
310     public COPSHandle getClientHandle() {\r
311         return _clientHandle;\r
312     }\r
313 \r
314     /**\r
315      * Returns true if it has error object\r
316      *\r
317      * @return   a boolean\r
318      *\r
319      */\r
320     public boolean hasError() {\r
321         return (_error != null);\r
322     };\r
323 \r
324     /**\r
325      * Should check hasError() before calling\r
326      *\r
327      * @return   a COPSError\r
328      *\r
329      */\r
330     public COPSError getError() {\r
331         return _error;\r
332     };\r
333 \r
334     /**\r
335      * Returns a map of decision for which is an arry of context and vector\r
336      * of associated decision object.\r
337      *\r
338      * @return   a Hashtable\r
339      *\r
340      */\r
341     public Hashtable getDecisions() {\r
342         return _decisions;\r
343     };\r
344 \r
345     /**\r
346      * Returns true if it has integrity object\r
347      *\r
348      * @return   a boolean\r
349      *\r
350      */\r
351     public boolean hasIntegrity() {\r
352         return (_integrity != null);\r
353     };\r
354 \r
355     /**\r
356      * Should check hasIntegrity() before calling\r
357      *\r
358      * @return   a COPSIntegrity\r
359      *\r
360      */\r
361     public COPSIntegrity getIntegrity() {\r
362         return _integrity;\r
363     };\r
364 \r
365     /**\r
366      * Method setMsgLength\r
367      *\r
368      * @throws   COPSException\r
369      *\r
370      */\r
371     protected void setMsgLength()  throws COPSException {\r
372         short len = 0;\r
373         if (_clientHandle != null)\r
374             len += _clientHandle.getDataLength();\r
375         if (_error != null)\r
376             len += _error.getDataLength();\r
377 \r
378         //Display any local decisions\r
379         for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) {\r
380 \r
381             COPSContext context = (COPSContext) e.nextElement();\r
382             Vector v = (Vector) _decisions.get(context);\r
383             len += context.getDataLength();\r
384 \r
385             for (Enumeration ee = v.elements() ; ee.hasMoreElements() ;) {\r
386                 COPSDecision decision = (COPSDecision) ee.nextElement();\r
387                 len += decision.getDataLength();\r
388             }\r
389         }\r
390         if (_decSI != null) {\r
391             len += _decSI.getDataLength();\r
392         }\r
393         if (_integrity != null) {\r
394             len += _integrity.getDataLength();\r
395         }\r
396 \r
397         _hdr.setMsgLength((int) len);\r
398     }\r
399 \r
400     /**\r
401      * Write an object textual description in the output stream\r
402      *\r
403      * @param    os                  an OutputStream\r
404      *\r
405      * @throws   IOException\r
406      *\r
407      */\r
408     public void dump(OutputStream os) throws IOException {\r
409         _hdr.dump(os);\r
410 \r
411         if (_clientHandle != null)\r
412             _clientHandle.dump(os);\r
413         if (_error != null)\r
414             _error.dump(os);\r
415 \r
416         //Display any local decisions\r
417         for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) {\r
418 \r
419             COPSContext context = (COPSContext) e.nextElement();\r
420             Vector v = (Vector) _decisions.get(context);\r
421             context.dump(os);\r
422 \r
423             for (Enumeration ee = v.elements() ; ee.hasMoreElements() ;) {\r
424                 COPSDecision decision = (COPSDecision) ee.nextElement();\r
425                 decision.dump(os);\r
426             }\r
427         }\r
428         if (_decSI != null) {\r
429             _decSI.dump(os);\r
430         }\r
431         if (_integrity != null) {\r
432             _integrity.dump(os);\r
433         }\r
434     }\r
435 }\r
436 \r
437 \r
438 \r