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 (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright (c) 1999 by Sun Microsystems, Inc.
23 * All rights reserved.
24 *
25 */
26
27//  SSrvMsg.java:     Message class for SLP service request.
28//  Author:           James Kempf
29//  Created On:       Thu Oct  9 13:40:16 1997
30//  Last Modified By: James Kempf
31//  Last Modified On: Tue Oct 27 10:57:38 1998
32//  Update Count:     112
33//
34
35package com.sun.slp;
36
37import java.util.*;
38import java.io.*;
39
40
41/**
42 * The SSrvMsg class models the SLP service (request, reply) message
43 * server side. Subclasses for other versions can specialize the
44 * initialize() and makeReply() methods.
45 *
46 * @author James Kempf
47 */
48
49class SSrvMsg extends SrvLocMsgImpl {
50
51    String serviceType = "";	// service type and naming authority
52    String query = "";		// the query
53    String spi = "";
54
55    protected SSrvMsg() {}
56
57    // Construct a SSrvMsg from the byte input stream.
58
59    SSrvMsg(SrvLocHeader hdr, DataInputStream dis)
60	throws ServiceLocationException, IOException {
61	super(hdr, SrvLocHeader.SrvReq);
62
63	this.initialize(dis);
64
65    }
66
67    // Initialize the message from the input stream.
68
69    void initialize(DataInputStream dis)
70	throws ServiceLocationException, IOException {
71
72	SLPServerHeaderV2 hdr = (SLPServerHeaderV2)getHeader();
73	StringBuffer buf = new StringBuffer();
74
75	// First get the previous responder.
76
77	hdr.parsePreviousRespondersIn(dis);
78
79	// Get the service type.
80
81	hdr.getString(buf, dis);
82
83	serviceType = buf.toString();
84
85	if (serviceType.length() <= 0) {
86	    throw
87		new ServiceLocationException(
88				ServiceLocationException.PARSE_ERROR,
89				"srq_stype_missing",
90				new Object[0]);
91	}
92
93	ServiceType t = new ServiceType(serviceType);
94
95	serviceType = t.toString();
96
97	// Get vector of scopes.
98
99	hdr.getString(buf, dis);
100
101	hdr.scopes = hdr.parseCommaSeparatedListIn(buf.toString(), true);
102
103	// Validate, but check for empty if solicitation for DAAdvert
104	//  or SAAdvert.
105
106	if (hdr.scopes.size() <= 0) {
107	    if (!t.equals(Defaults.DA_SERVICE_TYPE) &&
108		!t.equals(Defaults.SA_SERVICE_TYPE)) {
109		throw
110		    new ServiceLocationException(
111					ServiceLocationException.PARSE_ERROR,
112					"no_scope_vector",
113					new Object[0]);
114	    }
115	} else {
116
117	    // Unescape scope strings.
118
119	    hdr.unescapeScopeStrings(hdr.scopes);
120
121	    DATable.validateScopes(hdr.scopes, hdr.locale);
122
123	}
124
125	// Get the query.
126
127	hdr.getString(buf, dis);
128
129	query = buf.toString();
130
131	// Get the SPI
132
133	hdr.getString(buf, dis);
134
135	spi = buf.toString();
136
137	hdr.constructDescription("SrvRqst",
138				 "        service type=``" +
139				 serviceType + "''\n" +
140				 "        query=``" +
141				 query + "''\n" +
142				 "        spi=``" +
143				 spi + "''");
144    }
145
146    // Construct a SSrvMsg from the arguments. This will be a SrvRply
147    //  for transmission to the client.
148
149    SrvLocMsg makeReply(Hashtable urls, Hashtable URLSignatures)
150	throws ServiceLocationException {
151
152	SLPServerHeaderV2 hdr =
153	    ((SLPServerHeaderV2)getHeader()).makeReplyHeader();
154
155	hdr.iNumReplies = urls.size();
156	// keep this info so SAs can drop 0 replies
157
158	ByteArrayOutputStream baos = new ByteArrayOutputStream();
159
160	int n = urls.size();
161
162	String authDesc = "\n";
163
164	// Write out size.
165
166	hdr.putInt(n, baos);
167
168	Enumeration en = urls.keys();
169
170	int nurls = 0;
171
172	// Write out the members of the list, including the lifetime.
173
174	while (en.hasMoreElements()) {
175	    ServiceURL surl = (ServiceURL)en.nextElement();
176	    Hashtable auth = null;
177
178	    if (URLSignatures != null) {
179		auth = (Hashtable)URLSignatures.get(surl);
180		AuthBlock selectedAuth =
181		    AuthBlock.getEquivalentAuth(spi, auth);
182		auth = null;
183		if (selectedAuth != null) {
184		    auth = new Hashtable();
185		    auth.put(spi, selectedAuth);
186		}
187		authDesc =
188		    authDesc + "         " + surl.toString() + ": " +
189		    (auth != null ?
190		     selectedAuth.toString() :
191		     "No Auth Block\n");
192	    }
193
194	    // Parse out a URL entry. Check overflow. If the packet has filled
195	    //  up, then break out of the loop.
196
197	    if (hdr.parseServiceURLOut(surl,
198				       (auth != null),
199				       auth,
200				       baos,
201				       true) == false) {
202
203		// Note that we set overflow here because there are additional
204		//  URL's, but we don't have to truncate the packet.
205
206		hdr.overflow = true;
207
208		// We need to rewrite the size to what it should be.
209
210		byte[] bytes = baos.toByteArray();
211		baos.reset();
212		SrvLocHeader.putInteger(nurls, baos);
213		baos.write(bytes, 2, bytes.length - 2);
214		break;
215
216	    }
217
218	    nurls++;
219
220	}
221
222	hdr.payload = baos.toByteArray();
223
224	// Construct description.
225
226	hdr.constructDescription("SrvRply",
227				 "        service URLs=``" + urls + "''\n" +
228				 "        auth block=" + authDesc + "\n");
229
230	return hdr;
231
232    }
233}
234