2 * Copyright (c) 2003 University of Murcia. All rights reserved.
3 * --------------------------------------------------------------
4 * For more information, please see <http://www.umu.euro6ix.org/>.
7 package org.umu.cops.stack;
9 import org.umu.cops.stack.COPSDecision.DecisionFlag;
10 import org.umu.cops.stack.COPSObjHeader.CNum;
12 import java.io.IOException;
13 import java.io.OutputStream;
14 import java.net.Socket;
15 import java.util.Enumeration;
16 import java.util.Hashtable;
17 import java.util.Vector;
20 * COPS Decision Message
22 * @version COPSDecisionMsg.java, v 1.00 2003
25 public class COPSDecisionMsg extends COPSMsg {
27 /* COPSHeader coming from base class */
28 private COPSHandle _clientHandle;
29 private COPSError _error;
30 private Hashtable _decisions;
31 private COPSIntegrity _integrity;
32 private COPSContext _decContext;
33 private COPSClientSI _decSI;
36 public COPSDecisionMsg() {
39 _decisions = new Hashtable(20);
45 /** Checks the sanity of COPS message and throw an
46 * COPSBadDataException when data is bad.
48 public void checkSanity() throws COPSException {
49 if ((_hdr == null) || (_clientHandle == null) || ( (_error == null) && (_decisions.size() == 0))) {
50 throw new COPSException("Bad message format");
55 protected COPSDecisionMsg(byte[] data) throws COPSException {
56 _decisions = new Hashtable(20);
67 * Parses the data and fills COPSDecisionMsg with its constituents
69 * @param data a byte[]
71 * @throws COPSException
74 protected void parse(byte[] data) throws COPSException {
75 super.parseHeader(data);
77 while (_dataStart < _dataLength) {
78 byte[] buf = new byte[data.length - _dataStart];
79 System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart);
81 final COPSObjHeaderData objHdrData = COPSObjectParser.parseObjHeader(buf);
82 switch (objHdrData.header.getCNum()) {
84 _clientHandle = COPSHandle.parse(objHdrData, buf);
85 _dataStart += _clientHandle.getDataLength();
89 _decContext = COPSContext.parse(objHdrData, buf);
90 _dataStart += _decContext.getDataLength();
93 _error = COPSError.parse(objHdrData, buf);
94 _dataStart += _error.getDataLength();
97 COPSDecision decs = COPSDecision.parse(objHdrData, buf);
98 _dataStart += decs.getDataLength();
99 addDecision(decs, _decContext);
102 _integrity = COPSIntegrity.parse(objHdrData, buf);
103 _dataStart += _integrity.getDataLength();
106 throw new COPSException("Bad Message format, unknown object type");
114 * Parses the data and fills that follows the header hdr and fills COPSDecisionMsg
116 * @param hdr a COPSHeader
117 * @param data a byte[]
119 * @throws COPSException
122 protected void parse(COPSHeader hdr, byte[] data) throws COPSException {
131 * @param hdr a COPSHeader
133 * @throws COPSException
136 public void add (COPSHeader hdr) throws COPSException {
138 throw new COPSException ("Null Header");
139 if (hdr.getOpCode() != COPSHeader.COPS_OP_DEC)
140 throw new COPSException ("Error Header (no COPS_OP_DEC)");
146 * Add client handle to the message
148 * @param handle a COPSHandle
150 * @throws COPSException
153 public void add (COPSHandle handle) throws COPSException {
155 throw new COPSException ("Null Handle");
156 _clientHandle = handle;
161 * Add an Error object
163 * @param error a COPSError
165 * @throws COPSException
168 public void add (COPSError error) throws COPSException {
169 if (_decisions.size() != 0)
170 throw new COPSException ("No null decisions");
172 throw new COPSException ("No null error");
173 //Message integrity object should be the very last one
174 //If it is already added
175 if (_integrity != null)
176 throw new COPSException ("No null integrity");
182 * Add one or more local decision object for a given decision context
183 * the context is optional, if null all decision object are tided to
186 * @param decision a COPSDecision
187 * @param context a COPSContext
189 * @throws COPSException
192 public void addDecision(COPSDecision decision, COPSContext context) throws COPSException {
193 //Either error or decision can be added
194 //If error is aleady there assert
196 throw new COPSException ("No null error");
198 if (decision.getHeader().getCNum().equals(CNum.LPDP_DEC))
199 throw new COPSException ("Is local decision");
201 Vector v = (Vector) _decisions.get(context);
202 if (v == null) v = new Vector();
204 if (!decision.getFlag().equals(DecisionFlag.NA)) {//Commented out as advised by Felix
207 //Only one set of decision flags is allowed
209 // throw new COPSException ("Bad Message format, only one set of decision flags is allowed.");
213 //The flags decision must precede any other
214 //decision message, since the decision is not
215 //flags throw exception
216 throw new COPSException ("Bad Message format, flags decision must precede any other decision object.");
220 _decisions.put(context,v);
226 * Add integrity object
228 * @param integrity a COPSIntegrity
230 * @throws COPSException
233 public void add (COPSIntegrity integrity) throws COPSException {
234 if (integrity == null)
235 throw new COPSException ("Null Integrity");
236 _integrity = integrity;
240 * Add clientSI object
242 * @param clientSI a COPSClientSI
244 * @throws COPSException
247 public void add (COPSClientSI clientSI) throws COPSException {
248 if (clientSI == null)
249 throw new COPSException ("Null clientSI");
251 if (!integrity.isMessageIntegrity())
252 throw new COPSException ("Error Integrity");
259 * Writes data to given socket
263 * @throws IOException
266 public void writeData(Socket id) throws IOException {
268 if (_hdr != null) _hdr.writeData(id);
269 if (_clientHandle != null) _clientHandle.writeData(id);
270 if (_error != null) _error.writeData(id);
273 //Display any local decisions
274 for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) {
276 COPSContext context = (COPSContext) e.nextElement();
277 Vector v = (Vector) _decisions.get(context);
278 context.writeData(id);
280 for (Enumeration ee = v.elements() ; ee.hasMoreElements() ;) {
281 COPSDecision decision = (COPSDecision) ee.nextElement();
282 decision.writeData(id);
286 if (_decSI != null) _decSI.writeData(id);
287 if (_integrity != null) _integrity.writeData(id);
293 * @return a COPSHeader
296 public COPSHeader getHeader() {
301 * Method getClientHandle
303 * @return a COPSHandle
306 public COPSHandle getClientHandle() {
307 return _clientHandle;
311 * Returns true if it has error object
316 public boolean hasError() {
317 return (_error != null);
321 * Should check hasError() before calling
323 * @return a COPSError
326 public COPSError getError() {
331 * Returns a map of decision for which is an arry of context and vector
332 * of associated decision object.
334 * @return a Hashtable
337 public Hashtable getDecisions() {
342 * Returns true if it has integrity object
347 public boolean hasIntegrity() {
348 return (_integrity != null);
352 * Should check hasIntegrity() before calling
354 * @return a COPSIntegrity
357 public COPSIntegrity getIntegrity() {
362 * Method setMsgLength
364 * @throws COPSException
367 protected void setMsgLength() throws COPSException {
369 if (_clientHandle != null)
370 len += _clientHandle.getDataLength();
372 len += _error.getDataLength();
374 //Display any local decisions
375 for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) {
377 COPSContext context = (COPSContext) e.nextElement();
378 Vector v = (Vector) _decisions.get(context);
379 len += context.getDataLength();
381 for (Enumeration ee = v.elements() ; ee.hasMoreElements() ;) {
382 COPSDecision decision = (COPSDecision) ee.nextElement();
383 len += decision.getDataLength();
386 if (_decSI != null) {
387 len += _decSI.getDataLength();
389 if (_integrity != null) {
390 len += _integrity.getDataLength();
393 _hdr.setMsgLength((int) len);
397 * Write an object textual description in the output stream
399 * @param os an OutputStream
401 * @throws IOException
404 public void dump(OutputStream os) throws IOException {
407 if (_clientHandle != null)
408 _clientHandle.dump(os);
412 //Display any local decisions
413 for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) {
415 COPSContext context = (COPSContext) e.nextElement();
416 Vector v = (Vector) _decisions.get(context);
419 for (Enumeration ee = v.elements() ; ee.hasMoreElements() ;) {
420 COPSDecision decision = (COPSDecision) ee.nextElement();
424 if (_decSI != null) {
427 if (_integrity != null) {