package com.sun.slp;
import java.util.*;
class UARequester extends Object implements Locator {
private static SLPConfig config = null;
private static DATable dat = null;
private Locale locale;
UARequester(Locale nlocale) {
Assert.nonNullParameter(nlocale, "locale");
if (config == null) {
config = SLPConfig.getSLPConfig();
}
if (dat == null) {
dat = DATable.getDATable();
}
locale = nlocale;
}
public Locale getLocale() {
return locale;
}
public synchronized ServiceLocationEnumeration
findServiceTypes(String NA, Vector scopes)
throws ServiceLocationException {
Assert.nonNullParameter(NA, " NA");
Assert.nonNullParameter(scopes, "scopes");
Vector msgs = createMessages(SrvLocHeader.SrvTypeRqst,
NA,
null,
null,
scopes);
Vector ret = new Vector();
int i, n = msgs.size();
int max = config.getMaximumResults();
for (i = 0; i < n; i++) {
CSrvTypeMsg msg = (CSrvTypeMsg)msgs.elementAt(i);
checkForError(msg, msgs);
Vector serviceTypes = msg.serviceTypes;
addUnique(serviceTypes, ret, max);
}
return new ServiceLocationEnumerator(ret);
}
public synchronized ServiceLocationEnumeration
findServices(ServiceType type, Vector scopes, String query)
throws ServiceLocationException {
Assert.nonNullParameter(type, "type");
Assert.nonNullParameter(scopes, "scopes");
Assert.nonNullParameter(query, "query");
Vector msgs = createMessages(SrvLocHeader.SrvReq,
type,
query,
type,
scopes);
Vector ret = new Vector();
int i, n = msgs.size();
int max = config.getMaximumResults();
for (i = 0; i < n; i++) {
SrvLocMsg msg = (SrvLocMsg)msgs.elementAt(i);
checkForError(msg, msgs);
Vector serviceURLs = null;
if (msg instanceof CSrvMsg) {
serviceURLs = ((CSrvMsg)msg).serviceURLs;
} else if (msg instanceof CSAAdvert) {
serviceURLs = new Vector();
serviceURLs.addElement(((CSAAdvert)msg).URL);
} else if (msg instanceof CDAAdvert) {
serviceURLs = new Vector();
serviceURLs.addElement(((CDAAdvert)msg).URL);
}
addUnique(serviceURLs, ret, max);
}
return new ServiceLocationEnumerator(ret);
}
public synchronized ServiceLocationEnumeration
findAttributes(ServiceURL URL, Vector scopes, Vector attributeIds)
throws ServiceLocationException {
Assert.nonNullParameter(URL, "URL");
Assert.nonNullParameter(scopes, "scopes");
Assert.nonNullParameter(attributeIds, "attributeIds");
Vector msgs = createMessages(SrvLocHeader.AttrRqst,
URL,
attributeIds,
URL.getServiceType(),
scopes);
Vector ret = new Vector();
int i, n = msgs.size();
int max = config.getMaximumResults();
for (i = 0; i < n; i++) {
SrvLocMsg msg = (SrvLocMsg)msgs.elementAt(i);
checkForError(msg, msgs);
if (msg instanceof CAttrMsg) {
ret = ((CAttrMsg)msg).attrList;
} else if (msg instanceof CSAAdvert) {
CSAAdvert smsg = (CSAAdvert)msg;
if (!URL.equals(smsg.URL)) {
continue;
}
ret = smsg.attrs;
} else if (msg instanceof CDAAdvert) {
CDAAdvert smsg = (CDAAdvert)msg;
if (!URL.equals(smsg.URL)) {
continue;
}
ret = smsg.attrs;
}
if (ret.size() > max) {
ret.setSize(max);
}
break;
}
return new ServiceLocationEnumerator(ret);
}
public synchronized ServiceLocationEnumeration
findAttributes(ServiceType type, Vector scopes, Vector attributeIds)
throws ServiceLocationException {
Assert.nonNullParameter(type, "URL");
Assert.nonNullParameter(scopes, "scopes");
Assert.nonNullParameter(attributeIds, "attributeIds");
Vector msgs = createMessages(SrvLocHeader.AttrRqst,
type,
attributeIds,
type,
scopes);
Vector ret = new Vector();
int i, n = msgs.size();
int max = config.getMaximumResults();
Hashtable ht = new Hashtable();
for (i = 0; i < n && ret.size() < max; i++) {
SrvLocMsg msg = (SrvLocMsg)msgs.elementAt(i);
checkForError(msg, msgs);
Vector attrList = null;
if (msg instanceof CAttrMsg) {
attrList = ((CAttrMsg)msg).attrList;
} else if (msg instanceof CSAAdvert) {
attrList = ((CSAAdvert)msg).attrs;
} else if (msg instanceof CDAAdvert) {
attrList = ((CDAAdvert)msg).attrs;
}
int j, m = attrList.size();
for (j = 0; j < m; j++) {
ServiceLocationAttribute attr =
(ServiceLocationAttribute)attrList.elementAt(j);
ServiceLocationAttribute.mergeDuplicateAttributes(attr,
ht,
ret,
true);
if (ret.size() >= max) {
break;
}
}
}
return new ServiceLocationEnumerator(ret);
}
private Vector
createMessages(int msgType,
Object t1,
Object t2,
ServiceType type,
Vector scopes)
throws ServiceLocationException {
DATable.validateScopes(scopes, locale);
SrvLocMsg multiMsg = null;
SrvLocMsg uniMsg = null;
Vector daAddresses = null;
Vector multiCastScopes = null;
Hashtable daRecords = dat.findDAScopes(scopes);
multiCastScopes =
(Vector)daRecords.get(DATable.MULTICAST_KEY);
daAddresses =
(Vector)daRecords.get(DATable.UNICAST_KEY);
if (((msgType == SrvLocHeader.SrvReq) ||
(msgType == SrvLocHeader.AttrRqst)) &&
(type.equals(Defaults.DA_SERVICE_TYPE) ||
type.equals(Defaults.SA_SERVICE_TYPE))) {
multiCastScopes = scopes;
daAddresses = null;
String query = "";
if (msgType == SrvLocHeader.SrvReq) {
query = (String)t2;
}
multiMsg = new CSrvMsg(locale, type, multiCastScopes, query);
} else {
if (multiCastScopes != null) {
switch (msgType) {
case SrvLocHeader.SrvTypeRqst:
multiMsg =
new CSrvTypeMsg(locale, (String)t1, multiCastScopes);
break;
case SrvLocHeader.SrvReq:
multiMsg =
new CSrvMsg(locale, type, multiCastScopes, (String)t2);
break;
case SrvLocHeader.AttrRqst:
if (t1 instanceof ServiceURL) {
multiMsg =
new CAttrMsg(locale,
(ServiceURL)t1,
multiCastScopes,
(Vector)t2);
} else {
multiMsg =
new CAttrMsg(locale,
type,
multiCastScopes,
(Vector)t2);
}
}
}
if (daAddresses != null) {
switch (msgType) {
case SrvLocHeader.SrvTypeRqst:
uniMsg =
new CSrvTypeMsg(locale, (String)t1, scopes);
break;
case SrvLocHeader.SrvReq:
uniMsg =
new CSrvMsg(locale, type, scopes, (String)t2);
break;
case SrvLocHeader.AttrRqst:
if (t1 instanceof ServiceURL) {
uniMsg =
new CAttrMsg(locale,
(ServiceURL)t1,
scopes,
(Vector)t2);
} else {
uniMsg =
new CAttrMsg(locale,
type,
scopes,
(Vector)t2);
}
}
}
}
return Transact.transactUA(daAddresses,
uniMsg,
multiMsg,
config.getMulticastAddress());
}
private static void
checkForError(SrvLocMsg msg, Vector v)
throws ServiceLocationException {
int err = msg.getErrorCode();
if (err != ServiceLocationException.OK) {
if (v.size() == 1) {
config.writeLog("single_exception",
new Object[] {
Integer.valueOf(err)});
throw
new ServiceLocationException((short)err,
"remote_error",
new Object[] {});
} else {
config.writeLog("multiple_exception",
new Object[] {
Integer.valueOf(err)});
}
}
}
private static void addUnique(Vector incoming, Vector returns, int max) {
int i, n = incoming.size();
for (i = 0; i < n; i++) {
Object o = incoming.elementAt(i);
if (!returns.contains(o) && returns.size() < max) {
returns.addElement(o);
}
}
}
}