1 package com.atlassian.plugin.osgi.hostcomponents.impl;
2
3 import org.apache.commons.logging.Log;
4 import org.apache.commons.logging.LogFactory;
5 import org.osgi.framework.BundleContext;
6 import org.osgi.framework.ServiceRegistration;
7
8 import java.util.*;
9 import java.lang.reflect.Proxy;
10 import java.lang.reflect.InvocationHandler;
11 import java.lang.reflect.Method;
12 import java.lang.reflect.InvocationTargetException;
13
14 import com.atlassian.plugin.osgi.hostcomponents.*;
15
16
17
18
19 public class DefaultComponentRegistrar implements ComponentRegistrar
20 {
21 private List<HostComponentRegistration> registry = new ArrayList<HostComponentRegistration>();
22
23 private Log log = LogFactory.getLog(DefaultComponentRegistrar.class);
24
25 public InstanceBuilder register(Class<?>... mainInterfaces)
26 {
27 Registration reg = new Registration(mainInterfaces);
28 registry.add(reg);
29 return new DefaultInstanceBuilder(reg);
30 }
31
32 public List<ServiceRegistration> writeRegistry(BundleContext ctx)
33 {
34 ArrayList<ServiceRegistration> services = new ArrayList<ServiceRegistration>();
35
36 for (HostComponentRegistration reg : registry)
37 {
38 String[] names = reg.getMainInterfaces();
39
40 reg.getProperties().put(HOST_COMPONENT_FLAG, Boolean.TRUE.toString());
41
42 if (log.isDebugEnabled())
43 log.debug("Registering: "+ Arrays.asList(names)+" instance "+reg.getInstance() + "with properties: "+reg.getProperties());
44
45 Object service = reg.getInstance();
46 if (!ContextClassLoaderStrategy.USE_PLUGIN.name().equals(reg.getProperties().get(PropertyBuilder.CONTEXT_CLASS_LOADER_STRATEGY)))
47 service = wrapService(reg.getMainInterfaceClasses(), reg.getInstance());
48
49 ServiceRegistration sreg = ctx.registerService(names, service, reg.getProperties());
50 if (sreg != null)
51 {
52 services.add(sreg);
53 }
54 }
55 return services;
56 }
57
58
59
60
61
62
63
64
65 protected Object wrapService(Class[] interfaces, final Object service)
66 {
67 return Proxy.newProxyInstance(
68 getClass().getClassLoader(),
69 interfaces,
70 new InvocationHandler() {
71 public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
72 final Thread thread = Thread.currentThread();
73 final ClassLoader ccl = thread.getContextClassLoader();
74 try {
75 thread.setContextClassLoader(service.getClass().getClassLoader());
76 return method.invoke(service, objects);
77 } catch (InvocationTargetException e) {
78 throw e.getTargetException();
79 } finally {
80 thread.setContextClassLoader(ccl);
81 }
82 }
83 }
84 );
85 }
86
87 public List<HostComponentRegistration> getRegistry()
88 {
89 return registry;
90 }
91 }