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
7 package org.umu.cops.stack;
\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
17 * COPS Decision Message
\r
19 * @version COPSDecisionMsg.java, v 1.00 2003
\r
22 public class COPSDecisionMsg extends COPSMsg {
\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
33 public COPSDecisionMsg() {
\r
34 _clientHandle = null;
\r
36 _decisions = new Hashtable(20);
\r
42 /** Checks the sanity of COPS message and throw an
\r
43 * COPSBadDataException when data is bad.
\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
52 protected COPSDecisionMsg(byte[] data) throws COPSException {
\r
53 _decisions = new Hashtable(20);
\r
54 _clientHandle = null;
\r
64 * Parses the data and fills COPSDecisionMsg with its constituents
\r
66 * @param data a byte[]
\r
68 * @throws COPSException
\r
71 protected void parse(byte[] data) throws COPSException {
\r
72 super.parseHeader(data);
\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
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
85 case COPSObjHeader.COPS_CONTEXT: {
\r
87 _decContext = new COPSContext(buf);
\r
88 _dataStart += _decContext.getDataLength();
\r
91 case COPSObjHeader.COPS_ERROR: {
\r
92 _error = new COPSError(buf);
\r
93 _dataStart += _error.getDataLength();
\r
96 case COPSObjHeader.COPS_DEC: {
\r
97 COPSDecision decs = new COPSDecision(buf);
\r
98 _dataStart += decs.getDataLength();
\r
99 addDecision(decs, _decContext);
\r
102 case COPSObjHeader.COPS_MSG_INTEGRITY: {
\r
103 _integrity = new COPSIntegrity(buf);
\r
104 _dataStart += _integrity.getDataLength();
\r
108 throw new COPSException("Bad Message format, unknown object type");
\r
116 * Parses the data and fills that follows the header hdr and fills COPSDecisionMsg
\r
118 * @param hdr a COPSHeader
\r
119 * @param data a byte[]
\r
121 * @throws COPSException
\r
124 protected void parse(COPSHeader hdr, byte[] data) throws COPSException {
\r
131 * Add message header
\r
133 * @param hdr a COPSHeader
\r
135 * @throws COPSException
\r
138 public void add (COPSHeader hdr) throws COPSException {
\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
148 * Add client handle to the message
\r
150 * @param handle a COPSHandle
\r
152 * @throws COPSException
\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
163 * Add an Error object
\r
165 * @param error a COPSError
\r
167 * @throws COPSException
\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
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
188 * @param decision a COPSDecision
\r
189 * @param context a COPSContext
\r
191 * @throws COPSException
\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
200 if (decision.isLocalDecision())
\r
201 throw new COPSException ("Is local decision");
\r
203 Vector v = (Vector) _decisions.get(context);
\r
204 if (v == null) v = new Vector();
\r
206 if (decision.isFlagSet()) {//Commented out as advised by Felix
\r
207 //if (v.size() != 0)
\r
209 //Only one set of decision flags is allowed
\r
211 // throw new COPSException ("Bad Message format, only one set of decision flags is allowed.");
\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
222 _decisions.put(context,v);
\r
228 * Add integrity object
\r
230 * @param integrity a COPSIntegrity
\r
232 * @throws COPSException
\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
244 * Add clientSI object
\r
246 * @param integrity a COPSIntegrity
\r
248 * @throws COPSException
\r
251 public void add (COPSClientSI clientSI) throws COPSException {
\r
252 if (clientSI == null)
\r
253 throw new COPSException ("Null clientSI");
\r
255 if (!integrity.isMessageIntegrity())
\r
256 throw new COPSException ("Error Integrity");
\r
263 * Writes data to given socket
\r
265 * @param id a Socket
\r
267 * @throws IOException
\r
270 public void writeData(Socket id) throws IOException {
\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
276 //Display decisions
\r
277 //Display any local decisions
\r
278 for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) {
\r
280 COPSContext context = (COPSContext) e.nextElement();
\r
281 Vector v = (Vector) _decisions.get(context);
\r
282 context.writeData(id);
\r
284 for (Enumeration ee = v.elements() ; ee.hasMoreElements() ;) {
\r
285 COPSDecision decision = (COPSDecision) ee.nextElement();
\r
286 decision.writeData(id);
\r
290 if (_decSI != null) _decSI.writeData(id);
\r
291 if (_integrity != null) _integrity.writeData(id);
\r
297 * @return a COPSHeader
\r
300 public COPSHeader getHeader() {
\r
305 * Method getClientHandle
\r
307 * @return a COPSHandle
\r
310 public COPSHandle getClientHandle() {
\r
311 return _clientHandle;
\r
315 * Returns true if it has error object
\r
317 * @return a boolean
\r
320 public boolean hasError() {
\r
321 return (_error != null);
\r
325 * Should check hasError() before calling
\r
327 * @return a COPSError
\r
330 public COPSError getError() {
\r
335 * Returns a map of decision for which is an arry of context and vector
\r
336 * of associated decision object.
\r
338 * @return a Hashtable
\r
341 public Hashtable getDecisions() {
\r
346 * Returns true if it has integrity object
\r
348 * @return a boolean
\r
351 public boolean hasIntegrity() {
\r
352 return (_integrity != null);
\r
356 * Should check hasIntegrity() before calling
\r
358 * @return a COPSIntegrity
\r
361 public COPSIntegrity getIntegrity() {
\r
366 * Method setMsgLength
\r
368 * @throws COPSException
\r
371 protected void setMsgLength() throws COPSException {
\r
373 if (_clientHandle != null)
\r
374 len += _clientHandle.getDataLength();
\r
375 if (_error != null)
\r
376 len += _error.getDataLength();
\r
378 //Display any local decisions
\r
379 for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) {
\r
381 COPSContext context = (COPSContext) e.nextElement();
\r
382 Vector v = (Vector) _decisions.get(context);
\r
383 len += context.getDataLength();
\r
385 for (Enumeration ee = v.elements() ; ee.hasMoreElements() ;) {
\r
386 COPSDecision decision = (COPSDecision) ee.nextElement();
\r
387 len += decision.getDataLength();
\r
390 if (_decSI != null) {
\r
391 len += _decSI.getDataLength();
\r
393 if (_integrity != null) {
\r
394 len += _integrity.getDataLength();
\r
397 _hdr.setMsgLength((int) len);
\r
401 * Write an object textual description in the output stream
\r
403 * @param os an OutputStream
\r
405 * @throws IOException
\r
408 public void dump(OutputStream os) throws IOException {
\r
411 if (_clientHandle != null)
\r
412 _clientHandle.dump(os);
\r
413 if (_error != null)
\r
416 //Display any local decisions
\r
417 for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) {
\r
419 COPSContext context = (COPSContext) e.nextElement();
\r
420 Vector v = (Vector) _decisions.get(context);
\r
423 for (Enumeration ee = v.elements() ; ee.hasMoreElements() ;) {
\r
424 COPSDecision decision = (COPSDecision) ee.nextElement();
\r
428 if (_decSI != null) {
\r
431 if (_integrity != null) {
\r
432 _integrity.dump(os);
\r