blob: 37bacc71c9bf3c885c99b0999423130bf2a8cbac [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2006 IBM Corporation 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.equinox.metatype;
import java.util.ArrayList;
import org.osgi.framework.*;
import org.osgi.service.cm.ManagedServiceFactory;
import org.osgi.service.metatype.*;
import org.osgi.util.tracker.ServiceTracker;
public class MetaTypeProviderTracker implements MetaTypeInformation {
public static final String MANAGED_SERVICE = "org.osgi.service.cm.ManagedService"; //$NON-NLS-1$
public static final String MANAGED_SERVICE_FACTORY = "org.osgi.service.cm.ManagedServiceFactory"; //$NON-NLS-1$
public static final String FILTER_STRING = "(|(" + Constants.OBJECTCLASS + '=' + MANAGED_SERVICE + ")(" + Constants.OBJECTCLASS + '=' + MANAGED_SERVICE_FACTORY + "))"; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
Bundle _bundle;
BundleContext _context;
ServiceTracker _tracker;
/**
* Constructs a MetaTypeProviderTracker which tracks all MetaTypeProviders
* registered by the specified bundle.
* @param context The BundleContext of the MetaTypeService implementation
* @param bundle The bundle to track all MetaTypeProviders for.
*/
public MetaTypeProviderTracker(BundleContext context, Bundle bundle) {
this._context = context;
this._bundle = bundle;
// create a filter for ManagedService and ManagedServiceFactory services
try {
Filter filter = context.createFilter(FILTER_STRING);
// create a service tracker and open it.
this._tracker = new ServiceTracker(context, filter, null);
// we never close this, but it is no big deal because we
// really want to track the services until we are stopped
// at that point the framework will remove our listeners.
this._tracker.open();
} catch (InvalidSyntaxException e) {
// This should never happen; it means we have a bug in the filterString
e.printStackTrace();
throw new IllegalArgumentException(FILTER_STRING);
}
}
private String[] getPids(boolean factory) {
if (_bundle.getState() != Bundle.ACTIVE)
return new String[0]; // return none if not active
MetaTypeProviderWrapper[] wrappers = getMetaTypeProviders();
ArrayList results = new ArrayList();
for (int i = 0; i < wrappers.length; i++) {
// return only the correct type of pids (regular or factory)
if (factory == wrappers[i].factory)
results.add(wrappers[i].pid);
}
return (String[]) results.toArray(new String[results.size()]);
}
public String[] getPids() {
return getPids(false);
}
public String[] getFactoryPids() {
return getPids(true);
}
public Bundle getBundle() {
return _bundle;
}
public ObjectClassDefinition getObjectClassDefinition(String id, String locale) {
if (_bundle.getState() != Bundle.ACTIVE)
return null; // return none if not active
MetaTypeProviderWrapper[] wrappers = getMetaTypeProviders();
for (int i = 0; i < wrappers.length; i++) {
if (id.equals(wrappers[i].pid))
// found a matching pid now call the actual provider
return wrappers[i].provider.getObjectClassDefinition(id, locale);
}
return null;
}
public String[] getLocales() {
if (_bundle.getState() != Bundle.ACTIVE)
return new String[0]; // return none if not active
MetaTypeProviderWrapper[] wrappers = getMetaTypeProviders();
ArrayList locales = new ArrayList();
// collect all the unique locales from all providers we found
for (int i = 0; i < wrappers.length; i++) {
String[] wrappedLocales = wrappers[i].provider.getLocales();
if (wrappedLocales == null)
continue;
for (int j = 0; j < wrappedLocales.length; j++)
if (!locales.contains(wrappedLocales[j]))
locales.add(wrappedLocales[j]);
}
return (String[]) locales.toArray(new String[locales.size()]);
}
private MetaTypeProviderWrapper[] getMetaTypeProviders() {
ServiceReference[] refs = _tracker.getServiceReferences();
if (refs == null)
return new MetaTypeProviderWrapper[0];
ArrayList results = new ArrayList();
for (int i = 0; i < refs.length; i++)
// search for services registered by the bundle
if (refs[i].getBundle() == _bundle) {
Object service = _context.getService(refs[i]);
if (service instanceof MetaTypeProvider) {
// found one that implements MetaTypeProvider
// wrap its information in a MetaTypeProviderWrapper
String pid = (String) refs[i].getProperty(Constants.SERVICE_PID);
boolean factory = service instanceof ManagedServiceFactory;
results.add(new MetaTypeProviderWrapper((MetaTypeProvider) service, pid, factory));
}
// always unget a service.
// this leaves us open for the the service going away but who cares.
// we only use the service for a short period of time.
_context.ungetService(refs[i]);
}
return (MetaTypeProviderWrapper[]) results.toArray(new MetaTypeProviderWrapper[results.size()]);
}
// this is a simple class just used to temporarily store information about a provider
public class MetaTypeProviderWrapper {
MetaTypeProvider provider;
String pid;
boolean factory;
MetaTypeProviderWrapper(MetaTypeProvider provider, String pid, boolean factory) {
this.provider = provider;
this.pid = pid;
this.factory = factory;
}
}
}