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.module.ContainerManagedPlugin;
7   import com.google.common.base.Preconditions;
8   import com.google.common.collect.ImmutableSet;
9   import com.sun.jersey.api.core.ResourceConfig;
10  import com.sun.jersey.core.spi.component.ComponentContext;
11  import com.sun.jersey.core.spi.component.ComponentScope;
12  import com.sun.jersey.core.spi.component.ioc.IoCComponentProvider;
13  import com.sun.jersey.core.spi.component.ioc.IoCComponentProviderFactory;
14  import com.sun.jersey.core.spi.component.ioc.IoCManagedComponentProvider;
15  import com.sun.jersey.server.impl.container.servlet.JSPTemplateProcessor;
16  import com.sun.jersey.spi.resource.PerRequest;
17  
18  import static com.google.common.collect.Sets.difference;
19  
20  /**
21   * <p>The OSGi component provider factory.</p>
22   * <p>This will support <em>user defined</em> resources and providers only.</p>
23   */
24  public class OsgiComponentProviderFactory implements IoCComponentProviderFactory {
25      // Classes that are added to the resource config that we can't autowire.
26      private static final Set<Class<?>> EXCLUDE = ImmutableSet.<Class<?>>of(JSPTemplateProcessor.class);
27  
28      /**
29       * The plugin that this factory belongs to.
30       */
31      private final ContainerManagedPlugin plugin;
32  
33      /**
34       * The set of <em>user defined</em> resources and providers.
35       */
36      private final Set<Class<?>> classes;
37  
38      private final Set<?> instances;
39  
40      public OsgiComponentProviderFactory(ResourceConfig resourceConfig, ContainerManagedPlugin plugin) {
41          this.plugin = Preconditions.checkNotNull(plugin);
42  
43          // get the "user defined" resource and provider classes
44          final Set<Class<?>> classes = Preconditions.checkNotNull(resourceConfig).getClasses();
45          if (classes != null) {
46              this.classes = difference(ImmutableSet.copyOf(classes), EXCLUDE);
47          } else {
48              this.classes = Collections.emptySet();
49          }
50  
51          if (resourceConfig instanceof OsgiResourceConfig) {
52              instances = ((OsgiResourceConfig) resourceConfig).getInstances();
53          } else {
54              instances = Collections.emptySet();
55          }
56      }
57  
58      public IoCComponentProvider getComponentProvider(final Class<?> c) {
59          return getComponentProvider(null, c);
60      }
61  
62      public IoCComponentProvider getComponentProvider(ComponentContext cc, Class<?> c) {
63          if (!classes.contains(c)) {
64              return null;
65          }
66          final Object instance = getInstance(c);
67          return instance == null ? new ContainerManagedComponentProvider(plugin, c) : new InstanceOsgiComponentProvider(instance);
68      }
69  
70      private Object getInstance(Class<?> c) {
71          for (Object o : instances) {
72              if (o.getClass().equals(c)) {
73                  return o;
74              }
75          }
76          return null;
77      }
78  
79      private static class ContainerManagedComponentProvider implements IoCManagedComponentProvider {
80          private final ContainerManagedPlugin plugin;
81          private final Class<?> componentClass;
82  
83          public ContainerManagedComponentProvider(ContainerManagedPlugin plugin, Class<?> componentClass) {
84              this.plugin = plugin;
85              this.componentClass = componentClass;
86          }
87  
88          public Object getInstance() {
89              return plugin.getContainerAccessor().createBean(componentClass);
90          }
91  
92          public ComponentScope getScope() {
93              // If the class is annotated with PerRequest, then it should return per request, otherwise,
94              // default to singleton
95              if (componentClass.getAnnotation(PerRequest.class) != null) {
96                  return ComponentScope.PerRequest;
97              }
98              return ComponentScope.Singleton;
99          }
100 
101         public Object getInjectableInstance(Object o) {
102             plugin.getContainerAccessor().injectBean(o);
103             return o;
104         }
105     }
106 
107     private static class InstanceOsgiComponentProvider implements IoCManagedComponentProvider {
108         private final Object instance;
109 
110         public InstanceOsgiComponentProvider(Object instance) {
111             this.instance = Preconditions.checkNotNull(instance);
112         }
113 
114         public ComponentScope getScope() {
115             return ComponentScope.Singleton;
116         }
117 
118         public Object getInstance() {
119             return instance;
120         }
121 
122         public Object getInjectableInstance(Object o) {
123             return o;
124         }
125     }
126 }