blob: 7042ccf8e862de2529b1886343414864e2918e36 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010 Markus Alexander Kuppe.
* 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 (ecf-dev_eclipse.org <at> lemmster <dot> de) - initial API and implementation
******************************************************************************/
package org.eclipse.ecf.internal.discovery;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.ecf.core.identity.*;
import org.eclipse.ecf.core.util.StringUtils;
import org.eclipse.ecf.discovery.*;
import org.eclipse.ecf.discovery.identity.*;
import org.osgi.framework.*;
public class DiscoveryServiceListener implements ServiceListener {
private final AbstractDiscoveryContainerAdapter discoveryContainer;
private final Class listenerClass;
private final BundleContext context;
private final IServiceIDFactory idFactory;
private final Namespace discoveryNamespace;
public DiscoveryServiceListener(
AbstractDiscoveryContainerAdapter anAbstractDiscoveryContainerAdapter,
Class clazz) {
discoveryContainer = anAbstractDiscoveryContainerAdapter;
listenerClass = clazz;
discoveryNamespace = IDFactory.getDefault().getNamespaceByName(
DiscoveryNamespace.NAME);
idFactory = ServiceIDFactory.getDefault();
context = DiscoveryPlugin.getDefault().getBundleContext();
try {
// get existing listener
final ServiceReference[] references = context.getServiceReferences(
listenerClass.getName(), null);
addServiceListener(references);
// listen for more listeners
context.addServiceListener(this, getFilter());
} catch (InvalidSyntaxException e) {
DiscoveryPlugin.getDefault().log(
new Status(IStatus.ERROR, DiscoveryPlugin.PLUGIN_ID,
IStatus.ERROR, "Cannot create filter", e)); //$NON-NLS-1$
}
}
public void dispose() {
if (!DiscoveryPlugin.isStopped()) {
context.removeServiceListener(this);
}
}
private void addServiceListener(ServiceReference[] references) {
if (references == null) {
return;
}
for (int i = 0; i < references.length; i++) {
final ServiceReference serviceReference = references[i];
if (listenerClass.getName()
.equals(IServiceListener.class.getName())) {
if (isAllWildcards(serviceReference)) {
final IServiceListener aListener = (IServiceListener) context
.getService(serviceReference);
discoveryContainer.addServiceListener(aListener);
} else {
final IServiceTypeID aType = getIServiceTypeID(serviceReference);
if (aType == null) {
continue;
}
final IServiceListener aListener = (IServiceListener) context
.getService(serviceReference);
discoveryContainer.addServiceListener(aType, aListener);
}
} else {
final IServiceTypeListener aListener = (IServiceTypeListener) context
.getService(serviceReference);
discoveryContainer.addServiceTypeListener(aListener);
}
}
}
private void addServiceListener(ServiceReference reference) {
addServiceListener(new ServiceReference[] { reference });
}
private void removeServiceListener(ServiceReference[] references) {
if (references == null) {
return;
}
for (int i = 0; i < references.length; i++) {
final ServiceReference serviceReference = references[i];
if (listenerClass.getName()
.equals(IServiceListener.class.getName())) {
if (isAllWildcards(serviceReference)) {
final IServiceListener aListener = (IServiceListener) context
.getService(serviceReference);
discoveryContainer.removeServiceListener(aListener);
} else {
final IServiceTypeID aType = getIServiceTypeID(serviceReference);
if (aType == null) {
continue;
}
final IServiceListener aListener = (IServiceListener) context
.getService(serviceReference);
discoveryContainer.removeServiceListener(aType, aListener);
}
} else {
final IServiceTypeListener aListener = (IServiceTypeListener) context
.getService(serviceReference);
discoveryContainer.removeServiceTypeListener(aListener);
}
}
}
private void removeServiceListener(ServiceReference reference) {
removeServiceListener(new ServiceReference[] { reference });
}
private boolean isAllWildcards(ServiceReference serviceReference) {
return serviceReference
.getProperty("org.eclipse.ecf.discovery.namingauthority") == null
&& serviceReference
.getProperty("org.eclipse.ecf.discovery.services") == null
&& serviceReference
.getProperty("org.eclipse.ecf.discovery.scopes") == null
&& serviceReference
.getProperty("org.eclipse.ecf.discovery.protocols") == null;
}
private IServiceTypeID getIServiceTypeID(ServiceReference serviceReference) {
String namingAuthority = (String) serviceReference
.getProperty("org.eclipse.ecf.discovery.namingauthority"); //$NON-NLS-1$
if (namingAuthority == null) {
namingAuthority = "*"; //$NON-NLS-1$
}
try {
final IServiceTypeID createServiceTypeID = idFactory
.createServiceTypeID(
discoveryNamespace,
convert(serviceReference,
"org.eclipse.ecf.discovery.services"), //$NON-NLS-1$
convert(serviceReference,
"org.eclipse.ecf.discovery.scopes"), //$NON-NLS-1$
convert(serviceReference,
"org.eclipse.ecf.discovery.protocols"), //$NON-NLS-1$
namingAuthority);
return createServiceTypeID;
} catch (final IDCreateException e) {
return null;
}
}
private String[] convert(ServiceReference serviceReference, String key) {
final Object value = serviceReference.getProperty(key);
// default to wildcard for non-set values
if (value == null) {
return new String[] { "*" }; //$NON-NLS-1$
} else if (value instanceof String[]) {
return (String[]) value;
}
return StringUtils.split((String) value, "._"); //$NON-NLS-1$
}
/*
* (non-Javadoc)
*
* @see
* org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.
* ServiceEvent)
*/
public void serviceChanged(ServiceEvent event) {
// ignore events that are targeted at different discovery containers
final Object containerName = event.getServiceReference().getProperty(
IDiscoveryLocator.CONTAINER_NAME);
if (!discoveryContainer.getContainerName().equals(containerName)) {
return;
}
switch (event.getType()) {
case ServiceEvent.REGISTERED:
addServiceListener(event.getServiceReference());
break;
case ServiceEvent.UNREGISTERING:
removeServiceListener(event.getServiceReference());
break;
default:
break;
}
}
private String getFilter() {
return "(" + Constants.OBJECTCLASS + "=" + listenerClass.getName() //$NON-NLS-1$ //$NON-NLS-2$
+ ")"; //$NON-NLS-1$
}
}