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