the "on demand" access to remote services doesn't work properly for me. There are several problems in retrieving remote services which are described in the method below. If you think this is a worthy issue we can work together on this.
/**
* Returns a list of remote service proxies for a given service name. The given
* service might be provided by several users. Use filterIDs and filter to delimit the
* amount of services.
*
* @param service
* The needed remote service name. (Use yourinterface.class)
* @param filterIDs
* IRosterEntry-IDs, work as a filter though remote services will be
* limited to the given user. May be null if the service should
* be get for all users.
* @param filter
* Additional filter which checks if the service properties do
* match the given filter. May be null if all services should be
* found
* @return A list of remote service proxies
* @throws ECFException
* @throws InvalidSyntaxException
*/
public <T> List<T> getRemoteService(Class<T> service, ID[] filterIDs,
String filter) throws ECFException, InvalidSyntaxException {
List<T> remoteServices = new ArrayList<T>();
IRemoteServiceContainerAdapter remoteServiceContainerAdapter = getRemoteServiceContainerAdapter();
/*
* XXX: according to Scott Lewis the filterIDs have to be containerIDs
* and not rosterIDs, therefore the IRemoteServiceReferences are not
* properly filtered. Solution needed for this problem! According to
* Scott this might become API in the next release
* XXX this is a workaround for the above mentioned problem. The idea is
* to get all remote services and ask each serviceReference for the
* containerID. Afterwards the containerID-name will be matched with the
* given rosterID-name in order to filter only those services which are
* requested (filterIDs).
*/
/* 1. get all available services */
IRemoteServiceReference[] refs = remoteServiceContainerAdapter
.getRemoteServiceReferences(null, service.getName(), filter);
Map<String, T> filteredServices = new HashMap<String, T>();
/* 2. filter services for the given rosterIDs */
for (int serviceNumber = 0; serviceNumber < refs.length; serviceNumber++) {
IRemoteService remoteService = remoteServiceContainerAdapter
.getRemoteService(refs[serviceNumber]);
Assert.isNotNull(remoteService);
String containerIDName = refs[serviceNumber].getContainerID()
.getName();
int indexOfContainer = containerIDName.indexOf("@");
String containerUserName = containerIDName.substring(0,
indexOfContainer);
for (ID userID : filterIDs) {
String userIDName = userID.getName();
/*
* XXX workaround for container and roster IDs. Split user names
* and compare only names. This is dangerous as the same user
* can be connected to a XMPP server several times.
* TODO: Compare user resources as well?!?
*/
int indexOfUser = userIDName.indexOf("@");
String userName = userIDName.substring(0, indexOfUser);
if (containerUserName.equals(userName)) {
// get proxy for remote service and add service to the
// service list
T castedService = service.cast(remoteService.getProxy());
Assert.isNotNull(castedService);
/*
* XXX: next workaround. If a user connects and disconnects
* several times user services will also be registered
* several times. Asking for a specific service for a user
* in this method may result in multiple services references. A map
* will avoid multiple services and return only one service
* per user.
*/
filteredServices.put(userIDName, castedService);
break;
}
}
}
remoteServices.addAll(filteredServices.values());
return remoteServices;
}
I hope we can get this fixed as well.