10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7298SMark.J.Nelson@Sun.COM * Common Development and Distribution License (the "License"). 6*7298SMark.J.Nelson@Sun.COM * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 220Sstevel@tonic-gate * Copyright (c) 1999 by Sun Microsystems, Inc. 230Sstevel@tonic-gate * All rights reserved. 240Sstevel@tonic-gate * 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate // UARequester.java: Requester operations for UA. 280Sstevel@tonic-gate // Author: James Kempf 290Sstevel@tonic-gate // Created On: Thu Jan 8 15:17:35 1998 300Sstevel@tonic-gate // Last Modified By: James Kempf 310Sstevel@tonic-gate // Last Modified On: Mon Feb 22 13:47:06 1999 320Sstevel@tonic-gate // Update Count: 78 330Sstevel@tonic-gate // 340Sstevel@tonic-gate 350Sstevel@tonic-gate package com.sun.slp; 360Sstevel@tonic-gate 370Sstevel@tonic-gate import java.util.*; 380Sstevel@tonic-gate 390Sstevel@tonic-gate /** 400Sstevel@tonic-gate * The URequester class implements the Locator interface. 410Sstevel@tonic-gate * It handles the request for the API. If any of the parameters 420Sstevel@tonic-gate * are missing, they will be supplied with a default value if 430Sstevel@tonic-gate * possible. If a cached value may be supplied, it will be. 440Sstevel@tonic-gate * If no DA is present, and convergence is used to gather 450Sstevel@tonic-gate * results, these will be merged into one result. 460Sstevel@tonic-gate * 470Sstevel@tonic-gate * @author Erik Guttman, James Kempf 480Sstevel@tonic-gate */ 490Sstevel@tonic-gate 500Sstevel@tonic-gate 510Sstevel@tonic-gate class UARequester extends Object implements Locator { 520Sstevel@tonic-gate 530Sstevel@tonic-gate private static SLPConfig config = null; 540Sstevel@tonic-gate private static DATable dat = null; 550Sstevel@tonic-gate 560Sstevel@tonic-gate private Locale locale; 570Sstevel@tonic-gate UARequester(Locale nlocale)580Sstevel@tonic-gate UARequester(Locale nlocale) { 590Sstevel@tonic-gate 600Sstevel@tonic-gate Assert.nonNullParameter(nlocale, "locale"); 610Sstevel@tonic-gate 620Sstevel@tonic-gate if (config == null) { 630Sstevel@tonic-gate config = SLPConfig.getSLPConfig(); 640Sstevel@tonic-gate } 650Sstevel@tonic-gate 660Sstevel@tonic-gate if (dat == null) { 670Sstevel@tonic-gate dat = DATable.getDATable(); 680Sstevel@tonic-gate } 690Sstevel@tonic-gate 700Sstevel@tonic-gate locale = nlocale; 710Sstevel@tonic-gate } 720Sstevel@tonic-gate 730Sstevel@tonic-gate /** 740Sstevel@tonic-gate * Return the Locator's locale object. All requests are made in 750Sstevel@tonic-gate * this locale. 760Sstevel@tonic-gate * 770Sstevel@tonic-gate * @return The Locale object. 780Sstevel@tonic-gate */ 790Sstevel@tonic-gate getLocale()800Sstevel@tonic-gate public Locale getLocale() { 810Sstevel@tonic-gate return locale; 820Sstevel@tonic-gate 830Sstevel@tonic-gate } 840Sstevel@tonic-gate 850Sstevel@tonic-gate /** 860Sstevel@tonic-gate * Return an enumeration of known service types for this scope and naming 870Sstevel@tonic-gate * authority. Unless a proprietary or experimental service is being 880Sstevel@tonic-gate * discovered, the namingAuthority parameter should be the empty 890Sstevel@tonic-gate * string, "". 900Sstevel@tonic-gate * 910Sstevel@tonic-gate * @param NA The naming authority, "" for default, 920Sstevel@tonic-gate * '*' for any naming authority. 930Sstevel@tonic-gate * @param scopes The SLP scopes of the types. 940Sstevel@tonic-gate * @return ServiceLocationEnumeration of ServiceType objects for 950Sstevel@tonic-gate * the service type names. 960Sstevel@tonic-gate * @exception IllegalArgumentException If any of the parameters are 970Sstevel@tonic-gate * null or syntactically incorrect. 980Sstevel@tonic-gate * @exception ServiceLocationException An exception is thrown if the 990Sstevel@tonic-gate * operation fails. 1000Sstevel@tonic-gate */ 1010Sstevel@tonic-gate 1020Sstevel@tonic-gate public synchronized ServiceLocationEnumeration findServiceTypes(String NA, Vector scopes)1030Sstevel@tonic-gate findServiceTypes(String NA, Vector scopes) 1040Sstevel@tonic-gate throws ServiceLocationException { 1050Sstevel@tonic-gate 1060Sstevel@tonic-gate Assert.nonNullParameter(NA, " NA"); 1070Sstevel@tonic-gate Assert.nonNullParameter(scopes, "scopes"); 1080Sstevel@tonic-gate 1090Sstevel@tonic-gate // Formulate and send off messages. 1100Sstevel@tonic-gate 1110Sstevel@tonic-gate Vector msgs = createMessages(SrvLocHeader.SrvTypeRqst, 1120Sstevel@tonic-gate NA, 1130Sstevel@tonic-gate null, 1140Sstevel@tonic-gate null, 1150Sstevel@tonic-gate scopes); 1160Sstevel@tonic-gate 1170Sstevel@tonic-gate // Collate results. 1180Sstevel@tonic-gate 1190Sstevel@tonic-gate Vector ret = new Vector(); 1200Sstevel@tonic-gate int i, n = msgs.size(); 1210Sstevel@tonic-gate int max = config.getMaximumResults(); 1220Sstevel@tonic-gate 1230Sstevel@tonic-gate for (i = 0; i < n; i++) { 1240Sstevel@tonic-gate CSrvTypeMsg msg = (CSrvTypeMsg)msgs.elementAt(i); 1250Sstevel@tonic-gate 1260Sstevel@tonic-gate // Check for errors. 1270Sstevel@tonic-gate 1280Sstevel@tonic-gate checkForError(msg, msgs); 1290Sstevel@tonic-gate 1300Sstevel@tonic-gate Vector serviceTypes = msg.serviceTypes; 1310Sstevel@tonic-gate 1320Sstevel@tonic-gate addUnique(serviceTypes, ret, max); 1330Sstevel@tonic-gate 1340Sstevel@tonic-gate } 1350Sstevel@tonic-gate 1360Sstevel@tonic-gate // Return. 1370Sstevel@tonic-gate 1380Sstevel@tonic-gate return new ServiceLocationEnumerator(ret); 1390Sstevel@tonic-gate } 1400Sstevel@tonic-gate 1410Sstevel@tonic-gate /** 1420Sstevel@tonic-gate * Return an enumeration of ServiceURL objects for services matching 1430Sstevel@tonic-gate * the query. The services are returned from the locale of the 1440Sstevel@tonic-gate * locator. 1450Sstevel@tonic-gate * 1460Sstevel@tonic-gate * @param type The type of the service (e.g. printer, etc.). 1470Sstevel@tonic-gate * @param scopes The SLP scopes of the service types. 1480Sstevel@tonic-gate * @param query A string with the SLP query. 1490Sstevel@tonic-gate * @return ServiceLocationEnumeration of ServiceURL objects for 1500Sstevel@tonic-gate * services matching the 1510Sstevel@tonic-gate * attributes. 1520Sstevel@tonic-gate * @exception ServiceLocationException An exception is returned if the 1530Sstevel@tonic-gate * operation fails. 1540Sstevel@tonic-gate * @see ServiceURL 1550Sstevel@tonic-gate */ 1560Sstevel@tonic-gate 1570Sstevel@tonic-gate public synchronized ServiceLocationEnumeration findServices(ServiceType type, Vector scopes, String query)1580Sstevel@tonic-gate findServices(ServiceType type, Vector scopes, String query) 1590Sstevel@tonic-gate throws ServiceLocationException { 1600Sstevel@tonic-gate 1610Sstevel@tonic-gate Assert.nonNullParameter(type, "type"); 1620Sstevel@tonic-gate Assert.nonNullParameter(scopes, "scopes"); 1630Sstevel@tonic-gate Assert.nonNullParameter(query, "query"); 1640Sstevel@tonic-gate 1650Sstevel@tonic-gate // Formulate and send off messages. 1660Sstevel@tonic-gate 1670Sstevel@tonic-gate Vector msgs = createMessages(SrvLocHeader.SrvReq, 1680Sstevel@tonic-gate type, 1690Sstevel@tonic-gate query, 1700Sstevel@tonic-gate type, 1710Sstevel@tonic-gate scopes); 1720Sstevel@tonic-gate 1730Sstevel@tonic-gate // Collate results. 1740Sstevel@tonic-gate 1750Sstevel@tonic-gate Vector ret = new Vector(); 1760Sstevel@tonic-gate int i, n = msgs.size(); 1770Sstevel@tonic-gate int max = config.getMaximumResults(); 1780Sstevel@tonic-gate 1790Sstevel@tonic-gate for (i = 0; i < n; i++) { 1800Sstevel@tonic-gate SrvLocMsg msg = (SrvLocMsg)msgs.elementAt(i); 1810Sstevel@tonic-gate 1820Sstevel@tonic-gate // Check for errors. 1830Sstevel@tonic-gate 1840Sstevel@tonic-gate checkForError(msg, msgs); 1850Sstevel@tonic-gate 1860Sstevel@tonic-gate // Be sure to account for DAAdverts and SAAdverts. 1870Sstevel@tonic-gate 1880Sstevel@tonic-gate Vector serviceURLs = null; 1890Sstevel@tonic-gate 1900Sstevel@tonic-gate if (msg instanceof CSrvMsg) { 1910Sstevel@tonic-gate serviceURLs = ((CSrvMsg)msg).serviceURLs; 1920Sstevel@tonic-gate 1930Sstevel@tonic-gate } else if (msg instanceof CSAAdvert) { 1940Sstevel@tonic-gate serviceURLs = new Vector(); 1950Sstevel@tonic-gate serviceURLs.addElement(((CSAAdvert)msg).URL); 1960Sstevel@tonic-gate 1970Sstevel@tonic-gate } else if (msg instanceof CDAAdvert) { 1980Sstevel@tonic-gate serviceURLs = new Vector(); 1990Sstevel@tonic-gate serviceURLs.addElement(((CDAAdvert)msg).URL); 2000Sstevel@tonic-gate 2010Sstevel@tonic-gate } 2020Sstevel@tonic-gate 2030Sstevel@tonic-gate addUnique(serviceURLs, ret, max); 2040Sstevel@tonic-gate 2050Sstevel@tonic-gate } 2060Sstevel@tonic-gate 2070Sstevel@tonic-gate // Return. 2080Sstevel@tonic-gate 2090Sstevel@tonic-gate return new ServiceLocationEnumerator(ret); 2100Sstevel@tonic-gate } 2110Sstevel@tonic-gate 2120Sstevel@tonic-gate /** 2130Sstevel@tonic-gate * Return the attributes for the service URL, using the locale 2140Sstevel@tonic-gate * of the locator. 2150Sstevel@tonic-gate * 2160Sstevel@tonic-gate * @param URL The service URL. 2170Sstevel@tonic-gate * @param scopes The SLP scopes of the service. 2180Sstevel@tonic-gate * @param attributeIds A vector of strings identifying the desired 2190Sstevel@tonic-gate * attributes. A null value means return all 2200Sstevel@tonic-gate * the attributes. <b>Partial id strings</b> may 2210Sstevel@tonic-gate * begin with '*' to match all ids which end with 2220Sstevel@tonic-gate * the given suffix, or end with '*' to match all 2230Sstevel@tonic-gate * ids which begin with a given prefix, or begin 2240Sstevel@tonic-gate * and end with '*' to do substring matching for 2250Sstevel@tonic-gate * ids containing the given partial id. 2260Sstevel@tonic-gate * @return ServiceLocationEnumeration of ServiceLocationAttribute 2270Sstevel@tonic-gate * objects matching the ids. 2280Sstevel@tonic-gate * @exception ServiceLocationException An exception is returned if the 2290Sstevel@tonic-gate * operation fails. 2300Sstevel@tonic-gate * @exception IllegalArgumentException If any of the parameters are 2310Sstevel@tonic-gate * null or syntactically incorrect. 2320Sstevel@tonic-gate * @see ServiceLocationAttribute 2330Sstevel@tonic-gate * 2340Sstevel@tonic-gate */ 2350Sstevel@tonic-gate 2360Sstevel@tonic-gate public synchronized ServiceLocationEnumeration findAttributes(ServiceURL URL, Vector scopes, Vector attributeIds)2370Sstevel@tonic-gate findAttributes(ServiceURL URL, Vector scopes, Vector attributeIds) 2380Sstevel@tonic-gate throws ServiceLocationException { 2390Sstevel@tonic-gate 2400Sstevel@tonic-gate Assert.nonNullParameter(URL, "URL"); 2410Sstevel@tonic-gate Assert.nonNullParameter(scopes, "scopes"); 2420Sstevel@tonic-gate Assert.nonNullParameter(attributeIds, "attributeIds"); 2430Sstevel@tonic-gate 2440Sstevel@tonic-gate Vector msgs = createMessages(SrvLocHeader.AttrRqst, 2450Sstevel@tonic-gate URL, 2460Sstevel@tonic-gate attributeIds, 2470Sstevel@tonic-gate URL.getServiceType(), 2480Sstevel@tonic-gate scopes); 2490Sstevel@tonic-gate 2500Sstevel@tonic-gate // Check results. 2510Sstevel@tonic-gate 2520Sstevel@tonic-gate Vector ret = new Vector(); 2530Sstevel@tonic-gate int i, n = msgs.size(); 2540Sstevel@tonic-gate int max = config.getMaximumResults(); 2550Sstevel@tonic-gate 2560Sstevel@tonic-gate // We only take the first message that came back and is OK. 2570Sstevel@tonic-gate 2580Sstevel@tonic-gate for (i = 0; i < n; i++) { 2590Sstevel@tonic-gate SrvLocMsg msg = (SrvLocMsg)msgs.elementAt(i); 2600Sstevel@tonic-gate 2610Sstevel@tonic-gate // Check for errors. 2620Sstevel@tonic-gate 2630Sstevel@tonic-gate checkForError(msg, msgs); 2640Sstevel@tonic-gate 2650Sstevel@tonic-gate // Select out attribute list. 2660Sstevel@tonic-gate 2670Sstevel@tonic-gate if (msg instanceof CAttrMsg) { 2680Sstevel@tonic-gate ret = ((CAttrMsg)msg).attrList; 2690Sstevel@tonic-gate 2700Sstevel@tonic-gate } else if (msg instanceof CSAAdvert) { 2710Sstevel@tonic-gate 2720Sstevel@tonic-gate // Need to check that URL matches. 2730Sstevel@tonic-gate 2740Sstevel@tonic-gate CSAAdvert smsg = (CSAAdvert)msg; 2750Sstevel@tonic-gate 2760Sstevel@tonic-gate if (!URL.equals(smsg.URL)) { 2770Sstevel@tonic-gate continue; 2780Sstevel@tonic-gate 2790Sstevel@tonic-gate } 2800Sstevel@tonic-gate 2810Sstevel@tonic-gate ret = smsg.attrs; 2820Sstevel@tonic-gate 2830Sstevel@tonic-gate } else if (msg instanceof CDAAdvert) { 2840Sstevel@tonic-gate 2850Sstevel@tonic-gate // Need to check that URL matches. 2860Sstevel@tonic-gate 2870Sstevel@tonic-gate CDAAdvert smsg = (CDAAdvert)msg; 2880Sstevel@tonic-gate 2890Sstevel@tonic-gate if (!URL.equals(smsg.URL)) { 2900Sstevel@tonic-gate continue; 2910Sstevel@tonic-gate 2920Sstevel@tonic-gate } 2930Sstevel@tonic-gate 2940Sstevel@tonic-gate ret = smsg.attrs; 2950Sstevel@tonic-gate } 2960Sstevel@tonic-gate 2970Sstevel@tonic-gate // Truncate, if return is larger than maximum. 2980Sstevel@tonic-gate 2990Sstevel@tonic-gate if (ret.size() > max) { 3000Sstevel@tonic-gate ret.setSize(max); 3010Sstevel@tonic-gate 3020Sstevel@tonic-gate } 3030Sstevel@tonic-gate 3040Sstevel@tonic-gate // Break out, we only need one. 3050Sstevel@tonic-gate 3060Sstevel@tonic-gate break; 3070Sstevel@tonic-gate 3080Sstevel@tonic-gate } 3090Sstevel@tonic-gate 3100Sstevel@tonic-gate // Return. 3110Sstevel@tonic-gate 3120Sstevel@tonic-gate return new ServiceLocationEnumerator(ret); 3130Sstevel@tonic-gate } 3140Sstevel@tonic-gate 3150Sstevel@tonic-gate /** 3160Sstevel@tonic-gate * Return all attributes for all service URL's having this 3170Sstevel@tonic-gate * service type in the locale of the Locator. 3180Sstevel@tonic-gate * 3190Sstevel@tonic-gate * @param type The service type. 3200Sstevel@tonic-gate * @param scopes The SLP scopes of the service type. 3210Sstevel@tonic-gate * @param attributeIds A vector of strings identifying the desired 3220Sstevel@tonic-gate * attributes. A null value means return all 3230Sstevel@tonic-gate * the attributes. <b>Partial id strings</b> may 3240Sstevel@tonic-gate * begin with '*' to match all ids which end with 3250Sstevel@tonic-gate * the given suffix, or end with '*' to match all 3260Sstevel@tonic-gate * ids which begin with a given prefix, or begin 3270Sstevel@tonic-gate * and end with '*' to do substring matching for 3280Sstevel@tonic-gate * ids containing the given partial id. 3290Sstevel@tonic-gate * @return ServiceLocationEnumeration of ServiceLocationAttribute 3300Sstevel@tonic-gate * objects matching the ids. 3310Sstevel@tonic-gate * @exception ServiceLocationException An exception is returned if the 3320Sstevel@tonic-gate * operation fails. 3330Sstevel@tonic-gate * @exception IllegalArgumentException If any of the parameters are 3340Sstevel@tonic-gate * null or syntactically incorrect. 3350Sstevel@tonic-gate * @see ServiceLocationAttribute 3360Sstevel@tonic-gate * 3370Sstevel@tonic-gate */ 3380Sstevel@tonic-gate 3390Sstevel@tonic-gate public synchronized ServiceLocationEnumeration findAttributes(ServiceType type, Vector scopes, Vector attributeIds)3400Sstevel@tonic-gate findAttributes(ServiceType type, Vector scopes, Vector attributeIds) 3410Sstevel@tonic-gate throws ServiceLocationException { 3420Sstevel@tonic-gate 3430Sstevel@tonic-gate Assert.nonNullParameter(type, "URL"); 3440Sstevel@tonic-gate Assert.nonNullParameter(scopes, "scopes"); 3450Sstevel@tonic-gate Assert.nonNullParameter(attributeIds, "attributeIds"); 3460Sstevel@tonic-gate 3470Sstevel@tonic-gate // Formulate and send off messages. 3480Sstevel@tonic-gate 3490Sstevel@tonic-gate Vector msgs = createMessages(SrvLocHeader.AttrRqst, 3500Sstevel@tonic-gate type, 3510Sstevel@tonic-gate attributeIds, 3520Sstevel@tonic-gate type, 3530Sstevel@tonic-gate scopes); 3540Sstevel@tonic-gate // Collate results. 3550Sstevel@tonic-gate 3560Sstevel@tonic-gate Vector ret = new Vector(); 3570Sstevel@tonic-gate int i, n = msgs.size(); 3580Sstevel@tonic-gate int max = config.getMaximumResults(); 3590Sstevel@tonic-gate Hashtable ht = new Hashtable(); 3600Sstevel@tonic-gate 3610Sstevel@tonic-gate for (i = 0; i < n && ret.size() < max; i++) { 3620Sstevel@tonic-gate SrvLocMsg msg = (SrvLocMsg)msgs.elementAt(i); 3630Sstevel@tonic-gate 3640Sstevel@tonic-gate // Check for errors. 3650Sstevel@tonic-gate 3660Sstevel@tonic-gate checkForError(msg, msgs); 3670Sstevel@tonic-gate 3680Sstevel@tonic-gate Vector attrList = null; 3690Sstevel@tonic-gate 3700Sstevel@tonic-gate // Get the instance variable. 3710Sstevel@tonic-gate 3720Sstevel@tonic-gate if (msg instanceof CAttrMsg) { 3730Sstevel@tonic-gate attrList = ((CAttrMsg)msg).attrList; 3740Sstevel@tonic-gate 3750Sstevel@tonic-gate } else if (msg instanceof CSAAdvert) { 3760Sstevel@tonic-gate attrList = ((CSAAdvert)msg).attrs; 3770Sstevel@tonic-gate 3780Sstevel@tonic-gate } else if (msg instanceof CDAAdvert) { 3790Sstevel@tonic-gate attrList = ((CDAAdvert)msg).attrs; 3800Sstevel@tonic-gate 3810Sstevel@tonic-gate } 3820Sstevel@tonic-gate 3830Sstevel@tonic-gate // Merge any duplicates. 3840Sstevel@tonic-gate 3850Sstevel@tonic-gate int j, m = attrList.size(); 3860Sstevel@tonic-gate 3870Sstevel@tonic-gate for (j = 0; j < m; j++) { 3880Sstevel@tonic-gate ServiceLocationAttribute attr = 3890Sstevel@tonic-gate (ServiceLocationAttribute)attrList.elementAt(j); 3900Sstevel@tonic-gate 3910Sstevel@tonic-gate ServiceLocationAttribute.mergeDuplicateAttributes(attr, 3920Sstevel@tonic-gate ht, 3930Sstevel@tonic-gate ret, 3940Sstevel@tonic-gate true); 3950Sstevel@tonic-gate 3960Sstevel@tonic-gate if (ret.size() >= max) { 3970Sstevel@tonic-gate break; 3980Sstevel@tonic-gate 3990Sstevel@tonic-gate } 4000Sstevel@tonic-gate } 4010Sstevel@tonic-gate } 4020Sstevel@tonic-gate 4030Sstevel@tonic-gate // Return. 4040Sstevel@tonic-gate 4050Sstevel@tonic-gate return new ServiceLocationEnumerator(ret); 4060Sstevel@tonic-gate } 4070Sstevel@tonic-gate 4080Sstevel@tonic-gate // Execute the message request, returning messages. 4090Sstevel@tonic-gate 4100Sstevel@tonic-gate private Vector createMessages(int msgType, Object t1, Object t2, ServiceType type, Vector scopes)4110Sstevel@tonic-gate createMessages(int msgType, 4120Sstevel@tonic-gate Object t1, 4130Sstevel@tonic-gate Object t2, 4140Sstevel@tonic-gate ServiceType type, 4150Sstevel@tonic-gate Vector scopes) 4160Sstevel@tonic-gate throws ServiceLocationException { 4170Sstevel@tonic-gate 4180Sstevel@tonic-gate // Validate, lower case scopes. 4190Sstevel@tonic-gate 4200Sstevel@tonic-gate DATable.validateScopes(scopes, locale); 4210Sstevel@tonic-gate 4220Sstevel@tonic-gate SrvLocMsg multiMsg = null; 4230Sstevel@tonic-gate SrvLocMsg uniMsg = null; 4240Sstevel@tonic-gate Vector daAddresses = null; 4250Sstevel@tonic-gate Vector multiCastScopes = null; 4260Sstevel@tonic-gate 4270Sstevel@tonic-gate // Get the hashtable of unicast DA addresses and multicast scopes. 4280Sstevel@tonic-gate 4290Sstevel@tonic-gate Hashtable daRecords = dat.findDAScopes(scopes); 4300Sstevel@tonic-gate 4310Sstevel@tonic-gate // Get multicast scopes and DA addresses. 4320Sstevel@tonic-gate 4330Sstevel@tonic-gate multiCastScopes = 4340Sstevel@tonic-gate (Vector)daRecords.get(DATable.MULTICAST_KEY); 4350Sstevel@tonic-gate 4360Sstevel@tonic-gate daAddresses = 4370Sstevel@tonic-gate (Vector)daRecords.get(DATable.UNICAST_KEY); 4380Sstevel@tonic-gate 4390Sstevel@tonic-gate // Special case for service request and attribute request 4400Sstevel@tonic-gate // if the user is looking for a special SLP type. 4410Sstevel@tonic-gate 4420Sstevel@tonic-gate if (((msgType == SrvLocHeader.SrvReq) || 4430Sstevel@tonic-gate (msgType == SrvLocHeader.AttrRqst)) && 4440Sstevel@tonic-gate (type.equals(Defaults.DA_SERVICE_TYPE) || 4450Sstevel@tonic-gate type.equals(Defaults.SA_SERVICE_TYPE))) { 4460Sstevel@tonic-gate 4470Sstevel@tonic-gate multiCastScopes = scopes; 4480Sstevel@tonic-gate daAddresses = null; 4490Sstevel@tonic-gate 4500Sstevel@tonic-gate // Get query. If an attribute request, then the user 4510Sstevel@tonic-gate // needs to sort out the attributes. 4520Sstevel@tonic-gate 4530Sstevel@tonic-gate String query = ""; 4540Sstevel@tonic-gate 4550Sstevel@tonic-gate if (msgType == SrvLocHeader.SrvReq) { 4560Sstevel@tonic-gate query = (String)t2; 4570Sstevel@tonic-gate 4580Sstevel@tonic-gate } 4590Sstevel@tonic-gate 4600Sstevel@tonic-gate multiMsg = new CSrvMsg(locale, type, multiCastScopes, query); 4610Sstevel@tonic-gate 4620Sstevel@tonic-gate } else { 4630Sstevel@tonic-gate 4640Sstevel@tonic-gate // Handle a regular message. 4650Sstevel@tonic-gate 4660Sstevel@tonic-gate // Multicast scopes are all scopes not supported by any DA. 4670Sstevel@tonic-gate 4680Sstevel@tonic-gate if (multiCastScopes != null) { 4690Sstevel@tonic-gate 4700Sstevel@tonic-gate switch (msgType) { 4710Sstevel@tonic-gate 4720Sstevel@tonic-gate case SrvLocHeader.SrvTypeRqst: 4730Sstevel@tonic-gate multiMsg = 4740Sstevel@tonic-gate new CSrvTypeMsg(locale, (String)t1, multiCastScopes); 4750Sstevel@tonic-gate break; 4760Sstevel@tonic-gate 4770Sstevel@tonic-gate case SrvLocHeader.SrvReq: 4780Sstevel@tonic-gate multiMsg = 4790Sstevel@tonic-gate new CSrvMsg(locale, type, multiCastScopes, (String)t2); 4800Sstevel@tonic-gate break; 4810Sstevel@tonic-gate 4820Sstevel@tonic-gate case SrvLocHeader.AttrRqst: 4830Sstevel@tonic-gate 4840Sstevel@tonic-gate if (t1 instanceof ServiceURL) { 4850Sstevel@tonic-gate multiMsg = 4860Sstevel@tonic-gate new CAttrMsg(locale, 4870Sstevel@tonic-gate (ServiceURL)t1, 4880Sstevel@tonic-gate multiCastScopes, 4890Sstevel@tonic-gate (Vector)t2); 4900Sstevel@tonic-gate 4910Sstevel@tonic-gate } else { 4920Sstevel@tonic-gate multiMsg = 4930Sstevel@tonic-gate new CAttrMsg(locale, 4940Sstevel@tonic-gate type, 4950Sstevel@tonic-gate multiCastScopes, 4960Sstevel@tonic-gate (Vector)t2); 4970Sstevel@tonic-gate 4980Sstevel@tonic-gate } 4990Sstevel@tonic-gate } 5000Sstevel@tonic-gate } 5010Sstevel@tonic-gate 5020Sstevel@tonic-gate // Unicast only requires a single message because the DAs will 5030Sstevel@tonic-gate // ignore any scopes they do not support, just as long as 5040Sstevel@tonic-gate // they support one of them. 5050Sstevel@tonic-gate 5060Sstevel@tonic-gate if (daAddresses != null) { 5070Sstevel@tonic-gate switch (msgType) { 5080Sstevel@tonic-gate 5090Sstevel@tonic-gate case SrvLocHeader.SrvTypeRqst: 5100Sstevel@tonic-gate uniMsg = 5110Sstevel@tonic-gate new CSrvTypeMsg(locale, (String)t1, scopes); 5120Sstevel@tonic-gate break; 5130Sstevel@tonic-gate 5140Sstevel@tonic-gate case SrvLocHeader.SrvReq: 5150Sstevel@tonic-gate uniMsg = 5160Sstevel@tonic-gate new CSrvMsg(locale, type, scopes, (String)t2); 5170Sstevel@tonic-gate break; 5180Sstevel@tonic-gate 5190Sstevel@tonic-gate case SrvLocHeader.AttrRqst: 5200Sstevel@tonic-gate 5210Sstevel@tonic-gate if (t1 instanceof ServiceURL) { 5220Sstevel@tonic-gate uniMsg = 5230Sstevel@tonic-gate new CAttrMsg(locale, 5240Sstevel@tonic-gate (ServiceURL)t1, 5250Sstevel@tonic-gate scopes, 5260Sstevel@tonic-gate (Vector)t2); 5270Sstevel@tonic-gate 5280Sstevel@tonic-gate } else { 5290Sstevel@tonic-gate uniMsg = 5300Sstevel@tonic-gate new CAttrMsg(locale, 5310Sstevel@tonic-gate type, 5320Sstevel@tonic-gate scopes, 5330Sstevel@tonic-gate (Vector)t2); 5340Sstevel@tonic-gate 5350Sstevel@tonic-gate } 5360Sstevel@tonic-gate 5370Sstevel@tonic-gate } 5380Sstevel@tonic-gate } 5390Sstevel@tonic-gate } 5400Sstevel@tonic-gate 5410Sstevel@tonic-gate // Send off messages, return results. 5420Sstevel@tonic-gate 5430Sstevel@tonic-gate return Transact.transactUA(daAddresses, 5440Sstevel@tonic-gate uniMsg, 5450Sstevel@tonic-gate multiMsg, 5460Sstevel@tonic-gate config.getMulticastAddress()); 5470Sstevel@tonic-gate } 5480Sstevel@tonic-gate 5490Sstevel@tonic-gate // Check message for error code. 5500Sstevel@tonic-gate 5510Sstevel@tonic-gate private static void checkForError(SrvLocMsg msg, Vector v)5520Sstevel@tonic-gate checkForError(SrvLocMsg msg, Vector v) 5530Sstevel@tonic-gate throws ServiceLocationException { 5540Sstevel@tonic-gate int err = msg.getErrorCode(); 5550Sstevel@tonic-gate 5560Sstevel@tonic-gate if (err != ServiceLocationException.OK) { 5570Sstevel@tonic-gate if (v.size() == 1) { 5580Sstevel@tonic-gate config.writeLog("single_exception", 5590Sstevel@tonic-gate new Object[] { 5600Sstevel@tonic-gate new Integer(err)}); 5610Sstevel@tonic-gate throw 5620Sstevel@tonic-gate new ServiceLocationException((short)err, 5630Sstevel@tonic-gate "remote_error", 5640Sstevel@tonic-gate new Object[] {}); 5650Sstevel@tonic-gate } else { 5660Sstevel@tonic-gate config.writeLog("multiple_exception", 5670Sstevel@tonic-gate new Object[] { 5680Sstevel@tonic-gate new Integer(err)}); 5690Sstevel@tonic-gate } 5700Sstevel@tonic-gate } 5710Sstevel@tonic-gate } 5720Sstevel@tonic-gate 5730Sstevel@tonic-gate // Process the incoming vector, adding any unique returns. 5740Sstevel@tonic-gate addUnique(Vector incoming, Vector returns, int max)5750Sstevel@tonic-gate private static void addUnique(Vector incoming, Vector returns, int max) { 5760Sstevel@tonic-gate 5770Sstevel@tonic-gate int i, n = incoming.size(); 5780Sstevel@tonic-gate 5790Sstevel@tonic-gate for (i = 0; i < n; i++) { 5800Sstevel@tonic-gate Object o = incoming.elementAt(i); 5810Sstevel@tonic-gate 5820Sstevel@tonic-gate if (!returns.contains(o) && returns.size() < max) { 5830Sstevel@tonic-gate returns.addElement(o); 5840Sstevel@tonic-gate 5850Sstevel@tonic-gate } 5860Sstevel@tonic-gate } 5870Sstevel@tonic-gate } 5880Sstevel@tonic-gate 5890Sstevel@tonic-gate } 590