View Javadoc

1   package com.atlassian.plugins.rest.module;
2   
3   import java.util.Collection;
4   import java.util.Collections;
5   import java.util.Set;
6   
7   import javax.ws.rs.Path;
8   import javax.ws.rs.ext.Provider;
9   
10  import org.codehaus.jackson.map.Module;
11  import org.osgi.framework.Bundle;
12  import org.slf4j.Logger;
13  import org.slf4j.LoggerFactory;
14  
15  import com.atlassian.plugins.rest.common.error.jersey.NotFoundExceptionMapper;
16  import com.atlassian.plugins.rest.common.error.jersey.ThrowableExceptionMapper;
17  import com.atlassian.plugins.rest.common.error.jersey.UncaughtExceptionEntityWriter;
18  import com.atlassian.plugins.rest.common.json.JacksonJsonProviderFactory;
19  import com.atlassian.plugins.rest.common.security.jersey.AdminOnlyResourceFilter;
20  import com.atlassian.plugins.rest.common.security.jersey.AuthorisationExceptionMapper;
21  import com.atlassian.plugins.rest.common.security.jersey.SecurityExceptionMapper;
22  import com.atlassian.plugins.rest.common.security.jersey.SysadminOnlyResourceFilter;
23  import com.atlassian.plugins.rest.module.filter.AcceptLanguageFilter;
24  import com.atlassian.plugins.rest.module.scanner.AnnotatedClassScanner;
25  import com.atlassian.plugins.rest.module.xml.XMLStreamReaderContextProvider;
26  import com.google.common.base.Preconditions;
27  import com.google.common.collect.Lists;
28  import com.google.common.collect.Sets;
29  import com.sun.jersey.api.core.DefaultResourceConfig;
30  import com.sun.jersey.api.core.ResourceConfig;
31  import com.sun.jersey.spi.container.ContainerRequestFilter;
32  import com.sun.jersey.spi.container.ContainerResponseFilter;
33  import com.sun.jersey.spi.container.ResourceFilterFactory;
34  
35  /**
36   * An implementation of {@link ResourceConfig} that scans a given Osgi Bundle for Jersey resources ({#link Provider} and {@link Path}.
37   */
38  class OsgiResourceConfig extends DefaultResourceConfig {
39      private final Bundle bundle;
40  
41      @SuppressWarnings("unchecked")
42      private final Set<Class<?>> classes = Sets.newHashSet(
43              NotFoundExceptionMapper.class,
44              AuthorisationExceptionMapper.class,
45              SecurityExceptionMapper.class,
46              ThrowableExceptionMapper.class,
47              SysadminOnlyResourceFilter.class,
48              AdminOnlyResourceFilter.class,
49              UncaughtExceptionEntityWriter.class
50      );
51  
52      private final Set<Object> instances;
53  
54      private Set<Class<?>> scannedClasses;
55      private final String[] packages;
56  
57      OsgiResourceConfig(Bundle bundle,
58                         Set<String> packages,
59                         Collection<? extends ContainerRequestFilter> containerRequestFilters,
60                         Collection<? extends ContainerResponseFilter> containerResponseFilters,
61                         Collection<? extends ResourceFilterFactory> resourceFilterFactories,
62                         Collection<? extends Module> modules,
63                         Collection<?> providers) {
64          this.packages = packages.toArray(new String[packages.size()]);
65          this.bundle = Preconditions.checkNotNull(bundle);
66  
67          // adds "filters" to Jersey
68          getProperties().put(PROPERTY_CONTAINER_REQUEST_FILTERS, Lists.newLinkedList(containerRequestFilters));
69          getProperties().put(PROPERTY_CONTAINER_RESPONSE_FILTERS, Lists.newLinkedList(containerResponseFilters));
70          getProperties().put(PROPERTY_RESOURCE_FILTER_FACTORIES, Lists.newLinkedList(resourceFilterFactories));
71  
72          this.instances = Sets.newHashSet(Preconditions.checkNotNull(providers));
73          this.instances.add(new JacksonJsonProviderFactory().create(modules));
74          this.instances.add(new XMLStreamReaderContextProvider(this));
75  
76          addInstancesClassesToClasses();
77      }
78  
79      private void addInstancesClassesToClasses() {
80          for (Object o : instances) {
81              classes.add(o.getClass());
82          }
83      }
84  
85      @Override
86      public synchronized Set<Class<?>> getClasses() {
87          if (scannedClasses == null) {
88              scannedClasses = scanForAnnotatedClasses();
89              classes.addAll(scannedClasses);
90          }
91  
92          return classes;
93      }
94  
95      private Set<Class<?>> scanForAnnotatedClasses() {
96          return new AnnotatedClassScanner(bundle, Provider.class, Path.class).scan(packages);
97      }
98  
99      public Set<?> getInstances() {
100         return Collections.unmodifiableSet(instances);
101     }
102 }