Copyright (c) 2013 IBM Corporation and others.
This program and the accompanying materials
are made available under the terms of the Eclipse Public License 2.0
which accompanies this distribution, and is available at
https://www.eclipse.org/legal/epl-2.0/
SPDX-License-Identifier: EPL-2.0
Contributors:
IBM Corporation - initial API and implementation
/*******************************************************************************
* Copyright (c) 2013 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* 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.
/**
* ServiceObjects implementation.
*/
public class ServiceObjectsImpl<S> implements ServiceObjects<S> {
Service registration /** Service registration */
private final ServiceRegistrationImpl<S> registration;
Reference to service /** Reference to service */
private final ServiceReference<S> reference;
BundleContext associated with this service use /** BundleContext associated with this service use */
private final BundleContextImpl user;
Constructs a service objects encapsulating the service object.
Params: - user – bundle getting the service
- registration – ServiceRegistration of the service
/**
* Constructs a service objects encapsulating the service object.
*
* @param user bundle getting the service
* @param registration ServiceRegistration of the service
*/
ServiceObjectsImpl(BundleContextImpl user, ServiceRegistrationImpl<S> registration) {
this.registration = registration;
this.reference = registration.getReference();
this.user = user;
}
Returns a service object for the
referenced
service. This ServiceObjects
object can be used to obtain multiple service objects for the referenced service if the service has prototype
scope. If the referenced service has singleton
or bundle
scope, this method behaves the same as calling the BundleContext.getService(ServiceReference<Object>)
method for the referenced service. That is, only one, use-counted service object is available from this ServiceObjects
object.
This method will always return null
when the referenced service has been unregistered.
For a prototype scope service, the following steps are required to get
the service object:
- If the referenced service has been unregistered,
null
is returned.
- The
PrototypeServiceFactory.getService(Bundle, ServiceRegistration)
method is called to create a service object for the caller.
- If the service object returned by the
PrototypeServiceFactory
object is null
, not an instanceof
all the classes named when the service was registered or the PrototypeServiceFactory
object throws an exception, null
is returned and a Framework event of type FrameworkEvent.ERROR
containing a ServiceException
describing the error is fired.
- The service object is returned.
Throws: - IllegalStateException – If the BundleContext used to create this
ServiceObjects
object is no longer valid.
See Also: Returns: A service object for the referenced service 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.
/**
* Returns a service object for the {@link #getServiceReference()
* referenced} service.
*
* <p>
* 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.
*
* <p>
* This method will always return {@code null} when the referenced service
* has been unregistered.
*
* <p>
* For a prototype scope service, the following steps are required to get
* the service object:
* <ol>
* <li>If the referenced service has been unregistered, {@code null} is
* returned.</li>
* <li>The
* {@link PrototypeServiceFactory#getService(Bundle, ServiceRegistration)}
* method is called to create a service object for the caller.</li>
* <li>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.</li>
* <li>The service object is returned.</li>
* </ol>
*
* @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
referenced
service. This ServiceObjects
object can be used to obtain multiple service objects for the referenced service if the service has prototype
scope. If the referenced service has singleton
or bundle
scope, this method behaves the same as calling the BundleContext.ungetService(ServiceReference<?>)
method for the referenced service. That is, only one, use-counted service object is available from this ServiceObjects
object.
For a prototype scope service, the following steps are required to
release the service object:
- If the referenced service has been unregistered, this method returns
without doing anything.
- The
PrototypeServiceFactory.ungetService(Bundle, ServiceRegistration, Object)
method is called to release the specified service object.
The specified service object must no longer be used and all references to
it should be destroyed after calling this method.
Params: - service – A service object previously provided by this
ServiceObjects
object.
Throws: - IllegalStateException – If the BundleContext used to create this
ServiceObjects
object is no longer valid. - IllegalArgumentException – If the specified service was not provided by this
ServiceObjects
object.
See Also:
/**
* Releases a service object for the {@link #getServiceReference()
* referenced} service.
*
* <p>
* 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.
*
* <p>
* For a prototype scope service, the following steps are required to
* release the service object:
* <ol>
* <li>If the referenced service has been unregistered, this method returns
* without doing anything.</li>
* <li>The
* {@link PrototypeServiceFactory#ungetService(Bundle, ServiceRegistration, Object)}
* method is called to release the specified service object.</li>
* </ol>
*
* <p>
* 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 ServiceReference
for the service associated with this ServiceObjects
object. Returns: The ServiceReference
for the service associated with this ServiceObjects
object.
/**
* 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<S> getServiceReference() {
return reference;
}
}