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
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
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
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,
138 resourceFilterFactories.get(),
139 providers);
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 }