Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Copyright (c) 2003, 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.util.*;
A registered service. The framework returns a ServiceRegistration object when a BundleContext.registerService method is successful. This object is for the private use of the registering bundle and should not be shared with other bundles.

The ServiceRegistration object may be used to update the properties for the service or to unregister the service.

If the ServiceRegistration is garbage collected the framework may remove the service. This implies that if a bundle wants to keep its service registered, it should keep the ServiceRegistration object referenced.

ThreadSafe:
 
 public class ServiceRegistrationImpl implements ServiceRegistrationComparable {
Internal framework object.
 
 	private final Framework framework;
 
 	private final ServiceRegistry registry;

context which registered this service.
 
 	private final BundleContextImpl context;

bundle which registered this service.
 
 	private final Bundle bundle;

service classes for this registration.
 
 	private final String[] clazzes;

service object for this registration.
 
 	private final Object service;

Reference to this registration.
 
 	/* @GuardedBy("registrationLock") */
List of contexts using the service. List<BundleContextImpl>.
 
 	/* @GuardedBy("registrationLock") */
 	private final List contextsUsing;

properties for this registration.
 
 	/* @GuardedBy("registrationLock") */
service id.
 
 	private final long serviceid;

service ranking.
 
 	/* @GuardedBy("registrationLock") */
 	private int serviceranking;
 
 	/* internal object to use for synchronization */
 	private final Object registrationLock = new Object();

The registration state
 
 	/* @GuardedBy("registrationLock") */
 	private int state;
 	private static final int REGISTERED = 0x00;
 	private static final int UNREGISTERING = 0x01;
 	private static final int UNREGISTERED = 0x02;

Construct a ServiceRegistration and register the service in the framework's service registry.
 
 	ServiceRegistrationImpl(ServiceRegistry registryBundleContextImpl contextString[] clazzesObject service) {
 		this. = registry;
 		this. = context;
 		this. = context.getBundleImpl();
 		this. = context.getFramework();
 		this. = clazzes/* must be set before calling createProperties. */
 		this. = service;
 		this. = registry.getNextServiceId(); /* must be set before calling createProperties. */
 		this. = new ArrayList(10);
		synchronized () {
			this. = ;
			/* We leak this from the constructor here, but it is ok
			 * because the ServiceReferenceImpl constructor only
			 * stores the value in a final field without
			 * otherwise using it.
			 */
			this. = new ServiceReferenceImpl(this);
		}
	}

Call after constructing this object to complete the registration.
	void register(Dictionary props) {
		synchronized () {
			synchronized () {
				ref = /* used to publish event outside sync */
				this. = createProperties(props); /* must be valid after unregister is called. */
			}
				Debug.println("registerService[" +  + "](" + this + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			}
		}
		/* must not hold the registrations lock when this event is published */
	}

Update the properties associated with this service.

The key "objectClass" cannot be modified by this method. It's value is set when the service is registered.

The following steps are followed to modify a service's properties:

  1. The service's properties are replaced with the provided properties.
  2. A org.osgi.framework.ServiceEvent of type org.osgi.framework.ServiceEvent.MODIFIED is synchronously sent.

Parameters:
props The properties for this service. Changes should not be made to this object after calling this method. To update the service's properties this method should be called again.
Throws:
java.lang.IllegalStateException If this ServiceRegistration has already been unregistered.
java.lang.IllegalArgumentException If the properties parameter contains case variants of the same key name.
	public void setProperties(Dictionary props) {
		final ServiceProperties previousProperties;
		synchronized () {
			synchronized () {
				if ( != ) { /* in the process of unregisterING */
				}
				ref = /* used to publish event outside sync */
				previousProperties = this.;
			}
		}
		/* must not hold the registrationLock when this event is published */
		.publishServiceEvent(new ModifiedServiceEvent(refpreviousProperties));
	}

Unregister the service. Remove a service registration from the framework's service registry. All ServiceReferenceImpl objects for this registration can no longer be used to interact with the service.

The following steps are followed to unregister a service:

  1. The service is removed from the framework's service registry so that it may no longer be used. ServiceReferenceImpls for the service may no longer be used to get a service object for the service.
  2. A org.osgi.framework.ServiceEvent of type org.osgi.framework.ServiceEvent.UNREGISTERING is synchronously sent so that bundles using this service may release their use of the service.
  3. For each bundle whose use count for this service is greater than zero:
    1. The bundle's use count for this service is set to zero.
    2. If the service was registered with a org.osgi.framework.ServiceFactory, the ServiceFactory.ungetService method is called to release the service object for the bundle.

	public void unregister() {
		synchronized () {
			synchronized () {
				if ( != ) { /* in the process of unregisterING */
				}
				/* remove this object from the service registry */
					Debug.println("unregisterService[" +  + "](" + this + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				}
				 = /* mark unregisterING */
				ref = /* used to publish event outside sync */
			}
		}
		/* must not hold the registrationLock when this event is published */
		int size = 0;
		BundleContextImpl[] users = null;
		synchronized () {
			/* we have published the ServiceEvent, now mark the service fully unregistered */
			size = .size();
			if (size > 0) {
					Debug.println("unregisterService: releasing users"); //$NON-NLS-1$
				}
			}
		}
		/* must not hold the registrationLock while releasing services */
		for (int i = 0; i < sizei++) {
			releaseService(users[i]);
		}
		synchronized () {
			 = null/* mark registration dead */
		}
		/* The properties field must remain valid after unregister completes. */
	}

Returns a ServiceReferenceImpl object for this registration. The ServiceReferenceImpl object may be shared with other bundles.

Returns:
A ServiceReferenceImpl object.
Throws:
java.lang.IllegalStateException If this ServiceRegistration has already been unregistered.
	}
		/* use reference instead of unregistered so that ServiceFactorys, called
		 * by releaseService after the registration is unregistered, can
		 * get the ServiceReference. Note this technically may violate the spec
		 * but makes more sense.
		 */
		synchronized () {
			if ( == null) {
			}
			return ;
		}
	}

Construct a properties object from the dictionary for this ServiceRegistration.

Parameters:
p The properties for this service.
Returns:
A Properties object for this ServiceRegistration.
	/* @GuardedBy("registrationLock") */
		props.set(.new Long(), true);
		props.setReadOnly();
		 = (ranking instanceof Integer) ? ((Integerranking).intValue() : 0;
		return props;
	}

Return the properties object. This is for framework internal use only.

Returns:
The service registration's properties.
		synchronized () {
			return ;
		}
	}

Get the value of a service's property.

This method will continue to return property values after the service has been unregistered. This is so that references to unregistered service can be interrogated. (For example: ServiceReference objects stored in the log.)

Parameters:
key Name of the property.
Returns:
Value of the property or null if there is no property by that name.
		synchronized () {
			return .getProperty(key);
		}
	}

Get the list of key names for the service's properties.

This method will continue to return the keys after the service has been unregistered. This is so that references to unregistered service can be interrogated. (For example: ServiceReference objects stored in the log.)

Returns:
The list of property key names.
		synchronized () {
		}
	}

Return the service id for this service.

Returns:
The service id for this service.
	long getId() {
		return ;
	}

Return the service ranking for this service.

Returns:
The service ranking for this service.
	int getRanking() {
		synchronized () {
		}
	}
		return ;
	}
		return ;
	}

Return the bundle which registered the service.

This method will always return null when the service has been unregistered. This can be used to determine if the service has been unregistered.

Returns:
The bundle which registered the service.
		synchronized () {
			if ( == null) {
				return null;
			}
			return ;
		}
	}

Get a service object for the using BundleContext.

Parameters:
user BundleContext using service.
Returns:
Service object
		synchronized () {
			if ( == ) { /* service unregistered */
				return null;
			}
		}
			Debug.println("getService[" + user.getBundleImpl() + "](" + this + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		}
		Map servicesInUse = user.getServicesInUseMap();
		if (servicesInUse == null) { /* user is closed */
			user.checkValid(); /* throw exception */
		}
		/* Use a while loop to support retry if a call to a ServiceFactory fails */
		while (true) {
			boolean added = false;
			/* Obtain the ServiceUse object for this service by bundle user */
			synchronized (servicesInUse) {
				user.checkValid();
				use = (ServiceUseservicesInUse.get(this);
				if (use == null) {
					/* if this is the first use of the service
					 * optimistically record this service is being used. */
					use = new ServiceUse(userthis);
					added = true;
					synchronized () {
						if ( == ) { /* service unregistered */
							return null;
						}
						servicesInUse.put(thisuse);
					}
				}
			}
			/* Obtain and return the service object */
			synchronized (use) {
				/* if another thread removed the ServiceUse, then
				 * go back to the top and start again */
				synchronized (servicesInUse) {
					user.checkValid();
					if (servicesInUse.get(this) != use) {
						continue;
					}
				}
				Object serviceObject = use.getService();
				/* if the service factory failed to return an object and
				 * we created the service use, then remove the 
				 * optimistically added ServiceUse. */
				if ((serviceObject == null) && added) {
					synchronized (servicesInUse) {
						synchronized () {
							servicesInUse.remove(this);
						}
					}
				}
				return serviceObject;
			}
		}
	}

Unget a service for the using BundleContext.

Parameters:
user BundleContext using service.
Returns:
false if the context bundle's use count for the service is zero or if the service has been unregistered, otherwise true.
		synchronized () {
			if ( == ) {
				return false;
			}
		}
			Debug.println("ungetService[" + user.getBundleImpl() + "](" + this + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		}
		Map servicesInUse = user.getServicesInUseMap();
		if (servicesInUse == null) {
			return false;
		}
		synchronized (servicesInUse) {
			use = (ServiceUseservicesInUse.get(this);
			if (use == null) {
				return false;
			}
		}
		synchronized (use) {
			if (use.ungetService()) {
				/* use count is now zero */
				synchronized (servicesInUse) {
					synchronized () {
						servicesInUse.remove(this);
					}
				}
			}
		}
		return true;
	}

Release the service for the using BundleContext.

Parameters:
user BundleContext using service.
		synchronized () {
			if ( == null) { /* registration dead */
				return;
			}
		}
			Debug.println("releaseService[" + user.getBundleImpl() + "](" + this + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		}
		Map servicesInUse = user.getServicesInUseMap();
		if (servicesInUse == null) {
			return;
		}
		synchronized (servicesInUse) {
			synchronized () {
				use = (ServiceUseservicesInUse.remove(this);
				if (use == null) {
					return;
				}
			}
		}
		synchronized (use) {
		}
	}

Return the list of bundle which are using this service.

Returns:
Array of Bundles using this service.
		synchronized () {
			if ( == /* service unregistered */
				return null;
			int size = .size();
			if (size == 0)
				return null;
			/* Copy list of BundleContext into an array of Bundle. */
			Bundle[] bundles = new Bundle[size];
			for (int i = 0; i < sizei++)
			return bundles;
		}
	}
	boolean isAssignableTo(Bundle clientString className) {
		return .isServiceAssignableTo(clientclassName.getClass());
	}

Return a String representation of this object.

Returns:
String representation of this object.
	public String toString() {
		int size = .;
		StringBuffer sb = new StringBuffer(50 * size);
		sb.append('{');
		for (int i = 0; i < sizei++) {
			if (i > 0) {
				sb.append(", "); //$NON-NLS-1$
			}
		}
		sb.append("}="); //$NON-NLS-1$
		return sb.toString();
	}

Compares this ServiceRegistrationImpl with the specified ServiceRegistrationImpl for order.

This does a reverse comparison so that the highest item is sorted to the left. We keep ServiceRegistationImpls in sorted lists such that the highest ranked service is at element 0 for quick retrieval.

Parameters:
object The ServiceRegistrationImpl to be compared.
Returns:
Returns a negative integer, zero, or a positive integer if this ServiceRegistrationImpl is greater than, equal to, or less than the specified ServiceRegistrationImpl.
	public int compareTo(Object object) {
		final int thisRanking = this.getRanking();
		final int otherRanking = other.getRanking();
		if (thisRanking != otherRanking) {
			if (thisRanking < otherRanking) {
				return 1;
			}
			return -1;
		}
		final long thisId = this.getId();
		final long otherId = other.getId();
		if (thisId == otherId) {
			return 0;
		}
		if (thisId < otherId) {
			return -1;
		}
		return 1;
	}
New to GrepCode? Check out our FAQ X