Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Copyright (c) 2004, 2010 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.osgi.internal.serviceregistry;
  
  import java.security.*;
  import java.util.*;
The Service Registry. This class is the main control point for service layer operations in the framework.

ThreadSafe:
  
  public class ServiceRegistry {
  	public static final int SERVICEEVENT = 3;
  
  	private static final String findHookName = FindHook.class.getName();
  	private static final String eventHookName = EventHook.class.getName();
  	private static final String listenerHookName = ListenerHook.class.getName();

Published services by class name. Map<String,List<ServiceRegistrationImpl>> The List<ServiceRegistrationImpl>s are sorted.
  
  	/* @GuardedBy("this") */
  	private final Map/*<String,List<ServiceRegistrationImpl>>*/publishedServicesByClass;
All published services. List<ServiceRegistrationImpl>. The List<ServiceRegistrationImpl>s are sorted.
  
  	/* @GuardedBy("this") */
  	private final List/*<ServiceRegistrationImpl>*/allPublishedServices;
Published services by BundleContextImpl. Map<BundleContextImpl,List<ServiceRegistrationImpl>>. The List<ServiceRegistrationImpl>s are NOT sorted.
  
  	/* @GuardedBy("this") */
  	private final Map/*<BundleContextImpl,List<ServiceRegistrationImpl>>*/publishedServicesByContext;
next free service id.
  
  	/* @GuardedBy("this") */
  	private long serviceid;
Active Service Listeners. Map<BundleContextImpl,CopyOnWriteIdentityMap<ServiceListener,FilteredServiceListener>>.
  
  	/* @GuardedBy("serviceEventListeners") */
  	private final Map/*<BundleContextImpl,CopyOnWriteIdentityMap<ServiceListener,FilteredServiceListener>>*/serviceEventListeners;

initial capacity of the main data structure
  
  	private static final int initialCapacity = 50;
initial capacity of the nested data structure
  
  	private static final int initialSubCapacity = 10;
framework which created this service registry
  
  	private final Framework framework;

Initializes the internal data structures of this ServiceRegistry.
  
  	public ServiceRegistry(Framework framework) {
  		this. = framework;
  		 = 1;
  	}

Registers the specified service object with the specified properties under the specified class names into the Framework. A ServiceRegistrationImpl object is returned. The ServiceRegistrationImpl object is for the private use of the bundle registering the service and should not be shared with other bundles. The registering bundle is defined to be the context bundle. Other bundles can locate the service by using either the getServiceReferences(org.eclipse.osgi.framework.internal.core.BundleContextImpl,java.lang.String,java.lang.String,boolean) or getServiceReference(org.eclipse.osgi.framework.internal.core.BundleContextImpl,java.lang.String) method.

A bundle can register a service object that implements the org.osgi.framework.ServiceFactory interface to have more flexibility in providing service objects to other bundles.

The following steps are required to register a service:

  1. If service is not a ServiceFactory, an IllegalArgumentException is thrown if service is not an instanceof all the classes named.
  2. The Framework adds these service properties to the specified Dictionary (which may be null): a property named org.osgi.framework.Constants.SERVICE_ID identifying the registration number of the service and a property named org.osgi.framework.Constants.OBJECTCLASS containing all the specified classes. If any of these properties have already been specified by the registering bundle, their values will be overwritten by the Framework.
  3. The service is added to the Framework service registry and may now be used by other bundles.
  4. A service event of type org.osgi.framework.ServiceEvent.REGISTERED is fired.
  5. A ServiceRegistration object for this registration is returned.

Parameters:
context The BundleContext of the registering bundle.
clazzes The class names under which the service can be located. The class names in this array will be stored in the service's properties under the key org.osgi.framework.Constants.OBJECTCLASS.
service The service object or a ServiceFactory object.
properties The properties for this service. The keys in the properties object must all be String objects. See org.osgi.framework.Constants for a list of standard service property keys. Changes should not be made to this object after calling this method. To update the service's properties the org.osgi.framework.ServiceRegistration.setProperties(java.util.Dictionary) method must be called. The set of properties may be null if the service has no properties.
Returns:
A ServiceRegistrationImpl object for use by the bundle registering the service to update the service's properties or to unregister the service.
Throws:
java.lang.IllegalArgumentException If one of the following is true:
  • service is null.
  • service is not a ServiceFactory object and is not an instance of all the named classes in clazzes.
  • properties contains case variants of the same key name.
java.lang.SecurityException If the caller does not have the ServicePermission to register the service for all the named classes and the Java Runtime Environment supports permissions.
java.lang.IllegalStateException If this BundleContext is no longer valid.
See also:
org.osgi.framework.ServiceRegistration
org.osgi.framework.ServiceFactory
 
 	public ServiceRegistrationImpl registerService(BundleContextImpl contextString[] clazzesObject serviceDictionary properties) {
 		if (service == null) {
 				Debug.println("Service object is null"); //$NON-NLS-1$
 			}
 
 		}
 
 		int size = clazzes.length;
 
 		if (size == 0) {
 				Debug.println("Classes array is empty"); //$NON-NLS-1$
 			}
 
 		}
 
 		/* copy the array so that changes to the original will not affect us. */
 		List copy = new ArrayList(size);
 		// intern the strings and remove duplicates
 		for (int i = 0; i < sizei++) {
 			String clazz = clazzes[i].intern();
 			if (!copy.contains(clazz)) {
 				copy.add(clazz);
 			}
 		}
 		size = copy.size();
 		clazzes = (String[]) copy.toArray(new String[size]);
 
 		/* check for ServicePermissions. */
 
 		if (!(service instanceof ServiceFactory)) {
 			String invalidService = checkServiceClass(clazzesservice);
 			if (invalidService != null) {
 					Debug.println("Service object is not an instanceof " + invalidService); //$NON-NLS-1$
 				}
 			}
 		}
 
 		ServiceRegistrationImpl registration = new ServiceRegistrationImpl(thiscontextclazzesservice);
 		registration.register(properties);
 		if (copy.contains()) {
 			notifyNewListenerHook(registration);
 		}
 		return registration;
 	}

Returns an array of ServiceReferenceImpl objects. The returned array of ServiceReferenceImpl objects contains services that were registered under the specified class, match the specified filter criteria, and the packages for the class names under which the services were registered match the context bundle's packages as defined in org.osgi.framework.ServiceReference.isAssignableTo(org.osgi.framework.Bundle,java.lang.String).

The list is valid at the time of the call to this method, however since the Framework is a very dynamic environment, services can be modified or unregistered at anytime.

filter is used to select the registered service whose properties objects contain keys and values which satisfy the filter. See org.osgi.framework.Filter for a description of the filter string syntax.

If filter is null, all registered services are considered to match the filter. If filter cannot be parsed, an org.osgi.framework.InvalidSyntaxException will be thrown with a human readable message where the filter became unparsable.

The following steps are required to select a set of ServiceReferenceImpl objects:

  1. If the filter string is not null, the filter string is parsed and the set ServiceReferenceImpl objects of registered services that satisfy the filter is produced. If the filter string is null, then all registered services are considered to satisfy the filter.
  2. If the Java Runtime Environment supports permissions, the set of ServiceReferenceImpl objects produced by the previous step is reduced by checking that the caller has the ServicePermission to get at least one of the class names under which the service was registered. If the caller does not have the correct permission for a particular ServiceReferenceImpl object, then it is removed from the set.
  3. If clazz is not null, the set is further reduced to those services that are an instanceof and were registered under the specified class. The complete list of classes of which a service is an instance and which were specified when the service was registered is available from the service's org.osgi.framework.Constants.OBJECTCLASS property.
  4. The set is reduced one final time by cycling through each ServiceReference object and calling org.osgi.framework.ServiceReference.isAssignableTo(org.osgi.framework.Bundle,java.lang.String) with the context bundle and each class name under which the ServiceReference object was registered. For any given ServiceReferenceImpl object, if any call to org.osgi.framework.ServiceReference.isAssignableTo(org.osgi.framework.Bundle,java.lang.String) returns false, then it is removed from the set of ServiceReferenceImpl objects.
  5. An array of the remaining ServiceReferenceImpl objects is returned.

Parameters:
context The BundleContext of the requesting bundle.
clazz The class name with which the service was registered or null for all services.
filterstring The filter criteria.
allservices True if the bundle called getAllServiceReferences.
Returns:
An array of ServiceReferenceImpl objects or null if no services are registered which satisfy the search.
Throws:
org.osgi.framework.InvalidSyntaxException If filter contains an invalid filter string that cannot be parsed.
java.lang.IllegalStateException If this BundleContext is no longer valid.
 
 	public ServiceReferenceImpl[] getServiceReferences(final BundleContextImpl contextfinal String clazzfinal String filterstringfinal boolean allservicesthrows InvalidSyntaxException {
 			Debug.println((allservices ? "getAllServiceReferences(" : "getServiceReferences(") + clazz + ", \"" + filterstring + "\")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
 		}
 		Filter filter = (filterstring == null) ? null : context.createFilter(filterstring);
 		for (Iterator iter = references.iterator(); iter.hasNext();) {
 			if (allservices || isAssignableTo(contextreference)) {
 				try { /* test for permission to get the service */
 				} catch (SecurityException se) {
 					iter.remove();
 				}
 			} else {
 				iter.remove();
 			}
 		}
 
 		final Collection shrinkable = new ShrinkableCollection(references);
 		notifyFindHooks(contextclazzfilterstringallservicesshrinkable);
 
 		int size = references.size();
 		if (size == 0) {
 			return null;
 		}
 		return (ServiceReferenceImpl[]) references.toArray(new ServiceReferenceImpl[size]);
 	}

Returns a ServiceReference object for a service that implements and was registered under the specified class.

This ServiceReference object is valid at the time of the call to this method, however as the Framework is a very dynamic environment, services can be modified or unregistered at anytime.

This method is the same as calling org.osgi.framework.BundleContext.getServiceReferences(java.lang.String,java.lang.String) with a null filter string. It is provided as a convenience for when the caller is interested in any service that implements the specified class.

If multiple such services exist, the service with the highest ranking (as specified in its org.osgi.framework.Constants.SERVICE_RANKING property) is returned.

If there is a tie in ranking, the service with the lowest service ID (as specified in its org.osgi.framework.Constants.SERVICE_ID property); that is, the service that was registered first is returned.

Parameters:
context The BundleContext of the requesting bundle.
clazz The class name with which the service was registered.
Returns:
A ServiceReference object, or null if no services are registered which implement the named class.
Throws:
java.lang.IllegalStateException If this BundleContext is no longer valid.
 
 			Debug.println("getServiceReference(" + clazz + ")"); //$NON-NLS-1$ //$NON-NLS-2$
 		}
 
 		try {
 			ServiceReferenceImpl[] references = getServiceReferences(contextclazznullfalse);
 
 			if (references != null) {
 				// Since we maintain the registrations in a sorted List, the first element is always the
 				// correct one to return.
 				return references[0];
 			}
 		} catch (InvalidSyntaxException e) {
 				Debug.println("InvalidSyntaxException w/ null filter" + e.getMessage()); //$NON-NLS-1$
 				Debug.printStackTrace(e);
 			}
 		}
 
 		return null;
 	}

Returns the specified service object for a service.

A bundle's use of a service is tracked by the bundle's use count of that service. Each time a service's service object is returned by getService(org.eclipse.osgi.framework.internal.core.BundleContextImpl,org.eclipse.osgi.internal.serviceregistry.ServiceReferenceImpl) the context bundle's use count for that service is incremented by one. Each time the service is released by ungetService(org.eclipse.osgi.framework.internal.core.BundleContextImpl,org.eclipse.osgi.internal.serviceregistry.ServiceReferenceImpl) the context bundle's use count for that service is decremented by one.

When a bundle's use count for a service drops to zero, the bundle should no longer use that service.

This method will always return null when the service associated with this reference has been unregistered.

The following steps are required to get the service object:

  1. If the service has been unregistered, null is returned.
  2. The context bundle's use count for this service is incremented by one.
  3. If the context bundle's use count for the service is currently one and the service was registered with an object implementing the ServiceFactory interface, the org.osgi.framework.ServiceFactory.getService(org.osgi.framework.Bundle,org.osgi.framework.ServiceRegistration) method is called to create a service object for the context bundle. This service object is cached by the Framework. While the context bundle's use count for the service is greater than zero, subsequent calls to get the services's service object for the context bundle will return the cached service object.
    If the service object returned by the ServiceFactory object is not an instanceof all the classes named when the service was registered or the ServiceFactory object throws an exception, null is returned and a Framework event of type org.osgi.framework.FrameworkEvent.ERROR containing a org.osgi.framework.ServiceException describing the error is fired.
  4. The service object for the service is returned.

Parameters:
context The BundleContext of the requesting bundle.
reference A reference to the service.
Returns:
A service object for the service associated with reference or null if the service is not registered, the service object returned by a ServiceFactory does not implement the classes under which it was registered or the ServiceFactory threw an exception.
Throws:
java.lang.SecurityException If the caller does not have the ServicePermission to get the service using at least one of the named classes the service was registered under and the Java Runtime Environment supports permissions.
java.lang.IllegalStateException If this BundleContext is no longer valid.
See also:
ungetService(org.eclipse.osgi.framework.internal.core.BundleContextImpl,org.eclipse.osgi.internal.serviceregistry.ServiceReferenceImpl)
org.osgi.framework.ServiceFactory
 
 	public Object getService(BundleContextImpl contextServiceReferenceImpl reference) {
 		/* test for permission to get the service */
 
 		return reference.getRegistration().getService(context);
 	}

Releases the service object referenced by the specified ServiceReference object. If the context bundle's use count for the service is zero, this method returns false. Otherwise, the context bundle's use count for the service is decremented by one.

The service's service object should no longer be used and all references to it should be destroyed when a bundle's use count for the service drops to zero.

The following steps are required to unget the service object:

  1. If the context bundle's use count for the service is zero or the service has been unregistered, false is returned.
  2. The context bundle's use count for this service is decremented by one.
  3. If the context bundle's use count for the service is currently zero and the service was registered with a ServiceFactory object, the org.osgi.framework.ServiceFactory.ungetService(org.osgi.framework.Bundle,org.osgi.framework.ServiceRegistration,java.lang.Object) method is called to release the service object for the context bundle.
  4. true is returned.

Parameters:
context The BundleContext of the requesting bundle.
reference A reference to the service to be released.
Returns:
false if the context bundle's use count for the service is zero or if the service has been unregistered; true otherwise.
Throws:
java.lang.IllegalStateException If this BundleContext is no longer valid.
See also:
getService(org.eclipse.osgi.framework.internal.core.BundleContextImpl,org.eclipse.osgi.internal.serviceregistry.ServiceReferenceImpl)
org.osgi.framework.ServiceFactory
 
 	public boolean ungetService(BundleContextImpl contextServiceReferenceImpl reference) {
 		ServiceRegistrationImpl registration = reference.getRegistration();
 
 		return registration.ungetService(context);
 	}

Returns this bundle's ServiceReference list for all services it has registered or null if this bundle has no registered services.

If the Java runtime supports permissions, a ServiceReference object to a service is included in the returned list only if the caller has the ServicePermission to get the service using at least one of the named classes the service was registered under.

The list is valid at the time of the call to this method, however, as the Framework is a very dynamic environment, services can be modified or unregistered at anytime.

Parameters:
context The BundleContext of the requesting bundle.
Returns:
An array of ServiceReference objects or null.
Throws:
java.lang.IllegalStateException If this bundle has been uninstalled.
See also:
org.osgi.framework.ServiceRegistration
org.osgi.framework.ServiceReference
org.osgi.framework.ServicePermission
 
 		for (Iterator iter = references.iterator(); iter.hasNext();) {
 			try { /* test for permission to get the service */
 			} catch (SecurityException se) {
 				iter.remove();
 			}
 		}
 
 		int size = references.size();
 		if (size == 0) {
 			return null;
 		}
 		return (ServiceReferenceImpl[]) references.toArray(new ServiceReferenceImpl[size]);
 	}

Returns this bundle's ServiceReference list for all services it is using or returns null if this bundle is not using any services. A bundle is considered to be using a service if its use count for that service is greater than zero.

If the Java Runtime Environment supports permissions, a ServiceReference object to a service is included in the returned list only if the caller has the ServicePermission to get the service using at least one of the named classes the service was registered under.

The list is valid at the time of the call to this method, however, as the Framework is a very dynamic environment, services can be modified or unregistered at anytime.

Parameters:
context The BundleContext of the requesting bundle.
Returns:
An array of ServiceReference objects or null.
Throws:
java.lang.IllegalStateException If this bundle has been uninstalled.
See also:
org.osgi.framework.ServiceReference
org.osgi.framework.ServicePermission
 
 		Map servicesInUse = context.getServicesInUseMap();
 		if (servicesInUse == null) {
 			return null;
 		}
 
 		List references;
 		synchronized (servicesInUse) {
 			if (servicesInUse.size() == 0) {
 				return null;
 			}
 			references = changeRegistrationsToReferences(new ArrayList(servicesInUse.keySet()));
 		}
 		for (Iterator iter = references.iterator(); iter.hasNext();) {
 			try { /* test for permission to get the service */
 			} catch (SecurityException se) {
 				iter.remove();
 			}
 		}
 
 		int size = references.size();
 		if (size == 0) {
 			return null;
 		}
 		return (ServiceReferenceImpl[]) references.toArray(new ServiceReferenceImpl[size]);
 	}

Called when the BundleContext is closing to unregister all services currently registered by the bundle.

Parameters:
context The BundleContext of the closing bundle.
 
 	public void unregisterServices(BundleContextImpl context) {
 		List registrations = lookupServiceRegistrations(context);
 		for (Iterator iter = registrations.iterator(); iter.hasNext();) {
 			try {
 				registration.unregister();
 			} catch (IllegalStateException e) {
 				/* already unregistered */
 			}
 		}
 		removeServiceRegistrations(context); // remove empty list
 	}

Called when the BundleContext is closing to unget all services currently used by the bundle.

Parameters:
context The BundleContext of the closing bundle.
 
 	public void releaseServicesInUse(BundleContextImpl context) {
 		Map servicesInUse = context.getServicesInUseMap();
 		if (servicesInUse == null) {
 			return;
 		}
 		List registrations;
 		synchronized (servicesInUse) {
 			if (servicesInUse.size() == 0) {
 				return;
 			}
 			registrations = new ArrayList(servicesInUse.keySet());
 		}
 			Debug.println("Releasing services"); //$NON-NLS-1$
 		}
 		for (Iterator iter = registrations.iterator(); iter.hasNext();) {
 			registration.releaseService(context);
 		}
 	}

Add a new Service Listener for a bundle.

Parameters:
context Context of bundle adding listener.
listener Service Listener to be added.
filter Filter string for listener or null.
Throws:
org.osgi.framework.InvalidSyntaxException If the filter string is invalid.
 
 	public void addServiceListener(BundleContextImpl contextServiceListener listenerString filterthrows InvalidSyntaxException {
 		if (. && .) {
 			String listenerName = listener.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(listener)); //$NON-NLS-1$
 			Debug.println("addServiceListener[" + context.getBundleImpl() + "](" + listenerName + ", \"" + filter + "\")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
 		}
 
 		FilteredServiceListener filteredListener = new FilteredServiceListener(contextlistenerfilter);
 		FilteredServiceListener oldFilteredListener;
 		synchronized () {
 			Map listeners = (Map.get(context);
 			if (listeners == null) {
 				listeners = new CopyOnWriteIdentityMap();
 				.put(contextlisteners);
 			}
 			oldFilteredListener = (FilteredServiceListenerlisteners.put(listenerfilteredListener);
 		}
 
 		if (oldFilteredListener != null) {
 			oldFilteredListener.markRemoved();
 			Collection removedListeners = Collections.singletonList(oldFilteredListener);
 			notifyListenerHooks(removedListenersfalse);
 		}
 
 		Collection addedListeners = Collections.singletonList(filteredListener);
 		notifyListenerHooks(addedListenerstrue);
 	}

Remove a Service Listener for a bundle.

Parameters:
context Context of bundle removing listener.
listener Service Listener to be removed.
 
 	public void removeServiceListener(BundleContextImpl contextServiceListener listener) {
 		if (. && .) {
 			String listenerName = listener.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(listener)); //$NON-NLS-1$
 			Debug.println("removeServiceListener[" + context.getBundleImpl() + "](" + listenerName + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 		}
 
 		FilteredServiceListener oldFilteredListener;
 		synchronized () {
 			Map listeners = (Map.get(context);
 			if (listeners == null) {
 				return// this context has no listeners to begin with
 			}
 			oldFilteredListener = (FilteredServiceListenerlisteners.remove(listener);
 		}
 
 		if (oldFilteredListener == null) {
 			return;
 		}
 		oldFilteredListener.markRemoved();
 		Collection removedListeners = Collections.singletonList(oldFilteredListener);
 		notifyListenerHooks(removedListenersfalse);
 	}

Remove all Service Listener for a bundle.

Parameters:
context Context of bundle removing all listeners.
 
 	public void removeAllServiceListeners(BundleContextImpl context) {
 		Map removedListenersMap;
 		synchronized () {
 			removedListenersMap = (Map.remove(context);
 		}
 		if ((removedListenersMap == null) || (removedListenersMap.size() == 0)) {
 			return;
 		}
 		Collection removedListeners = removedListenersMap.values();
 		for (Iterator iter = removedListeners.iterator(); iter.hasNext();) {
 			FilteredServiceListener oldFilteredListener = (FilteredServiceListeneriter.next();
 			oldFilteredListener.markRemoved();
 		}
 		notifyListenerHooks(removedListenersfalse);
 	}

Deliver a ServiceEvent.

Parameters:
event The ServiceEvent to deliver.
 
 	void publishServiceEvent(final ServiceEvent event) {
 		if (System.getSecurityManager() == null) {
 		} else {
 			AccessController.doPrivileged(new PrivilegedAction() {
 				public Object run() {
 					return null;
 				}
 			});
 		}
 	}
 
 		/* Build the listener snapshot */
 		Map /*<BundleContextImpl,Set<Map.Entry<Object,Object>>>*/listenerSnapshot;
 		synchronized () {
 			listenerSnapshot = new HashMap(.size());
 			for (Iterator iter = .entrySet().iterator(); iter.hasNext();) {
 				Map.Entry entry = (Map.Entryiter.next();
 				BundleContextImpl context = (BundleContextImplentry.getKey();
 				Map listeners = (Mapentry.getValue();
 				if (!listeners.isEmpty()) {
 					listenerSnapshot.put(contextlisteners.entrySet());
 				}
 			}
 		}
 
 		/* shrink the snapshot.
 		 * keySet returns a Collection which cannot be added to and
 		 * removals from that collection will result in removals of the
 		 * entry from the snapshot.
 		 */
 		Collection/*<BundleContextImpl>*/shrinkable = listenerSnapshot.keySet();
 		notifyEventHooksPrivileged(eventshrinkable);
 		if (listenerSnapshot.isEmpty()) {
 			return;
 		}
 
 		/* deliver the event to the snapshot */
 		for (Iterator iter = listenerSnapshot.entrySet().iterator(); iter.hasNext();) {
 			Map.Entry entry = (Map.Entryiter.next();
 			EventDispatcher dispatcher = (BundleContextImplentry.getKey();
 			Set listeners = (Setentry.getValue();
 			queue.queueListeners(listenersdispatcher);
 		}
 	}

Return the next available service id.

Returns:
next service id.
 
 	synchronized long getNextServiceId() {
 		long id = ;
 		return id;
 	}

Add the ServiceRegistrationImpl to the data structure.

Parameters:
context The BundleContext of the bundle registering the service.
registration The new ServiceRegistration.
 
 	/* @GuardedBy("this") */
 		// Add the ServiceRegistrationImpl to the list of Services published by BundleContextImpl.
 		List contextServices = (List.get(context);
 		if (contextServices == null) {
 			contextServices = new ArrayList();
 			.put(contextcontextServices);
 		}
 		// The list is NOT sorted, so we just add
 		contextServices.add(registration);
 
 		// Add the ServiceRegistrationImpl to the list of Services published by Class Name.
 		String[] clazzes = registration.getClasses();
 		int insertIndex;
 		for (int i = 0, size = clazzes.lengthi < sizei++) {
 			String clazz = clazzes[i];
 
 			List services = (List.get(clazz);
 
 			if (services == null) {
 				services = new ArrayList();
 				.put(clazzservices);
 			}
 
 			// The list is sorted, so we must find the proper location to insert
 			insertIndex = -Collections.binarySearch(servicesregistration) - 1;
 			services.add(insertIndexregistration);
 		}
 
 		// Add the ServiceRegistrationImpl to the list of all published Services.
 		// The list is sorted, so we must find the proper location to insert
 		insertIndex = -Collections.binarySearch(registration) - 1;
 		.add(insertIndexregistration);
 	}

Modify the ServiceRegistrationImpl in the data structure.

Parameters:
context The BundleContext of the bundle registering the service.
registration The modified ServiceRegistration.
 
 	/* @GuardedBy("this") */
 		// The list of Services published by BundleContextImpl is not sorted, so
 		// we do not need to modify it.
 
 		// Remove the ServiceRegistrationImpl from the list of Services published by Class Name
 		// and then add at the correct index.
 		String[] clazzes = registration.getClasses();
 		int insertIndex;
 		for (int i = 0, size = clazzes.lengthi < sizei++) {
 			String clazz = clazzes[i];
 			List services = (List.get(clazz);
 			services.remove(registration);
 			// The list is sorted, so we must find the proper location to insert
 			insertIndex = -Collections.binarySearch(servicesregistration) - 1;
 			services.add(insertIndexregistration);
 		}
 
 		// Remove the ServiceRegistrationImpl from the list of all published Services
 		// and then add at the correct index.
 		// The list is sorted, so we must find the proper location to insert
 		insertIndex = -Collections.binarySearch(registration) - 1;
 		.add(insertIndexregistration);
 	}

Remove the ServiceRegistrationImpl from the data structure.

Parameters:
context The BundleContext of the bundle registering the service.
registration The ServiceRegistration to remove.
 
 	/* @GuardedBy("this") */
 		// Remove the ServiceRegistrationImpl from the list of Services published by BundleContextImpl.
 		List contextServices = (List.get(context);
 		if (contextServices != null) {
 			contextServices.remove(registration);
 		}
 
 		// Remove the ServiceRegistrationImpl from the list of Services published by Class Name.
 		String[] clazzes = registration.getClasses();
 		for (int i = 0, size = clazzes.lengthi < sizei++) {
 			String clazz = clazzes[i];
 			List services = (List.get(clazz);
 			services.remove(registration);
 			if (services.isEmpty()) { // remove empty list
 			}
 		}
 
 		// Remove the ServiceRegistrationImpl from the list of all published Services.
 	}

Lookup Service Registrations in the data structure by class name and filter.

Parameters:
clazz The class name with which the service was registered or null for all services.
filter The filter criteria.
Returns:
List<ServiceRegistrationImpl>
 
 	private List lookupServiceRegistrations(String clazzFilter filter) {
 		List result;
 		synchronized (this) {
 			if (clazz == null) { /* all services */
 			} else {
 				/* services registered under the class name */
 				result = (List.get(clazz);
 			}
 
 			if ((result == null) || (result.size() == 0)) {
 			}
 
 			result = new ArrayList(result); /* make a new list since we don't want to change the real list */
 		}
 
 		if (filter == null) {
 			return result;
 		}
 
 		for (Iterator iter = result.iterator(); iter.hasNext();) {
 			try {
 				reference = registration.getReferenceImpl();
 			} catch (IllegalStateException e) {
 				iter.remove(); /* service was unregistered after we left the synchronized block above */
 				continue;
 			}
 			if (!filter.match(reference)) {
 				iter.remove();
 			}
 		}
 		return result;
 	}

Lookup Service Registrations in the data structure by BundleContext.

Parameters:
context The BundleContext for which to return Service Registrations.
Returns:
List<ServiceRegistrationImpl>
 
 	private synchronized List lookupServiceRegistrations(BundleContextImpl context) {
 		List result = (List.get(context);
 
 		if ((result == null) || (result.size() == 0)) {
 		}
 
 		return new ArrayList(result); /* make a new list since we don't want to change the real list */
 	}

Remove Service Registrations in the data structure by BundleContext.

Parameters:
context The BundleContext for which to remove Service Registrations.
 
 	private synchronized void removeServiceRegistrations(BundleContextImpl context) {
 	}

Modify a List<ServiceRegistrationImpl> in place to a List<ServiceReferenceImpl>.

Parameters:
result The input List<ServiceRegistrationImpl>.
Returns:
result which has been changed to List<ServiceReferenceImpl>
 
 	private static List changeRegistrationsToReferences(List result) {
 		for (ListIterator iter = result.listIterator(); iter.hasNext();) {
 			try {
 				reference = registration.getReferenceImpl();
 			} catch (IllegalStateException e) {
 				iter.remove(); /* service was unregistered after we were called */
 				continue;
 			}
 			iter.set(reference); /* replace the registration with its reference */
 		}
 		return result;
 	}

Check for permission to register a service. The caller must have permission for ALL names.
 
 	private static void checkRegisterServicePermission(String[] names) {
 		if (sm == null) {
 			return;
 		}
 		for (int i = 0, len = names.lengthi < leni++) {
 		}
 	}

Check for permission to get a service.
 
 	private static void checkGetServicePermission(ServiceReference reference) {
 		if (sm == null) {
 			return;
 		}
 	}

Check for permission to listen to a service.
 
 	static boolean hasListenServicePermission(ServiceEvent eventBundleContextImpl context) {
 		if (domain == null) {
 			return true;
 		}
 
 	}

Return the name of the class that is not satisfied by the service object.

Parameters:
clazzes Array of class names.
serviceObject Service object.
Returns:
The name of the class that is not satisfied by the service object.
	static String checkServiceClass(final String[] clazzesfinal Object serviceObject) {
		ClassLoader cl = (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
			public Object run() {
				return serviceObject.getClass().getClassLoader();
		});
		for (int i = 0, len = clazzes.lengthi < leni++) {
			try {
				Class serviceClazz = cl == null ? Class.forName(clazzes[i]) : cl.loadClass(clazzes[i]);
				if (!serviceClazz.isInstance(serviceObject))
					return clazzes[i];
catch (ClassNotFoundException e) {
				//This check is rarely done
				if (extensiveCheckServiceClass(clazzes[i], serviceObject.getClass()))
					return clazzes[i];
		return null;
	private static boolean extensiveCheckServiceClass(String clazzClass serviceClazz) {
		if (clazz.equals(serviceClazz.getName()))
			return false;
		Class[] interfaces = serviceClazz.getInterfaces();
		for (int i = 0, len = interfaces.lengthi < leni++)
			if (!extensiveCheckServiceClass(clazzinterfaces[i]))
				return false;
		Class superClazz = serviceClazz.getSuperclass();
		if (superClazz != null)
			if (!extensiveCheckServiceClass(clazzsuperClazz))
				return false;
		return true;
	static boolean isAssignableTo(BundleContextImpl contextServiceReferenceImpl reference) {
		Bundle bundle = context.getBundleImpl();
		String[] clazzes = reference.getClasses();
		for (int i = 0, len = clazzes.lengthi < leni++)
			if (!reference.isAssignableTo(bundleclazzes[i]))
				return false;
		return true;
	}

Call the registered FindHook services to allow them to inspect and possibly shrink the result. The FindHook must be called in order: descending by service.ranking, then ascending by service.id. This is the natural order for ServiceReference.

Parameters:
context The context of the bundle getting the service references.
clazz The class name used to search for the service references.
filterstring The filter used to search for the service references.
allservices True if getAllServiceReferences called.
result The result to return to the caller which may have been shrunk by the FindHooks.
	private void notifyFindHooks(final BundleContextImpl contextfinal String clazzfinal String filterstringfinal boolean allservicesfinal Collection result) {
		if (System.getSecurityManager() == null) {
			notifyFindHooksPrivileged(contextclazzfilterstringallservicesresult);
else {
			AccessController.doPrivileged(new PrivilegedAction() {
				public Object run() {
					notifyFindHooksPrivileged(contextclazzfilterstringallservicesresult);
					return null;
			});
	void notifyFindHooksPrivileged(BundleContextImpl contextString clazzString filterstringboolean allservicesCollection result) {
		if (systemBundleContext == null) { // if no system bundle context, we are done!
			return;
			Debug.println("notifyFindHooks(" + context.getBundleImpl() + "," + clazz + "," + filterstring + "," + allservices + "," + result + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
		// Since the list is already sorted, we don't need to sort the list to call the hooks
		// in the proper order.
		for (Iterator iter = hooks.iterator(); iter.hasNext();) {
			Object findHook = registration.getService(systemBundleContext);
			if (findHook == null) { // if the hook is null
				continue;
			try {
				if (findHook instanceof FindHook) { // if the hook is usable
					((FindHookfindHook).find(contextclazzfilterstringallservicesresult);
catch (Throwable t) {
					Debug.println(findHook + ".find() exception: " + t.getMessage()); //$NON-NLS-1$
				// allow the adaptor to handle this unexpected error
				ServiceException se = new ServiceException(NLS.bind(.findHook.getClass().getName(), "find"), t); //$NON-NLS-1$ 
finally {
				registration.ungetService(systemBundleContext);
	}

Call the registered EventHook services to allow them to inspect and possibly shrink the result. The EventHooks must be called in order: descending by service.ranking, then ascending by service.id. This is the natural order for ServiceReference.

Parameters:
event The service event to be delivered.
result The result to return to the caller which may have been shrunk by the EventHooks.
	private void notifyEventHooksPrivileged(ServiceEvent eventCollection result) {
		if (systemBundleContext == null) { // if no system bundle context, we are done!
			return;
			Debug.println("notifyEventHooks(" + event.getType() + ":" + event.getServiceReference() + "," + result + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ 
		// Since the list is already sorted, we don't need to sort the list to call the hooks
		// in the proper order.
		for (Iterator iter = hooks.iterator(); iter.hasNext();) {
			Object eventHook = registration.getService(systemBundleContext);
			if (eventHook == null) { // if the hook is null
				continue;
			try {
				if (eventHook instanceof EventHook) { // if the hook is usable
					((EventHookeventHook).event(eventresult);
catch (Throwable t) {
					Debug.println(eventHook + ".event() exception: " + t.getMessage()); //$NON-NLS-1$
				// allow the adaptor to handle this unexpected error
				ServiceException se = new ServiceException(NLS.bind(.eventHook.getClass().getName(), "event"), t); //$NON-NLS-1$ 
finally {
				registration.ungetService(systemBundleContext);
	}

Call a newly registered ListenerHook service to provide the current collection of service listeners.

Parameters:
registration The newly registered ListenerHook service.
	private void notifyNewListenerHook(final ServiceRegistrationImpl registration) {
		if (System.getSecurityManager() == null) {
else {
			AccessController.doPrivileged(new PrivilegedAction() {
				public Object run() {
					return null;
			});
		if (systemBundleContext == null) { // if no system bundle context, we are done!
			return;
			Debug.println("notifyNewListenerHook(" + registration + ")"); //$NON-NLS-1$ //$NON-NLS-2$ 
		Collection addedListeners = new ArrayList();
		synchronized () {
			for (Iterator iter = .values().iterator(); iter.hasNext();) {
				Map listeners = (Mapiter.next();
				if (!listeners.isEmpty()) {
					addedListeners.addAll(listeners.values());
		addedListeners = Collections.unmodifiableCollection(addedListeners);
		Object listenerHook = registration.getService(systemBundleContext);
		if (listenerHook == null) { // if the hook is null
			return;
		try {
			if (listenerHook instanceof ListenerHook) { // if the hook is usable
				((ListenerHooklistenerHook).added(addedListeners);
catch (Throwable t) {
				Debug.println(listenerHook + ".added() exception: " + t.getMessage()); //$NON-NLS-1$
			// allow the adaptor to handle this unexpected error
			ServiceException se = new ServiceException(NLS.bind(.listenerHook.getClass().getName(), "event"), t); //$NON-NLS-1$ 
finally {
			registration.ungetService(systemBundleContext);
	}

Call the registered ListenerHook services to notify them of newly added or removed service listeners. The ListenerHook must be called in order: descending by service.ranking, then ascending by service.id. This is the natural order for ServiceReference.

Parameters:
listeners An unmodifiable collection of ListenerInfo objects.
added true if the specified listeners are being added. false if they are being removed.
	private void notifyListenerHooks(final Collection listenersfinal boolean added) {
		if (System.getSecurityManager() == null) {
else {
			AccessController.doPrivileged(new PrivilegedAction() {
				public Object run() {
					return null;
			});
	void notifyListenerHooksPrivileged(Collection listenersboolean added) {
		if (systemBundleContext == null) { // if no system bundle context, we are done!
			return;
			Debug.println("notifyListenerHooks(" + listeners + "," + (added ? "added" : "removed") + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
		// Since the list is already sorted, we don't need to sort the list to call the hooks
		// in the proper order.
		for (Iterator iter = hooks.iterator(); iter.hasNext();) {
			Object listenerHook = registration.getService(systemBundleContext);
			if (listenerHook == null) { // if the hook is null
				continue;
			try {
				if (listenerHook instanceof ListenerHook) { // if the hook is usable
					if (added) {
						((ListenerHooklistenerHook).added(listeners);
else {
						((ListenerHooklistenerHook).removed(listeners);
catch (Throwable t) {
					Debug.println(listenerHook + "." + (added ? "added" : "removed") + "() exception: " + t.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
				// allow the adaptor to handle this unexpected error
				ServiceException se = new ServiceException(NLS.bind(.listenerHook.getClass().getName(), "event"), t); //$NON-NLS-1$ 
finally {
				registration.ungetService(systemBundleContext);
New to GrepCode? Check out our FAQ X