blob: 5862042020f3aaa23a3c5d9caf619585e957597f [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 1997-2011 by ProSyst Software GmbH
* http://www.prosyst.com
* 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:
* ProSyst Software GmbH - initial API and implementation
* Joerg-Christian Boehme - bug.id = 246757
*******************************************************************************/
package org.eclipse.equinox.internal.ds.impl;
import java.util.Dictionary;
import java.util.Vector;
import org.eclipse.equinox.internal.ds.*;
import org.eclipse.equinox.internal.ds.model.*;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.*;
import org.osgi.service.component.*;
/**
* ComponentContextImpl.java
*
* @author Valentin Valchev, Nina Ruseva
* @author Stoyan Boshev
* @author Pavlin Dobrev
*/
public class ComponentContextImpl implements ComponentContext {
/* ComponentInstance instance */
private ComponentInstanceImpl componentInstance;
/* ComponentDescription */
private ServiceComponentProp scp;
private Bundle usingBundle;
private SCRManager mgr;
public ComponentContextImpl(ServiceComponentProp scp, Bundle usingBundle, ComponentInstanceImpl ci, SCRManager mgr) {
this.scp = scp;
this.componentInstance = ci;
this.usingBundle = usingBundle;
this.mgr = mgr;
}
/*
* (non-Javadoc)
*
* @see org.osgi.service.component.ComponentContext#getProperties()
*/
public Dictionary getProperties() {
return scp.getProperties();
}
/*
* (non-Javadoc) Returns the service object for the specified service
* reference name.
*
* @param name The name of a service reference as specified in a <code>reference</code>
* element in this component's description. @return A service object for the
* referenced service or <code>null</code> if the reference cardinality is
* <code>0..1</code> or <code>0..n</code> and no matching service is
* available. @throws ComponentException If the Service Component Runtime
* catches an exception while activating the target service.
*
* @see org.osgi.service.component.ComponentContext#locateService(java.lang.String)
*/
public Object locateService(String name) {
if (scp.references == null) {
return null;
}
if (Activator.DEBUG) {
Activator.log.debug("ComponentContextImpl.locateService(): " + name, null); //$NON-NLS-1$
}
Vector references = scp.references;
for (int i = 0; i < references.size(); i++) {
Reference reference = (Reference) references.elementAt(i);
ComponentReference ref = reference.reference;
// find the Reference Description with the specified name
if (ref.name.equals(name)) {
ServiceReference serviceReference = null;
synchronized (ref.serviceReferences) {
if (ref.serviceReferences.size() == 1) {
//in case of there is only one bound service (or the reference is unary)
serviceReference = (ServiceReference) ref.serviceReferences.keys().nextElement();
}
}
try {
if (serviceReference == null) {
Vector boundServiceReferences = reference.getBoundServiceReferences();
if (reference.isUnary() && boundServiceReferences.size() > 0) {
//get the bound service reference for the unary reference
serviceReference = (ServiceReference) boundServiceReferences.elementAt(0);
}
if (serviceReference == null) {
// try to find service in the FW
ServiceReference[] serviceReferences = scp.bc.getServiceReferences(ref.interfaceName, reference.getTarget());
if (serviceReferences != null && serviceReferences.length > 0) {
// the services references are sorted by
// service.reference and service.id
// so get the first one in the list
serviceReference = serviceReferences[0];
}
}
}
if (serviceReference != null) {
return getBoundService(reference, serviceReference);
}
} catch (Throwable t) {
if (t instanceof ComponentException) {
throw (ComponentException) t;
}
throw new ComponentException(NLS.bind(Messages.EXCEPTION_LOCATING_SERVICE, name), t);
}
if (Activator.DEBUG) {
Activator.log.debug("ComponentContextImpl.locateService(): error, service not found - " + ref.interfaceName + "; the comp. context belongs to " + scp.name, null); //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
return null;
}
/*
* Returns the service objects for the specified service reference name.
*
* @param name The name of a service reference as specified in a <code>reference</code>
* element in this component's description. @return An array of service
* objects for the referenced service or <code>null</code> if the
* reference cardinality is <code>0..1</code> or <code>0..n</code> and
* no matching service is available.
*
* @throws ComponentException If the Service Component Runtime catches an
* exception while activating a target service.
*
* @see org.osgi.service.component.ComponentContext#locateServices(java.lang.String)
*/
public Object[] locateServices(String name) {
if (scp.references == null) {
return null;
}
if (Activator.DEBUG) {
Activator.log.debug("ComponentContextImpl.locateServices(): " + name, null); //$NON-NLS-1$
}
Vector references = scp.references;
for (int i = 0; i < references.size(); i++) {
Reference reference = (Reference) references.elementAt(i);
ComponentReference ref = reference.reference;
if (ref.name.equals(name)) {
ServiceReference[] serviceReferences = null;
try {
if (reference.isUnary()) {
ServiceReference serviceReference = null;
synchronized (ref.serviceReferences) {
if (ref.serviceReferences.size() > 0) {
//in case the reference is unary
serviceReference = (ServiceReference) ref.serviceReferences.keys().nextElement();
}
}
if (serviceReference == null) {
Vector boundServiceReferences = reference.getBoundServiceReferences();
if (boundServiceReferences.size() > 0) {
//get the bound service reference for the unary reference
serviceReference = (ServiceReference) boundServiceReferences.elementAt(0);
}
}
if (serviceReference != null) {
Object result = getBoundService(reference, serviceReference);
if (result != null) {
return new Object[] {result};
}
}
}
serviceReferences = scp.bc.getServiceReferences(ref.interfaceName, reference.getTarget());
if (serviceReferences != null) {
Vector theServices = new Vector(5);
Object service;
for (int j = 0; j < serviceReferences.length; j++) {
service = getBoundService(reference, serviceReferences[j]);
if (service != null) {
theServices.addElement(service);
}
}
if (!theServices.isEmpty()) {
return theServices.toArray();
}
}
} catch (Throwable t) {
if (t instanceof ComponentException) {
throw (ComponentException) t;
}
throw new ComponentException(NLS.bind(Messages.EXCEPTION_LOCATING_SERVICES, name), t);
}
}
}
return null;
}
/*
* (non-Javadoc)
*
* @see org.osgi.service.component.ComponentContext#locateService(String
* name, ServiceReference reference)
*/
public Object locateService(String name, ServiceReference serviceReference) {
if (scp.references == null) {
return null;
}
if (Activator.DEBUG) {
Activator.log.debug("ComponentContextImpl.locateService(): " + name + " by service reference : " + serviceReference, null); //$NON-NLS-1$ //$NON-NLS-2$
}
Vector references = scp.references;
try {
for (int i = 0; i < references.size(); i++) {
Reference reference = (Reference) references.elementAt(i);
ComponentReference ref = reference.reference;
if (ref.name.equals(name)) {
if (serviceReference == null || !ref.serviceReferences.containsKey(serviceReference)) {
// the serviceReference is not bound to the specified
// reference
if (Activator.DEBUG) {
String referenceToString = (serviceReference == null) ? null : serviceReference.toString();
Activator.log.debug("ComponentContextImpl.locateService(): the specified service reference is not bound to the specified reference" + referenceToString, null); //$NON-NLS-1$
}
return null;
}
return getBoundService(reference, serviceReference);
}
}
} catch (Throwable t) {
if (t instanceof ComponentException) {
throw (ComponentException) t;
}
throw new ComponentException(NLS.bind(Messages.EXCEPTION_LOCATING_SERVICE, name), t);
}
return null;
}
private Object getBoundService(Reference reference, ServiceReference theServiceReference) {
Object result = componentInstance.bindedServices.get(theServiceReference);
if (result != null) {
// will skip the circularity checking in InstanceProcess.getService
return result;
}
result = InstanceProcess.staticRef.getService(reference, theServiceReference);
// the service object could be null because of circularity
if (result != null) {
componentInstance.bindedServices.put(theServiceReference, result);
return result;
}
return null;
}
/*
* (non-Javadoc)
*
* @see org.osgi.service.component.ComponentContext#getBundleContext()
*/
public BundleContext getBundleContext() {
return scp.bc;
}
/*
* (non-Javadoc)
*
* @see org.osgi.service.component.ComponentContext#getUsingBundle()
*/
public Bundle getUsingBundle() {
// this is only for service factories!
ServiceComponent componentDescription = scp.serviceComponent;
if ((componentDescription.provides == null) || (!componentDescription.serviceFactory)) {
return null;
}
return usingBundle;
}
/*
* (non-Javadoc)
*
* @see org.osgi.service.component.ComponentContext#getComponentInstance()
*/
public ComponentInstance getComponentInstance() {
return componentInstance;
}
/*
* (non-Javadoc)
*
* @see org.osgi.service.component.ComponentContext#enableComponent(java.lang.String)
*/
public void enableComponent(String name) {
mgr.enableComponent(name, scp.bc.getBundle());
}
/*
* (non-Javadoc)
*
* @see org.osgi.service.component.ComponentContext#disableComponent(java.lang.String)
*/
public void disableComponent(String name) {
if (name == null) {
throw new IllegalArgumentException(Messages.COMPONENT_NAME_IS_NULL);
}
mgr.disableComponent(name, scp.bc.getBundle());
}
/*
* (non-Javadoc)
*
* @see org.osgi.service.component.ComponentContext#getServiceReference()
*/
public ServiceReference getServiceReference() {
if (scp.serviceComponent.provides != null) {
ServiceRegistration reg = scp.registration;
if (reg != null) {
return reg.getReference();
}
}
return null;
}
}