All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.osgi.internal.serviceregistry.ServiceObjectsImpl Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 * Copyright (c) 2013 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 org.eclipse.osgi.internal.framework.BundleContextImpl;
import org.eclipse.osgi.internal.messages.Msg;
import org.osgi.framework.*;

/**
 * ServiceObjects implementation.
 */
public class ServiceObjectsImpl implements ServiceObjects {
	/** Service registration */
	private final ServiceRegistrationImpl registration;
	/** Reference to service */
	private final ServiceReference reference;
	/** BundleContext associated with this service use */
	private final BundleContextImpl user;

	/**
	 * Constructs a service objects encapsulating the service object.
	 *
	 * @param   user bundle getting the service
	 * @param   registration ServiceRegistration of the service
	 */
	ServiceObjectsImpl(BundleContextImpl user, ServiceRegistrationImpl registration) {
		this.registration = registration;
		this.reference = registration.getReference();
		this.user = user;
	}

	/**
	 * Returns a service object for the {@link #getServiceReference()
	 * referenced} service.
	 * 
	 * 

* This {@code ServiceObjects} object can be used to obtain multiple service * objects for the referenced service if the service has * {@link Constants#SCOPE_PROTOTYPE prototype} scope. If the referenced * service has {@link Constants#SCOPE_SINGLETON singleton} or * {@link Constants#SCOPE_BUNDLE bundle} scope, this method behaves the same * as calling the {@link BundleContext#getService(ServiceReference)} method * for the referenced service. That is, only one, use-counted service object * is available from this {@link ServiceObjects} object. * *

* This method will always return {@code null} when the referenced service * has been unregistered. * *

* For a prototype scope service, the following steps are required to get * the service object: *

    *
  1. If the referenced service has been unregistered, {@code null} is * returned.
  2. *
  3. The * {@link PrototypeServiceFactory#getService(Bundle, ServiceRegistration)} * method is called to create a service object for the caller.
  4. *
  5. If the service object returned by the {@code PrototypeServiceFactory} * object is {@code null}, not an {@code instanceof} all the classes named * when the service was registered or the {@code PrototypeServiceFactory} * object throws an exception, {@code null} is returned and a Framework * event of type {@link FrameworkEvent#ERROR} containing a * {@link ServiceException} describing the error is fired.
  6. *
  7. The service object is returned.
  8. *
* * @return A service object for the referenced service or {@code null} if * the service is not registered, the service object returned by a * {@code ServiceFactory} does not implement the classes under which * it was registered or the {@code ServiceFactory} threw an * exception. * @throws IllegalStateException If the BundleContext used to create this * {@code ServiceObjects} object is no longer valid. * @see #ungetService(Object) */ @Override public S getService() { user.checkValid(); return registration.getService(user, ServiceConsumer.prototypeConsumer); } /** * Releases a service object for the {@link #getServiceReference() * referenced} service. * *

* This {@code ServiceObjects} object can be used to obtain multiple service * objects for the referenced service if the service has * {@link Constants#SCOPE_PROTOTYPE prototype} scope. If the referenced * service has {@link Constants#SCOPE_SINGLETON singleton} or * {@link Constants#SCOPE_BUNDLE bundle} scope, this method behaves the same * as calling the {@link BundleContext#ungetService(ServiceReference)} * method for the referenced service. That is, only one, use-counted service * object is available from this {@link ServiceObjects} object. * *

* For a prototype scope service, the following steps are required to * release the service object: *

    *
  1. If the referenced service has been unregistered, this method returns * without doing anything.
  2. *
  3. The * {@link PrototypeServiceFactory#ungetService(Bundle, ServiceRegistration, Object)} * method is called to release the specified service object.
  4. *
* *

* The specified service object must no longer be used and all references to * it should be destroyed after calling this method. * * @param service A service object previously provided by this * {@code ServiceObjects} object. * @throws IllegalStateException If the BundleContext used to create this * {@code ServiceObjects} object is no longer valid. * @throws IllegalArgumentException If the specified service was not * provided by this {@code ServiceObjects} object. * @see #getService() */ @Override public void ungetService(S service) { user.checkValid(); boolean removed = registration.ungetService(user, ServiceConsumer.prototypeConsumer, service); if (!removed) { if (registration.isUnregistered()) { return; } throw new IllegalArgumentException(Msg.SERVICE_OBJECTS_UNGET_ARGUMENT_EXCEPTION); } } /** * Returns the {@link ServiceReference} for the service associated with this * {@code ServiceObjects} object. * * @return The {@link ServiceReference} for the service associated with this * {@code ServiceObjects} object. */ @Override public ServiceReference getServiceReference() { return reference; } }