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.json.JsonWithPaddingResponseFilter;
17  import com.google.common.collect.Lists;
18  import com.sun.jersey.api.core.ResourceConfig;
19  import com.sun.jersey.server.impl.model.method.dispatch.ResourceMethodDispatchProvider;
20  import com.sun.jersey.spi.container.ResourceFilterFactory;
21  import com.sun.jersey.spi.inject.InjectableProvider;
22  import com.sun.jersey.spi.template.TemplateProcessor;
23  import org.osgi.framework.Bundle;
24  import org.osgi.framework.BundleContext;
25  import org.osgi.framework.ServiceReference;
26  
27  import java.util.Arrays;
28  import java.util.Collection;
29  import java.util.Collections;
30  import java.util.Map;
31  import java.util.Set;
32  import javax.ws.rs.ext.MessageBodyReader;
33  
34  public class ResourceConfigManager
35  {
36      private final OsgiServiceAccessor<ResourceFilterFactory> resourceFilterFactories;
37      private final OsgiServiceAccessor<InjectableProvider> injectableProviders;
38      private final OsgiServiceAccessor<TemplateProcessor> templateProcessors;
39      private final OsgiServiceAccessor<MessageBodyReader> messageBodyReaders;
40      private final OsgiServiceAccessor<ResourceMethodDispatchProvider> dispatchProviders;
41      private final AutowireCapablePlugin plugin;
42      private final Bundle bundle;
43  
44      public ResourceConfigManager(AutowireCapablePlugin plugin, Bundle bundle)
45      {
46          this.plugin = plugin;
47          this.bundle = bundle;
48          BundleContext bundleContext = bundle.getBundleContext();
49  
50          // looking up resource filters
51          resourceFilterFactories = new OsgiServiceAccessor<ResourceFilterFactory>(ResourceFilterFactory.class, bundleContext, new OsgiFactory<ResourceFilterFactory>()
52          {
53              public ResourceFilterFactory getInstance(BundleContext bundleContext, ServiceReference serviceReference)
54              {
55                  return new OsgiServiceReferenceResourceFilterFactory(bundleContext, serviceReference);
56              }
57          });
58  
59          // looking up injectable providers
60          injectableProviders = new OsgiServiceAccessor<InjectableProvider>(InjectableProvider.class, bundleContext, new OsgiFactory<InjectableProvider>()
61          {
62              public InjectableProvider getInstance(BundleContext bundleContext, ServiceReference serviceReference)
63              {
64                  return (InjectableProvider) bundleContext.getService(serviceReference);
65              }
66          });
67  
68          templateProcessors = new OsgiServiceAccessor<TemplateProcessor>(TemplateProcessor.class, bundleContext, new OsgiFactory<TemplateProcessor>()
69          {
70              public TemplateProcessor getInstance(BundleContext bundleContext, ServiceReference serviceReference)
71              {
72                  return (TemplateProcessor) bundleContext.getService(serviceReference);
73              }
74          });
75  
76          messageBodyReaders = new OsgiServiceAccessor<MessageBodyReader>(MessageBodyReader.class, bundleContext, new OsgiFactory<MessageBodyReader>()
77          {
78              public MessageBodyReader getInstance(final BundleContext bundleContext, final ServiceReference serviceReference)
79              {
80                  return (MessageBodyReader) bundleContext.getService(serviceReference);
81              }
82          });
83  
84          dispatchProviders = new OsgiServiceAccessor<ResourceMethodDispatchProvider>(ResourceMethodDispatchProvider.class, bundleContext, new OsgiFactory<ResourceMethodDispatchProvider>()
85          {
86              public ResourceMethodDispatchProvider getInstance(final BundleContext bundleContext, final ServiceReference serviceReference)
87              {
88                  return (ResourceMethodDispatchProvider) bundleContext.getService(serviceReference);
89              }
90          });
91      }
92  
93      public ResourceConfig createResourceConfig(Map<String, Object> props, String[] excludes, Set<String> packages)
94      {
95          // get the excludes parameter
96          final Collection<String> excludesCollection = excludes != null ? Arrays.asList(excludes) : Collections.<String>emptyList();
97  
98          final EntityExpanderResolver expanderResolver = new ChainingEntityExpanderResolver(Lists.<EntityExpanderResolver>newArrayList(
99                  new PluginEntityExpanderResolver(plugin),
100                 new CollectionEntityExpanderResolver(),
101                 new ListWrapperEntityExpanderResolver(),
102                 new ExpandConstraintEntityExpanderResolver(),
103                 new SelfExpandingExpander.Resolver(),
104                 new IdentityEntityExpanderResolver()
105         ));
106 
107         final Collection<Object> providers = Lists.newLinkedList();
108         providers.addAll(injectableProviders.get());
109         providers.addAll(templateProcessors.get());
110         providers.addAll(messageBodyReaders.get());
111         providers.addAll(dispatchProviders.get());
112 
113         providers.add(new InterceptorChainBuilderProvider(plugin, new ExpandInterceptor(expanderResolver)));
114 
115         return new OsgiResourceConfig(bundle, packages, 
116                 Lists.newArrayList(new ExtensionJerseyFilter(excludesCollection), new AcceptHeaderJerseyMvcFilter()), // request filters
117                 Lists.newArrayList(new JsonWithPaddingResponseFilter()), // response filters
118                 resourceFilterFactories.get(), // resource filters
119                 providers); // provider instances
120     }
121 
122     public void destroy()
123     {
124         resourceFilterFactories.release();
125         injectableProviders.release();
126         templateProcessors.release();
127         messageBodyReaders.release();
128         dispatchProviders.release();
129     }
130 
131 
132 }