/* * 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); } }