1 package com.atlassian.plugins.rest.module;
2
3 import java.util.Collections;
4 import java.util.Set;
5
6 import com.atlassian.plugin.AutowireCapablePlugin;
7
8 import com.google.common.base.Preconditions;
9 import com.google.common.collect.ImmutableSet;
10 import com.sun.jersey.api.core.ResourceConfig;
11 import com.sun.jersey.core.spi.component.ComponentContext;
12 import com.sun.jersey.core.spi.component.ComponentScope;
13 import com.sun.jersey.core.spi.component.ioc.IoCComponentProvider;
14 import com.sun.jersey.core.spi.component.ioc.IoCComponentProviderFactory;
15 import com.sun.jersey.core.spi.component.ioc.IoCManagedComponentProvider;
16 import com.sun.jersey.server.impl.container.servlet.JSPTemplateProcessor;
17 import com.sun.jersey.spi.resource.PerRequest;
18
19 import static com.google.common.collect.Sets.difference;
20
21
22
23
24
25 public class OsgiComponentProviderFactory implements IoCComponentProviderFactory
26 {
27
28 private static final Set<Class<?>> EXCLUDE = ImmutableSet.<Class<?>>of(JSPTemplateProcessor.class);
29
30
31
32
33 private final AutowireCapablePlugin plugin;
34
35
36
37
38 private final Set<Class<?>> classes;
39
40 private final Set<?> instances;
41
42 public OsgiComponentProviderFactory(ResourceConfig resourceConfig, AutowireCapablePlugin plugin)
43 {
44 this.plugin = Preconditions.checkNotNull(plugin);
45
46
47 final Set<Class<?>> classes = Preconditions.checkNotNull(resourceConfig).getClasses();
48 if (classes != null)
49 {
50 this.classes = difference(ImmutableSet.copyOf(classes), EXCLUDE);
51 }
52 else
53 {
54 this.classes = Collections.emptySet();
55 }
56
57 if (resourceConfig instanceof OsgiResourceConfig)
58 {
59 instances = ((OsgiResourceConfig) resourceConfig).getInstances();
60 }
61 else
62 {
63 instances = Collections.emptySet();
64 }
65 }
66
67 public IoCComponentProvider getComponentProvider(final Class<?> c)
68 {
69 return getComponentProvider(null, c);
70 }
71
72 public IoCComponentProvider getComponentProvider(ComponentContext cc, Class<?> c)
73 {
74 if (!classes.contains(c))
75 {
76 return null;
77 }
78 final Object instance = getInstance(c);
79 return instance == null ? new AutowiredOsgiComponentProvider(plugin, c) : new InstanceOsgiComponentProvider(instance);
80 }
81
82 private Object getInstance(Class<?> c)
83 {
84 for (Object o : instances)
85 {
86 if (o.getClass().equals(c))
87 {
88 return o;
89 }
90 }
91 return null;
92 }
93
94 private static class AutowiredOsgiComponentProvider implements IoCManagedComponentProvider
95 {
96 private final AutowireCapablePlugin plugin;
97 private final Class<?> componentClass;
98
99 public AutowiredOsgiComponentProvider(AutowireCapablePlugin plugin, Class<?> componentClass)
100 {
101 this.plugin = plugin;
102 this.componentClass = componentClass;
103 }
104
105 public Object getInstance()
106 {
107 return plugin.autowire(componentClass);
108 }
109
110 public ComponentScope getScope()
111 {
112
113
114 if (componentClass.getAnnotation(PerRequest.class) != null)
115 {
116 return ComponentScope.PerRequest;
117 }
118 return ComponentScope.Singleton;
119 }
120
121 public Object getInjectableInstance(Object o)
122 {
123 plugin.autowire(o);
124 return o;
125 }
126 }
127
128 private static class InstanceOsgiComponentProvider implements IoCManagedComponentProvider
129 {
130 private final Object instance;
131
132 public InstanceOsgiComponentProvider(Object instance)
133 {
134 this.instance = Preconditions.checkNotNull(instance);
135 }
136
137 public ComponentScope getScope()
138 {
139 return ComponentScope.Singleton;
140 }
141
142 public Object getInstance()
143 {
144 return instance;
145 }
146
147 public Object getInjectableInstance(Object o)
148 {
149 return o;
150 }
151 }
152 }