View Javadoc

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   * <p>The OSGi component provider factory.</p>
23   * <p>This will support <em>user defined</em> resources and providers only.</p>
24   */
25  public class OsgiComponentProviderFactory implements IoCComponentProviderFactory
26  {
27      // Classes that are added to the resource config that we can't autowire.
28      private static final Set<Class<?>> EXCLUDE = ImmutableSet.<Class<?>>of(JSPTemplateProcessor.class);
29      
30      /**
31       * The plugin that this factory belongs to.
32       */
33      private final AutowireCapablePlugin plugin;
34  
35      /**
36       * The set of <em>user defined</em> resources and providers.
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          // get the "user defined" resource and provider classes
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             // If the class is annotated with PerRequest, then it should return per request, otherwise,
113             // default to singleton
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 }