no.steria.osgi.jsr330activator.implementation.ProviderAdapter Maven / Gradle / Ivy
package no.steria.osgi.jsr330activator.implementation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import no.steria.osgi.jsr330activator.Jsr330Activator;
/**
* This class defines the operations done by the {@link Jsr330Activator}
* on the {@link Provider} implementations found inside the bundle.
*
* The operations are starting and stopping the provider.
* Starting the provider means instantiating the provider and causing
* all injections to be satisfied.
*
* @author Steinar Bang
*
*/
public class ProviderAdapter {
private static final Class>[] emptyArgumentTypes = new Class>[0];
private Object provider;
private Type providedServiceType;
private List injections;
private ServiceRegistration> serviceRegistration;
public ProviderAdapter(Type serviceType, Class> providerType) {
try {
providedServiceType = serviceType;
provider = providerType.newInstance();
injections = findInjections(provider);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public Type getProvidedServiceType() {
return providedServiceType;
}
public ServiceRegistration> getServiceRegistration() {
return serviceRegistration;
}
static List findInjections(Object provider) {
List injections = new ArrayList();
Class extends Object> providerType = provider.getClass();
Field[] fields = providerType.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(Inject.class)) {
injections.add(new InjectionField(provider, field));
}
}
Method[] methods = providerType.getDeclaredMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(Inject.class)) {
// Only interested in methods that take exactly one argument
if (method.getGenericParameterTypes().length == 1) {
injections.add(new InjectionMethod(provider, method));
}
}
}
return injections;
}
public boolean hasInjections() {
return injections.size() > 0;
}
public void start(BundleContext bundleContext) {
if (!hasInjections()) {
// No injections means that the service can be made immediately available
registerService(bundleContext);
return;
}
setupInjectionListeners(bundleContext);
checkInjectionsAndRegisterServiceIfSatisfied(bundleContext);
}
public void stop(BundleContext context) {
for (Injection injection : injections) {
injection.unGet(context);
}
unregisterMyService();
}
private void unregisterMyService() {
if (!serviceAlreadyUnregistered()) {
serviceRegistration.unregister();
}
// Make sure this now invalid object isn't used again.
serviceRegistration = null;
}
private boolean serviceAlreadyUnregistered() {
return serviceRegistration == null;
}
void registerService(BundleContext bundleContext) {
try {
Method getMethod = provider.getClass().getMethod("get", emptyArgumentTypes);
Object serviceImpl = getMethod.invoke(provider);
if (providedServiceType instanceof Class) {
Class> service = (Class>)providedServiceType;
String serviceName = service.getCanonicalName();
serviceRegistration = bundleContext.registerService(serviceName, serviceImpl, null);
}
} catch (Exception e) {
}
}
void setupInjectionListeners(BundleContext bundleContext) {
for (Injection injection : injections) {
injection.setupListener(bundleContext, this);
}
}
void checkInjectionsAndRegisterServiceIfSatisfied(BundleContext bundleContext) {
if (getServiceRegistration() == null &&
allInjectionsHaveBeenInjected())
{
registerService(bundleContext);
}
}
void checkInjectionsAndUnregisterServiceIfNotSatisfied(BundleContext bundleContext) {
// Check for service already unregistered first because that is quickest
if (!serviceAlreadyUnregistered() && !allInjectionsHaveBeenInjected()) {
unregisterMyService();
}
}
private boolean allInjectionsHaveBeenInjected() {
boolean isInjected = true;
for (Injection injection : injections) {
isInjected = isInjected & injection.isInjected();
}
return isInjected;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy