blob: 9fb20510499f75da605cb76f6a33aa4656603157 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010 Composent, Inc. and others. All rights reserved. This
* program and the accompanying materials are made available under the terms of
* the Eclipse Public License v1.0 which accompanies this distribution, and is
* available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Composent, Inc. - initial API and implementation
******************************************************************************/
package org.eclipse.ecf.internal.osgi.services.distribution;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.ecf.core.ContainerConnectException;
import org.eclipse.ecf.core.ContainerTypeDescription;
import org.eclipse.ecf.core.IContainer;
import org.eclipse.ecf.core.IContainerManager;
import org.eclipse.ecf.core.identity.ID;
import org.eclipse.ecf.osgi.services.discovery.DiscoveredServiceNotification;
import org.eclipse.ecf.osgi.services.discovery.DiscoveredServiceTracker;
import org.eclipse.ecf.osgi.services.discovery.IRemoteServiceEndpointDescription;
import org.eclipse.ecf.osgi.services.discovery.RemoteServiceEndpointDescription;
import org.eclipse.ecf.osgi.services.discovery.RemoteServicePublication;
import org.eclipse.ecf.osgi.services.discovery.ServiceEndpointDescription;
import org.eclipse.ecf.osgi.services.discovery.ServicePublication;
import org.eclipse.ecf.osgi.services.distribution.IDistributionConstants;
import org.eclipse.ecf.osgi.services.distribution.IProxyContainerFinder;
import org.eclipse.ecf.osgi.services.distribution.IProxyDistributionListener;
import org.eclipse.ecf.remoteservice.Constants;
import org.eclipse.ecf.remoteservice.IRemoteService;
import org.eclipse.ecf.remoteservice.IRemoteServiceContainer;
import org.eclipse.ecf.remoteservice.IRemoteServiceListener;
import org.eclipse.ecf.remoteservice.IRemoteServiceReference;
import org.eclipse.ecf.remoteservice.events.IRemoteServiceEvent;
import org.eclipse.ecf.remoteservice.events.IRemoteServiceUnregisteredEvent;
import org.eclipse.osgi.framework.eventmgr.CopyOnWriteIdentityMap;
import org.eclipse.osgi.framework.eventmgr.EventDispatcher;
import org.eclipse.osgi.framework.eventmgr.EventManager;
import org.eclipse.osgi.framework.eventmgr.ListenerQueue;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceRegistration;
public class DiscoveredServiceTrackerImpl implements DiscoveredServiceTracker {
private DistributionProviderImpl distributionProvider;
private List serviceLocations = new ArrayList();
// <Map<containerID><RemoteServiceRegistration>
private Map discoveredRemoteServiceRegistrations = new HashMap();
private List ecfRemoteServiceProperties = Arrays.asList(new String[] {
Constants.SERVICE_ID, Constants.OBJECTCLASS,
org.eclipse.ecf.remoteservice.Constants.SERVICE_ID,
org.eclipse.ecf.remoteservice.Constants.SERVICE_CONTAINER_ID,
org.eclipse.ecf.remoteservice.Constants.SERVICE_RANKING,
IDistributionConstants.SERVICE_EXPORTED_CONFIGS,
RemoteServicePublication.ENDPOINT_ID,
RemoteServicePublication.ENDPOINT_INTERFACE_NAME,
RemoteServicePublication.ENDPOINT_LOCATION,
RemoteServicePublication.SERVICE_INTERFACE_NAME,
RemoteServicePublication.SERVICE_INTERFACE_VERSION,
RemoteServicePublication.SERVICE_PROPERTIES, "service.uri" }); //$NON-NLS-1$
// queue for incoming remote service available events
private ListenerQueue queue;
private EventManager eventManager;
// This class is to hold the discovered endpoint available events
class DiscoveredEndpointEvent {
private RemoteServiceEndpointDescription rsEndpointDescription;
public DiscoveredEndpointEvent(
RemoteServiceEndpointDescription rsEndpointDescription) {
this.rsEndpointDescription = rsEndpointDescription;
}
public RemoteServiceEndpointDescription getEndpointDescription() {
return rsEndpointDescription;
}
}
public DiscoveredServiceTrackerImpl(DistributionProviderImpl dp) {
this.distributionProvider = dp;
ThreadGroup eventGroup = new ThreadGroup("Remote Service Dispatcher"); //$NON-NLS-1$
eventGroup.setDaemon(true);
eventManager = new EventManager("Remote Service Dispatcher", eventGroup); //$NON-NLS-1$
queue = new ListenerQueue(eventManager);
CopyOnWriteIdentityMap listeners = new CopyOnWriteIdentityMap();
listeners.put(this, this);
queue.queueListeners(listeners.entrySet(), new EventDispatcher() {
public void dispatchEvent(Object eventListener,
Object listenerObject, int eventAction, Object eventObject) {
RemoteServiceEndpointDescription rsEndpointDescription = ((DiscoveredEndpointEvent) eventObject)
.getEndpointDescription();
try {
handleDiscoveredServiceAvailable(rsEndpointDescription);
} catch (Exception e) {
logError("handleDiscoveredServiceAvailble", //$NON-NLS-1$
"Unexpected exception with rsEndpointDescription=" //$NON-NLS-1$
+ rsEndpointDescription, e);
throw new RuntimeException(
"Unexpected exception with rsEndpointDescription=" //$NON-NLS-1$
+ rsEndpointDescription, e);
}
}
});
}
public void close() {
if (eventManager != null) {
eventManager.close();
eventManager = null;
queue = null;
}
serviceLocations.clear();
discoveredRemoteServiceRegistrations.clear();
}
/*
* (non-Javadoc)
*
* @see
* org.osgi.service.discovery.DiscoveredServiceTracker#serviceChanged(org
* .osgi.service.discovery.DiscoveredServiceNotification)
*/
public void serviceChanged(final DiscoveredServiceNotification notification) {
if (notification == null)
return;
int notificationType = notification.getType();
switch (notificationType) {
case DiscoveredServiceNotification.AVAILABLE:
RemoteServiceEndpointDescription adesc = null;
try {
// If the service endpoint description is not ECF's then we
// don't process it
adesc = getECFDescription(notification
.getServiceEndpointDescription());
} catch (Exception e) {
logError("serviceChanged.AVAILABLE", //$NON-NLS-1$
"Error creating ECF endpoint description", e); //$NON-NLS-1$
return;
}
// If it's not for us then return
if (adesc == null)
return;
if (!isValidDescription(adesc)) {
trace("serviceChanged.AVAILABLE", //$NON-NLS-1$
"Duplicate or invalid description=" + adesc); //$NON-NLS-1$
return;
}
final RemoteServiceEndpointDescription rsEndpointDescription = adesc;
// put in queue and execute asynchronously
queue.dispatchEventAsynchronous(0, new DiscoveredEndpointEvent(
rsEndpointDescription));
break;
case DiscoveredServiceNotification.UNAVAILABLE:
try {
RemoteServiceEndpointDescription udesc = getECFDescription(notification
.getServiceEndpointDescription());
// If it's not for us then return
if (udesc == null)
return;
// Remove existing proxy service registrations that correspond
// to the
// given serviceID
synchronized (serviceLocations) {
ServiceRegistration[] proxyServiceRegistrations = removeProxyServiceRegistrations(udesc);
// Then unregister them
if (proxyServiceRegistrations != null) {
for (int i = 0; i < proxyServiceRegistrations.length; i++) {
trace("handleDiscoveredServiceUnavailable", //$NON-NLS-1$
"proxyServiceRegistrations=" //$NON-NLS-1$
+ proxyServiceRegistrations[i]
+ ",serviceEndpointDesc=" + udesc); //$NON-NLS-1$
unregisterProxyServiceRegistration(udesc,
proxyServiceRegistrations[i]);
}
removeDiscoveredServiceID(udesc);
}
}
} catch (Exception e) {
logError("serviceChanged", "UNAVAILABLE", e); //$NON-NLS-1$ //$NON-NLS-2$
}
break;
case DiscoveredServiceNotification.MODIFIED:
// Do nothing for now
break;
case DiscoveredServiceNotification.MODIFIED_ENDMATCH:
// Do nothing for now
break;
default:
logWarning("serviceChanged", "DiscoveredServiceNotification type=" //$NON-NLS-1$ //$NON-NLS-2$
+ notificationType + " not found. Ignoring"); //$NON-NLS-1$
break;
}
}
private void handleDiscoveredServiceAvailable(
RemoteServiceEndpointDescription endpointDescription) {
// Find IRemoteServiceContainers for the given
// RemoteServiceEndpointDescription via registered services
IRemoteServiceContainer[] rsContainers = findProxyContainers(endpointDescription);
// If none found, we have nothing to do
if (rsContainers == null || rsContainers.length == 0) {
logWarning("handleDiscoveredServiceAvailable", //$NON-NLS-1$
"No local RemoteServiceContainers found for endpoint description=" //$NON-NLS-1$
+ endpointDescription);
return;
}
// Get endpoint ID
ID endpointID = endpointDescription.getEndpointAsID();
// Get remote service filter from the service endpoint description
// if it exists.
String remoteServiceFilter = getFullRemoteServicesFilter(
endpointDescription.getRemoteServicesFilter(),
endpointDescription.getRemoteServiceId());
// Get provided interfaces as collection
Collection providedInterfaces = endpointDescription
.getProvidedInterfaces();
// Now for all remote service containers
for (int i = 0; i < rsContainers.length; i++) {
for (Iterator j = providedInterfaces.iterator(); j.hasNext();) {
String providedInterface = (String) j.next();
IRemoteServiceReference[] remoteReferences = null;
// fire IProxyDistributionListeners pre get references
firePreGetRemoteServiceReferences(endpointDescription,
rsContainers[i]);
try {
// Get remote remote references for each container
remoteReferences = rsContainers[i].getContainerAdapter()
.getRemoteServiceReferences(endpointID,
new ID[] { endpointID }, providedInterface,
remoteServiceFilter);
} catch (ContainerConnectException e) {
logError("handleDiscoveredServiceAvailable", "rsca=" //$NON-NLS-1$ //$NON-NLS-2$
+ rsContainers[i] + ",endpointId=" + endpointID //$NON-NLS-1$
+ ",intf=" + providedInterface //$NON-NLS-1$
+ ". Connect error in getRemoteServiceReferences", //$NON-NLS-1$
e);
continue;
} catch (InvalidSyntaxException e) {
logError(
"handleDiscoveredServiceAvailable", //$NON-NLS-1$
"rsca=" //$NON-NLS-1$
+ rsContainers[i]
+ ",endpointId=" //$NON-NLS-1$
+ endpointID
+ ",intf=" //$NON-NLS-1$
+ providedInterface
+ " Filter syntax error in getRemoteServiceReferences", //$NON-NLS-1$
e);
continue;
}
if (remoteReferences == null || remoteReferences.length == 0) {
logError("handleDiscoveredServiceAvailable", //$NON-NLS-1$
"getRemoteServiceReferences result is empty. " //$NON-NLS-1$
+ "containerHelper=" //$NON-NLS-1$
+ rsContainers[i]
+ "remoteReferences=" //$NON-NLS-1$
+ ((remoteReferences == null) ? "null" //$NON-NLS-1$
: Arrays.asList(remoteReferences)
.toString()), null);
continue;
} else {
registerRemoteServiceReferences(endpointDescription,
rsContainers[i], remoteReferences);
}
}
}
}
private String getFullRemoteServicesFilter(String remoteServicesFilter,
long remoteServiceId) {
if (remoteServiceId < 0)
return remoteServicesFilter;
StringBuffer filter = new StringBuffer("(&(") //$NON-NLS-1$
.append(org.eclipse.ecf.remoteservice.Constants.SERVICE_ID)
.append("=").append(remoteServiceId).append(")"); //$NON-NLS-1$ //$NON-NLS-2$
if (remoteServicesFilter != null)
filter.append(remoteServicesFilter);
filter.append(")"); //$NON-NLS-1$
return filter.toString();
}
private void firePreGetRemoteServiceReferences(
final IRemoteServiceEndpointDescription endpointDescription,
final IRemoteServiceContainer remoteServiceContainer) {
Activator activator = Activator.getDefault();
if (activator != null) {
IProxyDistributionListener[] listeners = activator
.getProxyDistributionListeners();
if (listeners != null) {
for (int i = 0; i < listeners.length; i++) {
final IProxyDistributionListener l = listeners[i];
SafeRunner.run(new ISafeRunnable() {
public void handleException(Throwable exception) {
logError(
"firePreGetRemoteServiceReferences", //$NON-NLS-1$
"Exception calling proxy distribution listener", //$NON-NLS-1$
exception);
}
public void run() throws Exception {
l.retrievingRemoteServiceReferences(
endpointDescription, remoteServiceContainer);
}
});
}
}
}
}
private void firePreRegister(
final IRemoteServiceEndpointDescription endpointDescription,
final IRemoteServiceContainer remoteServiceContainer,
final IRemoteServiceReference remoteServiceReference) {
Activator activator = Activator.getDefault();
if (activator != null) {
IProxyDistributionListener[] listeners = activator
.getProxyDistributionListeners();
if (listeners != null) {
for (int i = 0; i < listeners.length; i++) {
final IProxyDistributionListener l = listeners[i];
SafeRunner.run(new ISafeRunnable() {
public void handleException(Throwable exception) {
logError(
"firePreRegister", //$NON-NLS-1$
"Exception calling proxy distribution listener", //$NON-NLS-1$
exception);
}
public void run() throws Exception {
l.registering(endpointDescription,
remoteServiceContainer,
remoteServiceReference);
}
});
}
}
}
}
private void firePostRegister(
final IRemoteServiceEndpointDescription endpointDescription,
final IRemoteServiceContainer remoteServiceContainer,
final IRemoteServiceReference remoteServiceReference,
final ServiceRegistration serviceRegistration) {
Activator activator = Activator.getDefault();
if (activator != null) {
IProxyDistributionListener[] listeners = activator
.getProxyDistributionListeners();
if (listeners != null) {
for (int i = 0; i < listeners.length; i++) {
final IProxyDistributionListener l = listeners[i];
SafeRunner.run(new ISafeRunnable() {
public void handleException(Throwable exception) {
logError(
"firePreRegister", //$NON-NLS-1$
"Exception calling proxy distribution listener", //$NON-NLS-1$
exception);
}
public void run() throws Exception {
l.registered(endpointDescription,
remoteServiceContainer,
remoteServiceReference, serviceRegistration);
}
});
}
}
}
}
private void fireUnregister(
final IRemoteServiceEndpointDescription endpointDescription,
final ServiceRegistration registration) {
Activator activator = Activator.getDefault();
if (activator != null) {
IProxyDistributionListener[] listeners = activator
.getProxyDistributionListeners();
if (listeners != null) {
for (int i = 0; i < listeners.length; i++) {
final IProxyDistributionListener l = listeners[i];
SafeRunner.run(new ISafeRunnable() {
public void handleException(Throwable exception) {
logError(
"fireUnregister", //$NON-NLS-1$
"Exception calling proxy distribution listener", //$NON-NLS-1$
exception);
}
public void run() throws Exception {
l.unregistered(endpointDescription, registration);
}
});
}
}
}
}
private RemoteServiceEndpointDescription getECFDescription(
ServiceEndpointDescription aServiceEndpointDesc) {
RemoteServiceEndpointDescription ecfSED;
if (!(aServiceEndpointDesc instanceof RemoteServiceEndpointDescription)) {
ecfSED = (RemoteServiceEndpointDescription) Activator
.getDefault()
.getAdapterManager()
.loadAdapter(aServiceEndpointDesc,
RemoteServiceEndpointDescription.class.getName());
} else
ecfSED = (RemoteServiceEndpointDescription) aServiceEndpointDesc;
return ecfSED;
}
private boolean findProxyServiceRegistration(
RemoteServiceEndpointDescription sed) {
synchronized (discoveredRemoteServiceRegistrations) {
for (Iterator i = discoveredRemoteServiceRegistrations.keySet()
.iterator(); i.hasNext();) {
ID containerID = (ID) i.next();
RemoteServiceRegistration reg = (RemoteServiceRegistration) discoveredRemoteServiceRegistrations
.get(containerID);
if (reg.hasRSED(sed))
return true;
}
return false;
}
}
private ServiceRegistration[] removeProxyServiceRegistrations(
RemoteServiceEndpointDescription sed) {
List results = new ArrayList();
synchronized (discoveredRemoteServiceRegistrations) {
final List containerIDsToRemove = new ArrayList();
for (Iterator i = discoveredRemoteServiceRegistrations.keySet()
.iterator(); i.hasNext();) {
ID containerID = (ID) i.next();
RemoteServiceRegistration reg = (RemoteServiceRegistration) discoveredRemoteServiceRegistrations
.get(containerID);
if (reg != null) {
ServiceRegistration sr = reg.removeServiceRegistration(sed);
if (sr != null)
results.add(sr);
if (reg.isEmpty()) {
reg.dispose();
containerIDsToRemove.add(containerID);
}
}
}
// Outside of the iterator, now remove any containerID found to
// match
for (Iterator i = containerIDsToRemove.iterator(); i.hasNext();) {
discoveredRemoteServiceRegistrations.remove(i.next());
}
return (ServiceRegistration[]) results
.toArray(new ServiceRegistration[] {});
}
}
class RemoteServiceReferenceUnregisteredListener implements
IRemoteServiceListener {
public void handleServiceEvent(IRemoteServiceEvent event) {
if (event instanceof IRemoteServiceUnregisteredEvent) {
ID containerID = event.getContainerID();
ID localContainerID = event.getLocalContainerID();
IRemoteServiceReference reference = event.getReference();
trace("handleRemoteServiceUnregisteredEvent", //$NON-NLS-1$
"localContainerID=" + localContainerID //$NON-NLS-1$
+ ",containerID=" + containerID //$NON-NLS-1$
+ ",remoteReference=" + reference); //$NON-NLS-1$
// Synchronize on serviceLocations so no other changes happen
// while
// this is going on...as it can be invoked by an arbitrary
RemoteServiceRegistration.RSEDAndSRAssoc[] assocs = null;
synchronized (serviceLocations) {
synchronized (discoveredRemoteServiceRegistrations) {
List containerIDsToRemove = new ArrayList();
RemoteServiceRegistration rsRegs = (RemoteServiceRegistration) discoveredRemoteServiceRegistrations
.get(localContainerID);
// If we've got any remote service registrations for the
// containerID
if (rsRegs != null) {
assocs = rsRegs
.removeServiceRegistration(reference);
// If this removes *all* references for this
// registration
if (rsRegs.isEmpty()) {
rsRegs.dispose();
containerIDsToRemove.add(localContainerID);
}
if (assocs != null) {
for (int i = 0; i < assocs.length; i++) {
removeDiscoveredServiceID(assocs[i]
.getRSED());
}
}
}
for (Iterator i = containerIDsToRemove.iterator(); i
.hasNext();) {
discoveredRemoteServiceRegistrations.remove(i
.next());
}
}
}
// Call this outside of synchronized block
if (assocs != null) {
for (int i = 0; i < assocs.length; i++) {
ServiceRegistration sr = assocs[i].getSR();
trace("handleRemoteServiceUnregisteredEvent.unregister", //$NON-NLS-1$
"localContainerID=" //$NON-NLS-1$
+ localContainerID + ",containerID=" //$NON-NLS-1$
+ containerID + ",remoteReference=" //$NON-NLS-1$
+ reference + ",proxyServiceRegistrations=" //$NON-NLS-1$
+ sr);
unregisterProxyServiceRegistration(assocs[i].getRSED(),
sr);
}
}
}
}
}
private void unregisterProxyServiceRegistration(
IRemoteServiceEndpointDescription endpointDescription,
ServiceRegistration reg) {
try {
distributionProvider.removeRemoteService(reg.getReference());
reg.unregister();
} catch (IllegalStateException e) {
// Ignore
logWarning("unregisterProxyServiceRegistration", //$NON-NLS-1$
"Exception unregistering serviceRegistration=" + reg); //$NON-NLS-1$
} catch (Exception e) {
logError("unregisterProxyServiceRegistration", //$NON-NLS-1$
"Exception unregistering serviceRegistration=" + reg, e); //$NON-NLS-1$
}
fireUnregister(endpointDescription, reg);
}
private void registerRemoteServiceReferences(
RemoteServiceEndpointDescription sed,
IRemoteServiceContainer remoteServiceContainer,
IRemoteServiceReference[] remoteReferences) {
synchronized (serviceLocations) {
// check to make sure that this serviceLocation
// is still present
if (!containsDiscoveredServiceID(sed)) {
logError("registerRemoteServiceReferences", "serviceLocation=" //$NON-NLS-1$ //$NON-NLS-2$
+ sed + " no longer present", null); //$NON-NLS-1$
return;
}
// check to make sure that the proxy service registry is not
// already there
if (findProxyServiceRegistration(sed)) {
logError("registerRemoteServiceReferences", //$NON-NLS-1$
"serviceEndpointDesc=" + sed //$NON-NLS-1$
+ " previously registered locally...ignoring", //$NON-NLS-1$
null);
return;
}
// Then get/setup remote service
for (int i = 0; i < remoteReferences.length; i++) {
// Get IRemoteService, used to create the proxy
IRemoteService remoteService = remoteServiceContainer
.getContainerAdapter().getRemoteService(
remoteReferences[i]);
// If no remote service then give up
if (remoteService == null) {
logError("registerRemoteServiceReferences", //$NON-NLS-1$
"Remote service is null for remote reference " //$NON-NLS-1$
+ remoteReferences[i], null);
continue;
}
// Get classes to register for remote service
String[] clazzes = (String[]) remoteReferences[i]
.getProperty(Constants.OBJECTCLASS);
if (clazzes == null || clazzes.length == 0) {
logError("registerRemoteServiceReferences", //$NON-NLS-1$
"No classes specified for remote service reference " //$NON-NLS-1$
+ remoteReferences[i], null);
continue;
}
// Get service properties for the proxy registration
Dictionary properties = getPropertiesForRemoteService(sed,
remoteServiceContainer, remoteReferences[i],
remoteService);
// Create proxy right here
Object proxy = null;
try {
proxy = remoteService.getProxy();
if (proxy == null) {
logError("registerRemoteServiceReferences", //$NON-NLS-1$
"Remote service proxy is null", null); //$NON-NLS-1$
continue;
}
// Fire pre register notification fir
// IProxyDistributionListener
firePreRegister(sed, remoteServiceContainer,
remoteReferences[i]);
trace("registerRemoteServiceReferences", "rsca=" //$NON-NLS-1$ //$NON-NLS-2$
+ remoteServiceContainer + ",remoteReference=" //$NON-NLS-1$
+ remoteReferences[i]);
// Actually register proxy here
ServiceRegistration registration = Activator.getDefault()
.getContext()
.registerService(clazzes, proxy, properties);
RemoteServiceRegistration reg = getProxyServiceRegistration(remoteServiceContainer);
reg.addServiceRegistration(remoteReferences[i], sed,
registration);
// And add to distribution provider
distributionProvider.addRemoteService(registration
.getReference());
trace("addLocalServiceRegistration.COMPLETE", //$NON-NLS-1$
"containerHelper=" + remoteServiceContainer //$NON-NLS-1$
+ ",remoteServiceReference=" //$NON-NLS-1$
+ remoteReferences[i]
+ ",localServiceRegistration=" //$NON-NLS-1$
+ registration);
// Fire IProxyDistributionListener to notify we're done
firePostRegister(sed, remoteServiceContainer,
remoteReferences[i], registration);
} catch (Exception e) {
logError("registerRemoteServiceReferences", //$NON-NLS-1$
"Exception creating or registering remote reference " //$NON-NLS-1$
+ remoteReferences[i], e);
continue;
}
}
}
}
private RemoteServiceRegistration getProxyServiceRegistration(
IRemoteServiceContainer rsContainer) {
ID localContainerID = rsContainer.getContainer().getID();
synchronized (discoveredRemoteServiceRegistrations) {
RemoteServiceRegistration reg = (RemoteServiceRegistration) discoveredRemoteServiceRegistrations
.get(localContainerID);
// If there is none, then create one
if (reg == null) {
reg = new RemoteServiceRegistration(rsContainer,
new RemoteServiceReferenceUnregisteredListener());
discoveredRemoteServiceRegistrations.put(localContainerID, reg);
}
return reg;
}
}
private boolean isRemoteServiceProperty(String propertyKey) {
return ecfRemoteServiceProperties.contains(propertyKey);
}
private Dictionary getPropertiesForRemoteService(
RemoteServiceEndpointDescription rsEndpointDescription,
IRemoteServiceContainer rsContainer,
IRemoteServiceReference rsReference, IRemoteService remoteService) {
Properties props = new Properties();
// Add the required 'service.imported' property, which for ECF rs
// providers
// exposes the IRemoteService
props.put(IDistributionConstants.SERVICE_IMPORTED, remoteService);
// Add service intents...if not null (optional property)
String[] serviceIntents = rsEndpointDescription.getServiceIntents();
if (serviceIntents != null)
props.put(IDistributionConstants.SERVICE_INTENTS, serviceIntents);
// Then add all other service properties
String[] propKeys = rsReference.getPropertyKeys();
for (int i = 0; i < propKeys.length; i++) {
if (!isRemoteServiceProperty(propKeys[i])) {
props.put(propKeys[i], rsReference.getProperty(propKeys[i]));
}
}
// make the service identifiable by consumers
// especially org.eclipse.ecf.remoteservice.ui.dosgi
final ID endpointId = (ID) rsReference
.getProperty(org.eclipse.ecf.remoteservice.Constants.SERVICE_CONTAINER_ID);
final Long serviceId = (Long) rsReference
.getProperty(org.eclipse.ecf.remoteservice.Constants.SERVICE_ID);
props.put(ServicePublication.ENDPOINT_ID, endpointId + "#" + serviceId); //$NON-NLS-1$
// finally add service.imported.configs
addImportedConfigsProperties(
getContainerTypeDescription(rsContainer.getContainer()),
rsEndpointDescription.getSupportedConfigs(), props);
return props;
}
private void addImportedConfigsProperties(
ContainerTypeDescription containerTypeDescription,
String[] remoteExportedConfigs, Dictionary exportedProperties) {
if (containerTypeDescription == null)
return;
if (remoteExportedConfigs != null) {
String[] importedConfigs = containerTypeDescription
.getImportedConfigs(remoteExportedConfigs);
if (importedConfigs != null) {
// Add the service.imported.configs property
exportedProperties.put(
IDistributionConstants.SERVICE_IMPORTED_CONFIGS,
importedConfigs);
// First get any/all properties to add
Dictionary localConfigProperties = containerTypeDescription
.getPropertiesForImportedConfigs(importedConfigs,
exportedProperties);
if (localConfigProperties != null) {
for (Enumeration e = localConfigProperties.keys(); e
.hasMoreElements();) {
String key = (String) e.nextElement();
exportedProperties.put(key,
localConfigProperties.get(key));
}
}
}
}
}
protected ContainerTypeDescription getContainerTypeDescription(
IContainer container) {
IContainerManager containerManager = getContainerManager();
if (containerManager == null)
return null;
return containerManager.getContainerTypeDescription(container.getID());
}
protected IContainerManager getContainerManager() {
Activator activator = Activator.getDefault();
if (activator == null)
return null;
return activator.getContainerManager();
}
private boolean addDiscoveredServiceID(RemoteServiceEndpointDescription desc) {
synchronized (serviceLocations) {
return serviceLocations.add(desc);
}
}
private boolean removeDiscoveredServiceID(
RemoteServiceEndpointDescription desc) {
synchronized (serviceLocations) {
return serviceLocations.remove(desc);
}
}
private boolean containsDiscoveredServiceID(
RemoteServiceEndpointDescription desc) {
synchronized (serviceLocations) {
return serviceLocations.contains(desc);
}
}
protected void trace(String methodName, String message) {
LogUtility.trace(methodName, DebugOptions.DISCOVEREDSERVICETRACKER,
this.getClass(), message);
}
protected void traceException(String methodName, String message, Throwable t) {
LogUtility.traceException(methodName, DebugOptions.EXCEPTIONS_CATCHING,
this.getClass(), message, t);
}
protected void logError(String methodName, String message, Throwable t) {
LogUtility.logError(methodName, DebugOptions.DISCOVEREDSERVICETRACKER,
this.getClass(), message, t);
}
protected void logError(String methodName, String message) {
LogUtility.logError(methodName, DebugOptions.DISCOVEREDSERVICETRACKER,
this.getClass(), message);
}
protected void logWarning(String methodName, String message) {
LogUtility
.logWarning(methodName, DebugOptions.DISCOVEREDSERVICETRACKER,
this.getClass(), message);
}
private boolean isValidDescription(
RemoteServiceEndpointDescription rsEndpointDescription) {
if (rsEndpointDescription == null)
return false;
synchronized (serviceLocations) {
if (containsDiscoveredServiceID(rsEndpointDescription)) {
return false;
} else {
addDiscoveredServiceID(rsEndpointDescription);
return true;
}
}
}
private IRemoteServiceContainer[] findProxyContainers(
final RemoteServiceEndpointDescription rsEndpointDescription) {
// Get activator
Activator activator = Activator.getDefault();
if (activator == null)
return null;
// Get finder (as service)
IProxyContainerFinder finder = activator
.getProxyRemoteServiceContainerFinder();
if (finder == null) {
logError("findRemoteServiceContainersViaService", //$NON-NLS-1$
"No container finders available"); //$NON-NLS-1$
return null;
}
return finder.findProxyContainers(rsEndpointDescription.getServiceID(),
rsEndpointDescription);
}
}