package org.osgi.cdi.impl.extension.services;
import java.io.File;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Proxy;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.enterprise.inject.New;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.InjectionPoint;
import org.osgi.cdi.api.extension.BundleState;
import org.osgi.cdi.api.extension.Registrations;
import org.osgi.cdi.api.extension.Service;
import org.osgi.cdi.api.extension.annotation.BundleDataFile;
import org.osgi.cdi.api.extension.annotation.BundleHeader;
import org.osgi.cdi.api.extension.annotation.BundleHeaders;
import org.osgi.cdi.api.extension.annotation.OSGiBundle;
import org.osgi.cdi.api.extension.annotation.Required;
import org.osgi.cdi.impl.extension.CDIOSGiExtension;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Version;
/**
* Producers for Specific injected types;
*
* @author Mathieu ANCELIN - SERLI (mathieu.ancelin@serli.com)
*/
public class WeldOSGiProducer {
@Produces
public BundleState getBundleState(BundleHolder holder) {
return holder.getState();
}
@Produces
public Bundle getBundle(BundleHolder holder, InjectionPoint p) {
return holder.getBundle();
}
@Produces @OSGiBundle("")
public Bundle getSpecificBundle(BundleHolder holder, InjectionPoint p) {
Set<Annotation> qualifiers = p.getQualifiers();
OSGiBundle bundle = null;
for (Annotation qualifier : qualifiers) {
if (qualifier.annotationType().equals(OSGiBundle.class)) {
bundle = (OSGiBundle) qualifier;
break;
}
}
if (bundle.value().equals("")) {
return getBundle(holder, p);
}
return (Bundle) Proxy.newProxyInstance(getClass().getClassLoader(),
new Class[] {Bundle.class},
new BundleHandler(bundle.value(), bundle.version(), holder.getContext()));
}
@Produces
public BundleContext getBundleContext(BundleHolder holder, InjectionPoint p) {
return holder.getContext();
}
@Produces @BundleDataFile("")
public File getDataFile(BundleHolder holder, InjectionPoint p) {
Set<Annotation> qualifiers = p.getQualifiers();
BundleDataFile file = null;
for (Annotation qualifier : qualifiers) {
if (qualifier.annotationType().equals(BundleDataFile.class)) {
file = (BundleDataFile) qualifier;
break;
}
}
if (file.value().equals("")) {
return null;
}
return holder.getContext().getDataFile(file.value());
}
@Produces @Required
public <T> Service<T> getOSGiRequiredService(BundleHolder holder,
CDIOSGiExtension extension, InjectionPoint p) {
extension.getRequiredOsgiServiceDependencies().add((Class)
((ParameterizedType) p.getType()).getActualTypeArguments()[0]);
return getOSGiService(holder, p);
}
@Produces
public <T> Service<T> getOSGiService(BundleHolder holder, InjectionPoint p) {
return new ServiceImpl<T>(((ParameterizedType)p.getType()).getActualTypeArguments()[0],
holder.getContext());
}
@Produces
public <T> Registrations<T> getRegistrations(
@New RegistrationsImpl registration,
BundleHolder bundleHolder,
RegistrationsHolder holder,
InjectionPoint p) {
registration.setType(((Class<T>) ((ParameterizedType)p.getType()).getActualTypeArguments()[0]));
registration.setHolder(holder);
registration.setRegistry(bundleHolder.getContext());
registration.setBundle(bundleHolder.getBundle());
return registration;
}
@Produces @BundleHeaders
public Map<String, String> getBundleHeaders(BundleHolder holder) {
Dictionary dict = holder.getBundle().getHeaders();
Map<String, String> headers = new HashMap<String, String>();
Enumeration<String> keys = dict.keys();
while(keys.hasMoreElements()) {
String key = keys.nextElement();
headers.put(key, (String) dict.get(key));
}
return headers;
}
@Produces @BundleHeader("")
public String getSpecificBundleHeaders(BundleHolder holder, InjectionPoint p) {
Set<Annotation> qualifiers = p.getQualifiers();
BundleHeader headers = null;
for (Annotation qualifier : qualifiers) {
if (qualifier.annotationType().equals(BundleHeader.class)) {
headers = (BundleHeader) qualifier;
break;
}
}
if (headers == null) {
throw new IllegalStateException("You must specify a key for your BundleHeaders qualifier");
}
if (headers.value().equals("")) {
return null; // not cool at all but should never happened ...
}
return (String) holder.getBundle().getHeaders().get(headers.value());
}
private static class BundleHandler implements InvocationHandler {
private final String symbolicName;
private Version version;
private final BundleContext context;
public BundleHandler(String symbolicName, String version, BundleContext context) {
this.symbolicName = symbolicName;
this.context = context;
if (!version.equals("")) {
this.version = new Version(version);
}
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Bundle bundle = null;
Bundle[] bundles = context.getBundles();
if (bundles != null) {
for (Bundle b : bundles) {
if (bundle != null) {
if (b.getSymbolicName().equals(symbolicName)) {
if (version != null) {
if (version.equals(b.getVersion())) {
bundle = b;
break;
}
} else {
bundle = b;
break;
}
}
}
}
}
if (bundle == null) {
System.out.println("Bundle " + symbolicName + " is unavailable.");
return null;
}
return method.invoke(bundle, args);
}
}
}