View Javadoc

1   package com.atlassian.plugins.rest.module;
2   
3   import com.atlassian.plugin.AutowireCapablePlugin;
4   import com.atlassian.plugins.rest.common.expand.SelfExpandingExpander;
5   import com.atlassian.plugins.rest.common.expand.interceptor.ExpandInterceptor;
6   import com.atlassian.plugins.rest.common.expand.resolver.ChainingEntityExpanderResolver;
7   import com.atlassian.plugins.rest.common.expand.resolver.CollectionEntityExpanderResolver;
8   import com.atlassian.plugins.rest.common.expand.resolver.EntityExpanderResolver;
9   import com.atlassian.plugins.rest.common.expand.resolver.ExpandConstraintEntityExpanderResolver;
10  import com.atlassian.plugins.rest.common.expand.resolver.IdentityEntityExpanderResolver;
11  import com.atlassian.plugins.rest.common.expand.resolver.ListWrapperEntityExpanderResolver;
12  import com.atlassian.plugins.rest.common.filter.ExtensionJerseyFilter;
13  import com.atlassian.plugins.rest.common.interceptor.impl.InterceptorChainBuilderProvider;
14  import com.atlassian.plugins.rest.module.expand.resolver.PluginEntityExpanderResolver;
15  import com.atlassian.plugins.rest.module.filter.AcceptHeaderJerseyMvcFilter;
16  import com.atlassian.plugins.rest.module.filter.CorsAcceptOptionsPreflightFilter;
17  import com.atlassian.plugins.rest.module.json.JsonWithPaddingResponseFilter;
18  import com.google.common.collect.Lists;
19  import com.sun.jersey.api.core.ResourceConfig;
20  import com.sun.jersey.spi.container.ContainerRequestFilter;
21  import com.sun.jersey.spi.container.ContainerResponseFilter;
22  import com.sun.jersey.spi.container.ResourceFilterFactory;
23  import com.sun.jersey.spi.container.ResourceMethodDispatchProvider;
24  import com.sun.jersey.spi.inject.InjectableProvider;
25  import com.sun.jersey.spi.template.TemplateProcessor;
26  import org.osgi.framework.Bundle;
27  import org.osgi.framework.BundleContext;
28  import org.osgi.framework.ServiceReference;
29  
30  import javax.ws.rs.ext.MessageBodyReader;
31  import java.util.Arrays;
32  import java.util.Collection;
33  import java.util.Collections;
34  import java.util.List;
35  import java.util.Map;
36  import java.util.Set;
37  
38  import static com.atlassian.plugins.rest.module.json.JsonWithPaddingResponseFilter.ATLASSIAN_ALLOW_JSONP;
39  import static com.google.common.collect.Lists.newArrayList;
40  
41  public class ResourceConfigManager
42  {
43      private final OsgiServiceAccessor<ResourceFilterFactory> resourceFilterFactories;
44      private final OsgiServiceAccessor<InjectableProvider> injectableProviders;
45      private final OsgiServiceAccessor<TemplateProcessor> templateProcessors;
46      private final OsgiServiceAccessor<MessageBodyReader> messageBodyReaders;
47      private final OsgiServiceAccessor<ResourceMethodDispatchProvider> dispatchProviders;
48      private final AutowireCapablePlugin plugin;
49      private final Bundle bundle;
50  
51      public ResourceConfigManager(AutowireCapablePlugin plugin, Bundle bundle)
52      {
53          this.plugin = plugin;
54          this.bundle = bundle;
55          BundleContext bundleContext = bundle.getBundleContext();
56  
57          // looking up resource filters
58          resourceFilterFactories = new OsgiServiceAccessor<ResourceFilterFactory>(ResourceFilterFactory.class, bundleContext, new OsgiFactory<ResourceFilterFactory>()
59          {
60              public ResourceFilterFactory getInstance(BundleContext bundleContext, ServiceReference serviceReference)
61              {
62                  return new OsgiServiceReferenceResourceFilterFactory(bundleContext, serviceReference);
63              }
64          });
65  
66          // looking up injectable providers
67          injectableProviders = new OsgiServiceAccessor<InjectableProvider>(InjectableProvider.class, bundleContext, new OsgiFactory<InjectableProvider>()
68          {
69              public InjectableProvider getInstance(BundleContext bundleContext, ServiceReference serviceReference)
70              {
71                  return (InjectableProvider) bundleContext.getService(serviceReference);
72              }
73          });
74  
75          templateProcessors = new OsgiServiceAccessor<TemplateProcessor>(TemplateProcessor.class, bundleContext, new OsgiFactory<TemplateProcessor>()
76          {
77              public TemplateProcessor getInstance(BundleContext bundleContext, ServiceReference serviceReference)
78              {
79                  return (TemplateProcessor) bundleContext.getService(serviceReference);
80              }
81          });
82  
83          messageBodyReaders = new OsgiServiceAccessor<MessageBodyReader>(MessageBodyReader.class, bundleContext, new OsgiFactory<MessageBodyReader>()
84          {
85              public MessageBodyReader getInstance(final BundleContext bundleContext, final ServiceReference serviceReference)
86              {
87                  return (MessageBodyReader) bundleContext.getService(serviceReference);
88              }
89          });
90  
91          dispatchProviders = new OsgiServiceAccessor<ResourceMethodDispatchProvider>(ResourceMethodDispatchProvider.class, bundleContext, new OsgiFactory<ResourceMethodDispatchProvider>()
92          {
93              public ResourceMethodDispatchProvider getInstance(final BundleContext bundleContext, final ServiceReference serviceReference)
94              {
95                  return (ResourceMethodDispatchProvider) bundleContext.getService(serviceReference);
96              }
97          });
98      }
99  
100     public ResourceConfig createResourceConfig(Map<String, Object> props, String[] excludes, Set<String> packages)
101     {
102         // get the excludes parameter
103         final Collection<String> excludesCollection = excludes != null ? Arrays.asList(excludes) : Collections.<String>emptyList();
104 
105         final EntityExpanderResolver expanderResolver = new ChainingEntityExpanderResolver(Lists.<EntityExpanderResolver>newArrayList(
106                 new PluginEntityExpanderResolver(plugin),
107                 new CollectionEntityExpanderResolver(),
108                 new ListWrapperEntityExpanderResolver(),
109                 new ExpandConstraintEntityExpanderResolver(),
110                 new SelfExpandingExpander.Resolver(),
111                 new IdentityEntityExpanderResolver()
112         ));
113 
114         final Collection<Object> providers = Lists.newLinkedList();
115         providers.addAll(injectableProviders.get());
116         providers.addAll(templateProcessors.get());
117         providers.addAll(messageBodyReaders.get());
118         providers.addAll(dispatchProviders.get());
119 
120         providers.add(new InterceptorChainBuilderProvider(plugin, new ExpandInterceptor(expanderResolver)));
121 
122         List<ContainerRequestFilter> containerRequestFilters = newArrayList(new ExtensionJerseyFilter(excludesCollection), new AcceptHeaderJerseyMvcFilter(), new CorsAcceptOptionsPreflightFilter());
123 
124         List<ContainerResponseFilter> containerResponseFilters = null;
125 
126         if ("true".equals(System.getProperty(ATLASSIAN_ALLOW_JSONP)))
127         {
128             containerResponseFilters = Lists.<ContainerResponseFilter>newArrayList(new JsonWithPaddingResponseFilter());
129         }
130         else
131         {
132             containerResponseFilters = newArrayList();
133         }
134 
135         return new OsgiResourceConfig(bundle, packages,
136                 containerRequestFilters,
137                 containerResponseFilters, // response filters
138                 resourceFilterFactories.get(), // resource filters
139                 providers); // provider instances
140     }
141 
142     public void destroy()
143     {
144         resourceFilterFactories.release();
145         injectableProviders.release();
146         templateProcessors.release();
147         messageBodyReaders.release();
148         dispatchProviders.release();
149     }
150 
151 
152 }