| /******************************************************************************* |
| * Copyright (c) 2013 Markus Alexander Kuppe 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: |
| * Markus Alexander Kuppe - initial API and implementation |
| ******************************************************************************/ |
| package org.eclipse.ecf.internal.discovery; |
| |
| import org.eclipse.ecf.core.identity.Namespace; |
| import org.eclipse.ecf.discovery.*; |
| import org.eclipse.ecf.discovery.identity.*; |
| import org.osgi.framework.BundleContext; |
| import org.osgi.framework.ServiceReference; |
| import org.osgi.util.tracker.ServiceTracker; |
| import org.osgi.util.tracker.ServiceTrackerCustomizer; |
| |
| /** |
| * An IServiceInfoServiceListener is a whiteboard pattern listener responsible |
| * to handle IServiceInfos registered in the OSGi service registry. |
| */ |
| public class IServiceInfoServiceListener { |
| |
| private final ServiceTracker serviceTracker; |
| |
| public IServiceInfoServiceListener(final IDiscoveryAdvertiser advertiser) { |
| final BundleContext bundleContext = DiscoveryPlugin.getDefault() |
| .getBundleContext(); |
| serviceTracker = new ServiceTracker(bundleContext, IServiceInfo.class, |
| new ServiceTrackerCustomizer() { |
| |
| public Object addingService(ServiceReference reference) { |
| final IServiceInfo serviceInfo = (IServiceInfo) bundleContext |
| .getService(reference); |
| final IServiceInfo specific = convertToProviderSpecific( |
| advertiser, serviceInfo); |
| if (advertiser instanceof AbstractDiscoveryContainerAdapter) { |
| AbstractDiscoveryContainerAdapter adca = (AbstractDiscoveryContainerAdapter) advertiser; |
| if (adca.getConnectedID() == null) |
| return null; |
| } |
| advertiser.registerService(specific); |
| return serviceInfo; |
| } |
| |
| public void modifiedService(ServiceReference reference, |
| Object service) { |
| // TODO discovery containers might require to |
| // unregisterService first |
| advertiser.registerService(convertToProviderSpecific( |
| advertiser, (IServiceInfo) service)); |
| } |
| |
| public void removedService(ServiceReference reference, |
| Object service) { |
| advertiser.unregisterService(convertToProviderSpecific( |
| advertiser, (IServiceInfo) service)); |
| } |
| }); |
| serviceTracker.open(); |
| } |
| |
| /** |
| * Converts the generic (not discovery provider specific WRT |
| * IServiceID/IServiceTypeID) IServiceInfo into a discovery provider |
| * specific one. This is required so that discovery providers can correctly |
| * advertise services. |
| */ |
| private IServiceInfo convertToProviderSpecific( |
| final IDiscoveryAdvertiser advertiser, |
| final IServiceInfo genericInfo) { |
| |
| // Convert similar to |
| // org.eclipse.ecf.provider.discovery.CompositeDiscoveryContainer.getServiceIDForDiscoveryContainer(IServiceID, |
| // IDiscoveryLocator) |
| final Namespace servicesNamespace = advertiser.getServicesNamespace(); |
| |
| final IServiceID genericServiceID = genericInfo.getServiceID(); |
| final ServiceID specificServiceID = (ServiceID) servicesNamespace |
| .createInstance(new Object[] { |
| genericServiceID.getServiceTypeID().getName(), |
| genericServiceID.getLocation() }); |
| |
| final IServiceTypeID serviceTypeID = specificServiceID |
| .getServiceTypeID(); |
| |
| return new ServiceInfo(genericServiceID.getLocation(), |
| genericInfo.getServiceName(), serviceTypeID, |
| genericInfo.getPriority(), genericInfo.getWeight(), |
| genericInfo.getServiceProperties()); |
| } |
| |
| public void dispose() { |
| serviceTracker.close(); |
| } |
| } |