/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2001-2002 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
*/
// SLPServerHeaderV2.java: SLPv2 Header Class for Server Side
// Author: James Kempf
// Created On: Wed Sep 16 08:44:31 1998
// Last Modified By: James Kempf
// Last Modified On: Mon Jan 4 15:26:33 1999
// Update Count: 30
//
package com.sun.slp;
import java.util.*;
import java.net.*;
import java.io.*;
import java.security.*;
/**
* The SLPServerHeaderV2 class serves as the header class for all server side
* SLPv2 messages.
*
* @author James Kempf
*/
class SLPServerHeaderV2 extends SLPHeaderV2 implements Cloneable {
// Function code for message reply.
int replyFunctionCode = SrvLocHeader.SrvAck;
// For SrvLocHeader.newInstance().
SLPServerHeaderV2() {
super();
}
// Construct a header for output. Used by the client side code to
// construct an initial request and the server side code to construct
// a reply.
SLPServerHeaderV2(int functionCode, boolean fresh, Locale locale)
throws ServiceLocationException {
super(functionCode, fresh, locale);
}
// Assign reply code based on function code type, then use superclass
// method to parse header.
void parseHeader(int functionCode, DataInputStream dis)
throws ServiceLocationException, IOException {
// We ignore the error case here.
switch (functionCode) {
case SrvLocHeader.SrvReq:
replyFunctionCode = SrvLocHeader.SrvRply;
break;
case SrvLocHeader.AttrRqst:
replyFunctionCode = SrvLocHeader.AttrRply;
break;
case SrvLocHeader.SrvTypeRqst:
replyFunctionCode = SrvLocHeader.SrvTypeRply;
break;
case SrvLocHeader.SrvReg: case SrvLocHeader.SrvDereg:
replyFunctionCode = SrvLocHeader.SrvAck;
break;
// If we get an error during creating of the DAAdvert to
// reply, we need to continue and reply with DAAdvert.
// This is only true for a unicast DAAdvert, though.
case SrvLocHeader.DAAdvert:
replyFunctionCode = SrvLocHeader.DAAdvert;
break;
// We ignore the header error code for SAAdvert because
// it is always multicast.
}
// We are now set up to handle any errors that may come flying out
// of here.
super.parseHeader(functionCode, dis);
}
// Replace the superclass method with a method that parses the server
// side.
SrvLocMsg parseMsg(DataInputStream dis)
throws ServiceLocationException,
IOException,
IllegalArgumentException {
SrvLocMsg msg = null;
// DAAdvert needs to get it's error code parsed here because
// error codes are always handled in parseMsg() and it is
// the only server side message that has one.
if (functionCode == SrvLocHeader.DAAdvert) {
errCode = (short)getInt(dis);
}
// Switch and convert according to function code.
switch (functionCode) {
case SrvLocHeader.SrvReg:
msg = new SSrvReg(this, dis);
break;
case SrvLocHeader.SrvDereg:
msg = new SSrvDereg(this, dis);
break;
case SrvLocHeader.SrvReq:
msg = new SSrvMsg(this, dis);
break;
case SrvLocHeader.AttrRqst:
msg = new SAttrMsg(this, dis);
break;
case SrvLocHeader.SrvAck:
// We function as our own message.
msg = this;
iNumReplies = 1;
break;
case SrvLocHeader.SrvTypeRqst:
msg = new SSrvTypeMsg(this, dis);
break;
case SrvLocHeader.DAAdvert:
msg = new CDAAdvert(this, dis);
break;
case SrvLocHeader.SAAdvert:
msg = new CSAAdvert(this, dis);
break;
default:
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"function_code_error",
new Object[] {
new Integer(functionCode)});
}
// Check for size overflow.
if (nbytes > length) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"length_overflow",
new Object[] {
new Integer(nbytes), new Integer(length)});
}
return msg;
}
// Create an error reply using the reply code. Calculate the
// error code using the exception.
SrvLocMsg makeErrorReply(Exception ex) {
SrvLocHeader hdr = null;
// Clone the header to make sure that everything else is the same.
// We don't want to use the same header because it may be tested
// elsewhere.
try {
hdr = (SrvLocHeader)this.clone();
} catch (CloneNotSupportedException exx) {
// We support it, so no-op.
}
// Re-initialize flags but not multicast, since we need to filter on it
hdr.fresh = false;
hdr.overflow = false;
hdr.functionCode = replyFunctionCode;
// We should *not* be getting a null exception down this path!
Assert.slpassert(ex != null,
"null_parameter",
new Object[] {ex});
if (ex instanceof ServiceLocationException) {
hdr.errCode = ((ServiceLocationException)ex).getErrorCode();
if (!ServiceLocationException.validWireErrorCode(hdr.errCode)) {
hdr.errCode = ServiceLocationException.INTERNAL_ERROR;
}
} else if (ex instanceof IllegalArgumentException ||
ex instanceof IOException) {
hdr.errCode = ServiceLocationException.PARSE_ERROR;
} else {
hdr.errCode = ServiceLocationException.INTERNAL_ERROR;
}
// Construct header description.
constructDescription("SrvLocMsg", "");
return hdr;
}
// Return a reply header with flags properly set.
SLPServerHeaderV2 makeReplyHeader() {
SLPServerHeaderV2 hdr = null;
try {
hdr = (SLPServerHeaderV2)this.clone();
} catch (CloneNotSupportedException ex) {
// No-op, since we support it.
}
hdr.functionCode = replyFunctionCode;
hdr.length = 0;
hdr.previousResponders = null;
hdr.scopes = null;
hdr.overflow = false;
hdr.fresh = false;
hdr.mcast = false;
hdr.nbytes = 0;
return hdr;
}
// Return display string.
public String toString() {
return
getMsgType() + ":version=``" + version + "''\n" +
" functionCode=``" + functionCode + "''\n" +
" length=``" + length + "''" + "''\n" +
" overflow=``" + overflow + "''\n" +
" mcast = ``" + mcast + "''\n" +
" fresh=``" + fresh + "''\n" +
" locale = ``" + locale + "''\n" +
" xid=``0x" + Integer.toHexString(xid) + "''\n" +
" errCode=``" + errCode + "''\n" +
" previousResponders=``" + previousResponders + "''\n" +
" scopes=``" + scopes + "''\n" +
getMsgDescription();
}
//
// Parsing Utilities.
//
// Parse in the scope list.
void parseScopesIn(DataInputStream dis)
throws ServiceLocationException, IOException {
StringBuffer buf = new StringBuffer();
getString(buf, dis);
scopes = parseCommaSeparatedListIn(buf.toString(), true);
// Unescape scope strings.
unescapeScopeStrings(scopes);
// Validate.
DATable.validateScopes(scopes, locale);
}
void parsePreviousRespondersIn(DataInputStream dis)
throws ServiceLocationException, IOException {
StringBuffer buf = new StringBuffer();
getString(buf, dis);
previousResponders =
parseCommaSeparatedListIn(buf.toString(), true);
}
// Return an SLPv2 DAAdvert.
SDAAdvert
getDAAdvert(short xid,
long timestamp,
ServiceURL url,
Vector scopes,
Vector attrs)
throws ServiceLocationException {
// If scopes vector is null, then return all scopes for this
// DA.
if (scopes.size() <= 0) {
scopes = SLPConfig.getSLPConfig().getSAConfiguredScopes();
}
return new SDAAdvert(this, xid, timestamp, url, scopes, attrs);
}
}