xref: /illumos-gate/usr/src/lib/libslp/javalib/com/sun/slp/SLPServerHeaderV2.java (revision a5f69788de7ac07553de47f7fec8c05a9a94c105)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * ident	"%Z%%M%	%I%	%E% SMI"
24  *
25  * Copyright 2001-2002 Sun Microsystems, Inc.  All rights reserved.
26  * Use is subject to license terms.
27  *
28  */
29 
30 //  SCCS Status:      %W%	%G%
31 //  SLPServerHeaderV2.java: SLPv2 Header Class for Server Side
32 //  Author:           James Kempf
33 //  Created On:       Wed Sep 16 08:44:31 1998
34 //  Last Modified By: James Kempf
35 //  Last Modified On: Mon Jan  4 15:26:33 1999
36 //  Update Count:     30
37 //
38 
39 package com.sun.slp;
40 
41 import java.util.*;
42 
43 import java.net.*;
44 import java.io.*;
45 import java.security.*;
46 
47 /**
48  * The SLPServerHeaderV2 class serves as the header class for all server side
49  * SLPv2 messages.
50  *
51  * @version %R%.%L% %D%
52  * @author James Kempf
53  */
54 
55 class SLPServerHeaderV2 extends SLPHeaderV2  implements Cloneable {
56 
57     // Function code for message reply.
58 
59     int replyFunctionCode = SrvLocHeader.SrvAck;
60 
61     // For SrvLocHeader.newInstance().
62 
63     SLPServerHeaderV2() {
64 	super();
65 
66     }
67 
68     // Construct a header for output. Used by the client side code to
69     //  construct an initial request and the server side code to construct
70     //  a reply.
71 
72     SLPServerHeaderV2(int functionCode, boolean fresh, Locale locale)
73 	throws ServiceLocationException {
74 	super(functionCode, fresh, locale);
75 
76     }
77 
78     // Assign reply code based on function code type, then use superclass
79     //  method to parse header.
80 
81     void parseHeader(int functionCode, DataInputStream dis)
82 	throws ServiceLocationException, IOException {
83 
84 	// We ignore the error case here.
85 
86 	switch (functionCode) {
87 
88 	case SrvLocHeader.SrvReq:
89 	    replyFunctionCode = SrvLocHeader.SrvRply;
90 	    break;
91 
92 	case SrvLocHeader.AttrRqst:
93 	    replyFunctionCode = SrvLocHeader.AttrRply;
94 	    break;
95 
96 	case SrvLocHeader.SrvTypeRqst:
97 	    replyFunctionCode = SrvLocHeader.SrvTypeRply;
98 	    break;
99 
100 	case SrvLocHeader.SrvReg: case SrvLocHeader.SrvDereg:
101 	    replyFunctionCode = SrvLocHeader.SrvAck;
102 	    break;
103 
104 	    // If we get an error during creating of the DAAdvert to
105 	    //  reply, we need to continue and reply with DAAdvert.
106 	    //  This is only true for a unicast DAAdvert, though.
107 
108 	case SrvLocHeader.DAAdvert:
109 	    replyFunctionCode = SrvLocHeader.DAAdvert;
110 	    break;
111 
112 	    // We ignore the header error code for SAAdvert because
113 	    //  it is always multicast.
114 
115 	}
116 
117 	// We are now set up to handle any errors that may come flying out
118 	//  of here.
119 
120 	super.parseHeader(functionCode, dis);
121 
122     }
123 
124     // Replace the superclass method with a method that parses the server
125     //  side.
126 
127     SrvLocMsg parseMsg(DataInputStream dis)
128 	throws ServiceLocationException,
129 	       IOException,
130 	       IllegalArgumentException {
131 
132 	SrvLocMsg msg = null;
133 
134 	// DAAdvert needs to get it's error code parsed here because
135 	//  error codes are always handled in parseMsg() and it is
136 	//  the only server side message that has one.
137 
138 	if (functionCode == SrvLocHeader.DAAdvert) {
139 	    errCode = (short)getInt(dis);
140 
141 	}
142 
143 	// Switch and convert according to function code.
144 
145 	switch (functionCode) {
146 
147 	case SrvLocHeader.SrvReg:
148 	    msg = new SSrvReg(this, dis);
149 	    break;
150 
151 	case SrvLocHeader.SrvDereg:
152 	    msg = new SSrvDereg(this, dis);
153 	    break;
154 
155 	case SrvLocHeader.SrvReq:
156 	    msg = new SSrvMsg(this, dis);
157 	    break;
158 
159 	case SrvLocHeader.AttrRqst:
160 	    msg = new SAttrMsg(this, dis);
161 	    break;
162 
163 	case SrvLocHeader.SrvAck:
164 
165 	    // We function as our own message.
166 
167 	    msg = this;
168 	    iNumReplies = 1;
169 	    break;
170 
171 	case SrvLocHeader.SrvTypeRqst:
172 	    msg = new SSrvTypeMsg(this, dis);
173 	    break;
174 
175 	case SrvLocHeader.DAAdvert:
176 	    msg = new CDAAdvert(this, dis);
177 	    break;
178 
179 	case SrvLocHeader.SAAdvert:
180 	    msg = new CSAAdvert(this, dis);
181 	    break;
182 
183 	default:
184 	    throw
185 		new ServiceLocationException(
186 				ServiceLocationException.PARSE_ERROR,
187 				"function_code_error",
188 				new Object[] {
189 		    new Integer(functionCode)});
190 
191 	}
192 
193 	// Check for size overflow.
194 
195 	if (nbytes > length) {
196 	    throw
197 		new ServiceLocationException(
198 				ServiceLocationException.PARSE_ERROR,
199 				"length_overflow",
200 				new Object[] {
201 		    new Integer(nbytes), new Integer(length)});
202 
203 	}
204 
205 	return msg;
206 
207     }
208 
209     // Create an error reply using the reply code. Calculate the
210     //  error code using the exception.
211 
212     SrvLocMsg makeErrorReply(Exception ex) {
213 
214 	SrvLocHeader hdr = null;
215 
216 	// Clone the header to make sure that everything else is the same.
217 	//  We don't want to use the same header because it may be tested
218 	//  elsewhere.
219 
220 	try {
221 	    hdr = (SrvLocHeader)this.clone();
222 
223 	} catch (CloneNotSupportedException exx) {
224 
225 	    // We support it, so no-op.
226 
227 	}
228 
229 	// Re-initialize flags but not multicast, since we need to filter on it
230 
231 	hdr.fresh = false;
232 	hdr.overflow = false;
233 	hdr.functionCode = replyFunctionCode;
234 
235 	// We should *not* be getting a null exception down this path!
236 
237 	Assert.slpassert(ex != null,
238 		      "null_parameter",
239 		      new Object[] {ex});
240 
241 	if (ex instanceof ServiceLocationException) {
242 
243 	    hdr.errCode = ((ServiceLocationException)ex).getErrorCode();
244 
245 	    if (!ServiceLocationException.validWireErrorCode(hdr.errCode)) {
246 		hdr.errCode = ServiceLocationException.INTERNAL_ERROR;
247 
248 	    }
249 
250 	} else if (ex instanceof IllegalArgumentException ||
251 		   ex instanceof IOException) {
252 	    hdr.errCode = ServiceLocationException.PARSE_ERROR;
253 
254 	} else {
255 	    hdr.errCode = ServiceLocationException.INTERNAL_ERROR;
256 
257 	}
258 
259 	// Construct header description.
260 
261 	constructDescription("SrvLocMsg", "");
262 
263 	return hdr;
264     }
265 
266     // Return a reply header with flags properly set.
267 
268     SLPServerHeaderV2 makeReplyHeader() {
269 
270 	SLPServerHeaderV2 hdr = null;
271 
272 	try {
273 	    hdr = (SLPServerHeaderV2)this.clone();
274 
275 	} catch (CloneNotSupportedException ex) {
276 
277 	    // No-op, since we support it.
278 
279 	}
280 
281 	hdr.functionCode = replyFunctionCode;
282 	hdr.length = 0;
283 	hdr.previousResponders = null;
284 	hdr.scopes = null;
285 	hdr.overflow = false;
286 	hdr.fresh = false;
287 	hdr.mcast = false;
288 	hdr.nbytes = 0;
289 
290 	return hdr;
291     }
292 
293     // Return display string.
294 
295     public String toString() {
296 	return
297 	    getMsgType() + ":version=``" + version + "''\n" +
298 	    "       functionCode=``" + functionCode + "''\n" +
299 	    "       length=``" + length + "''" + "''\n" +
300 	    "       overflow=``" + overflow + "''\n" +
301 	    "       mcast = ``" + mcast + "''\n" +
302 	    "       fresh=``" + fresh + "''\n" +
303 	    "       locale = ``" + locale + "''\n" +
304 	    "       xid=``0x" + Integer.toHexString(xid) + "''\n" +
305 	    "       errCode=``" + errCode + "''\n" +
306 	    "       previousResponders=``" + previousResponders + "''\n" +
307 	    "       scopes=``" + scopes + "''\n" +
308 	    getMsgDescription();
309     }
310 
311     //
312     // Parsing Utilities.
313     //
314 
315     // Parse in the scope list.
316 
317     void parseScopesIn(DataInputStream dis)
318 	throws ServiceLocationException, IOException {
319 
320 	StringBuffer buf = new StringBuffer();
321 
322 	getString(buf, dis);
323 
324 	scopes = parseCommaSeparatedListIn(buf.toString(), true);
325 
326 	// Unescape scope strings.
327 
328 	unescapeScopeStrings(scopes);
329 
330 	// Validate.
331 
332 	DATable.validateScopes(scopes, locale);
333 
334     }
335 
336     void parsePreviousRespondersIn(DataInputStream dis)
337 	throws ServiceLocationException, IOException {
338 
339 	StringBuffer buf = new StringBuffer();
340 
341 	getString(buf, dis);
342 
343 	previousResponders =
344 	    parseCommaSeparatedListIn(buf.toString(), true);
345 
346     }
347 
348     // Return an SLPv2 DAAdvert.
349 
350     SDAAdvert
351 	getDAAdvert(short xid,
352 		    long timestamp,
353 		    ServiceURL url,
354 		    Vector scopes,
355 		    Vector attrs)
356 	throws ServiceLocationException {
357 
358 	// If scopes vector is null, then return all scopes for this
359 	//  DA.
360 
361 	if (scopes.size() <= 0) {
362 	    scopes = SLPConfig.getSLPConfig().getSAConfiguredScopes();
363 
364 	}
365 
366 	return new SDAAdvert(this, xid, timestamp, url, scopes, attrs);
367 
368     }
369 
370 }
371