View Javadoc

1   package com.atlassian.plugins.rest.common.interceptor.impl;
2   
3   import com.atlassian.annotations.tenancy.TenantAware;
4   import com.atlassian.plugin.module.ContainerManagedPlugin;
5   import com.atlassian.plugins.rest.common.interceptor.InterceptorChain;
6   import com.atlassian.plugins.rest.common.interceptor.ResourceInterceptor;
7   
8   import java.lang.reflect.Method;
9   import java.util.ArrayList;
10  import java.util.LinkedHashMap;
11  import java.util.List;
12  
13  import static com.atlassian.annotations.tenancy.TenancyScope.TENANTLESS;
14  
15  /**
16   * Builds the interceptor chain for the resource method.  Uses the {@link InterceptorChain} resource by building the
17   * chain from the method then class then package, then default interceptors passed into the constructor.
18   *
19   * This is a private class and used by the  {@link EntityParamDispatchProviderWrapper}
20   * and {@link com.atlassian.plugins.rest.common.multipart.jersey.MultipartFormDispatchProvider}
21   * which both will use this helper class to wrap calls to rest methods with interceptors.
22   *
23   * @since 2.0
24   */
25  public class InterceptorChainBuilder {
26  
27      @TenantAware(TENANTLESS)
28      private final LinkedHashMap<Class<? extends ResourceInterceptor>, ResourceInterceptor> defaultResourceInterceptors;
29      private final ContainerManagedPlugin plugin;
30  
31      public InterceptorChainBuilder(ContainerManagedPlugin plugin, ResourceInterceptor... resourceInterceptors) {
32          defaultResourceInterceptors = new LinkedHashMap<>();
33          for (ResourceInterceptor resourceInterceptor : resourceInterceptors) {
34              defaultResourceInterceptors.put(resourceInterceptor.getClass(), resourceInterceptor);
35          }
36          this.plugin = plugin;
37      }
38  
39      public List<ResourceInterceptor> getResourceInterceptorsForMethod(Method m) {
40          // First check the method
41          InterceptorChain chain = m.getAnnotation(InterceptorChain.class);
42          if (chain == null) {
43              // Next check the class
44              chain = m.getDeclaringClass().getAnnotation(InterceptorChain.class);
45              if (chain == null) {
46                  // Finally, check the package
47                  chain = m.getDeclaringClass().getPackage().getAnnotation(InterceptorChain.class);
48              }
49          }
50  
51          if (chain != null) {
52              return buildFromClass(chain.value());
53          } else {
54              // Return default interceptor list
55              return new ArrayList<ResourceInterceptor>(defaultResourceInterceptors.values());
56          }
57      }
58  
59      private List<ResourceInterceptor> buildFromClass(Class<? extends ResourceInterceptor>[] resourceInterceptorClasses) {
60          List<ResourceInterceptor> resourceInterceptors = new ArrayList<ResourceInterceptor>();
61          for (Class<? extends ResourceInterceptor> resourceInterceptorClass : resourceInterceptorClasses) {
62              if (defaultResourceInterceptors.containsKey(resourceInterceptorClass)) {
63                  resourceInterceptors.add(defaultResourceInterceptors.get(resourceInterceptorClass));
64              } else {
65                  resourceInterceptors.add(plugin.getContainerAccessor().createBean(resourceInterceptorClass));
66  
67                  // todo: we should find a way to autowire from jersey injectables
68              }
69          }
70          return resourceInterceptors;
71      }
72  }