View Javadoc

1   package com.atlassian.plugins.rest.module;
2   
3   import com.atlassian.plugin.module.ContainerManagedPlugin;
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.AcceptLanguageFilter;
18  import com.atlassian.plugins.rest.module.filter.CorsAcceptOptionsPreflightFilter;
19  import com.atlassian.plugins.rest.module.json.JsonWithPaddingResponseFilter;
20  import com.google.common.collect.ImmutableList;
21  import com.google.common.collect.Lists;
22  import com.sun.jersey.api.core.ResourceConfig;
23  import com.sun.jersey.spi.container.ContainerRequestFilter;
24  import com.sun.jersey.spi.container.ContainerResponseFilter;
25  import com.sun.jersey.spi.container.ResourceFilterFactory;
26  import com.sun.jersey.spi.container.ResourceMethodDispatchProvider;
27  import com.sun.jersey.spi.inject.InjectableProvider;
28  import com.sun.jersey.spi.template.TemplateProcessor;
29  
30  import org.codehaus.jackson.map.Module;
31  import org.osgi.framework.Bundle;
32  import org.osgi.framework.BundleContext;
33  import org.osgi.framework.ServiceReference;
34  
35  import javax.ws.rs.ext.MessageBodyReader;
36  
37  import java.util.Arrays;
38  import java.util.Collection;
39  import java.util.Collections;
40  import java.util.List;
41  import java.util.Map;
42  import java.util.Set;
43  
44  import static com.atlassian.plugins.rest.module.json.JsonWithPaddingResponseFilter.ATLASSIAN_ALLOW_JSONP;
45  import static com.google.common.collect.Lists.newArrayList;
46  
47  public class ResourceConfigManager {
48      private final OsgiServiceAccessor<ResourceFilterFactory> resourceFilterFactories;
49      private final OsgiServiceAccessor<InjectableProvider> injectableProviders;
50      private final OsgiServiceAccessor<TemplateProcessor> templateProcessors;
51      private final OsgiServiceAccessor<MessageBodyReader> messageBodyReaders;
52      private final OsgiServiceAccessor<ResourceMethodDispatchProvider> dispatchProviders;
53      private final OsgiServiceAccessor<Module> modules;
54      private final ContainerManagedPlugin plugin;
55      private final Bundle bundle;
56  
57      public ResourceConfigManager(ContainerManagedPlugin plugin, Bundle bundle) {
58          this.plugin = plugin;
59          this.bundle = bundle;
60          BundleContext bundleContext = bundle.getBundleContext();
61  
62          // looking up resource filters
63          resourceFilterFactories = new OsgiServiceAccessor<ResourceFilterFactory>(ResourceFilterFactory.class, bundleContext, new OsgiFactory<ResourceFilterFactory>() {
64              public ResourceFilterFactory getInstance(BundleContext bundleContext, ServiceReference serviceReference) {
65                  return new OsgiServiceReferenceResourceFilterFactory(bundleContext, serviceReference);
66              }
67          });
68  
69          // looking up injectable providers
70          injectableProviders = new OsgiServiceAccessor<InjectableProvider>(InjectableProvider.class, bundleContext, new OsgiFactory<InjectableProvider>() {
71              public InjectableProvider getInstance(BundleContext bundleContext, ServiceReference serviceReference) {
72                  return (InjectableProvider) bundleContext.getService(serviceReference);
73              }
74          });
75  
76          templateProcessors = new OsgiServiceAccessor<TemplateProcessor>(TemplateProcessor.class, bundleContext, new OsgiFactory<TemplateProcessor>() {
77              public TemplateProcessor getInstance(BundleContext bundleContext, ServiceReference serviceReference) {
78                  return (TemplateProcessor) bundleContext.getService(serviceReference);
79              }
80          });
81  
82          messageBodyReaders = new OsgiServiceAccessor<MessageBodyReader>(MessageBodyReader.class, bundleContext, new OsgiFactory<MessageBodyReader>() {
83              public MessageBodyReader getInstance(final BundleContext bundleContext, final ServiceReference serviceReference) {
84                  return (MessageBodyReader) bundleContext.getService(serviceReference);
85              }
86          });
87  
88          dispatchProviders = new OsgiServiceAccessor<ResourceMethodDispatchProvider>(ResourceMethodDispatchProvider.class, bundleContext, new OsgiFactory<ResourceMethodDispatchProvider>() {
89              public ResourceMethodDispatchProvider getInstance(final BundleContext bundleContext, final ServiceReference serviceReference) {
90                  return (ResourceMethodDispatchProvider) bundleContext.getService(serviceReference);
91              }
92          });
93  
94          modules = new OsgiServiceAccessor<Module>(Module.class, bundleContext, new OsgiFactory<Module>() {
95              public Module getInstance(final BundleContext bundleContext, final ServiceReference serviceReference) {
96                  return (Module) bundleContext.getService(serviceReference);
97              }
98          });
99      }
100 
101     public ResourceConfig createResourceConfig(Map<String, Object> props, String[] excludes, Set<String> packages) {
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(
123                 new ExtensionJerseyFilter(excludesCollection),
124                 new AcceptHeaderJerseyMvcFilter(),
125                 new AcceptLanguageFilter(),
126                 new CorsAcceptOptionsPreflightFilter()
127         );
128 
129         ImmutableList.Builder containerResponseFilters =
130                 new ImmutableList.Builder<ContainerResponseFilter>();
131         containerResponseFilters.add(new AntiSniffingResponseFilter());
132 
133         if ("true".equals(System.getProperty(ATLASSIAN_ALLOW_JSONP))) {
134             containerResponseFilters.add(new JsonWithPaddingResponseFilter());
135         }
136 
137         return new OsgiResourceConfig(bundle, packages,
138                 containerRequestFilters,
139                 containerResponseFilters.build(), // response filters
140                 resourceFilterFactories.get(), // resource filters
141                 modules.get(),
142                 providers); // provider instances
143     }
144 
145     public void destroy() {
146         resourceFilterFactories.release();
147         injectableProviders.release();
148         templateProcessors.release();
149         messageBodyReaders.release();
150         dispatchProviders.release();
151         modules.release();
152     }
153 
154 
155 }