1   package com.atlassian.plugins.rest.common.interceptor.impl;
2   
3   import com.atlassian.plugin.AutowireCapablePlugin;
4   import com.atlassian.plugins.rest.common.interceptor.InterceptorChain;
5   import com.atlassian.plugins.rest.common.interceptor.ResourceInterceptor;
6   
7   import java.lang.reflect.Method;
8   import java.util.ArrayList;
9   import java.util.LinkedHashMap;
10  import java.util.List;
11  
12  /**
13   * Builds the interceptor chain for the resource method.  Uses the {@link InterceptorChain} resource by building the
14   * chain from the method then class then package, then default interceptors passed into the constructor.
15   *
16   * @since 2.0
17   */
18  class InterceptorChainBuilder
19  {
20      private final LinkedHashMap<Class<? extends ResourceInterceptor>, ResourceInterceptor> defaultResourceInterceptors;
21      private final AutowireCapablePlugin plugin;
22  
23      public InterceptorChainBuilder(AutowireCapablePlugin plugin, ResourceInterceptor... resourceInterceptors)
24      {
25          defaultResourceInterceptors = new LinkedHashMap<Class<? extends ResourceInterceptor>, ResourceInterceptor>();
26          for (ResourceInterceptor resourceInterceptor : resourceInterceptors)
27          {
28              defaultResourceInterceptors.put(resourceInterceptor.getClass(), resourceInterceptor);
29          }
30          this.plugin = plugin;
31      }
32  
33      public List<ResourceInterceptor> getResourceInterceptorsForMethod(Method m)
34      {
35          // First check the method
36          InterceptorChain chain = m.getAnnotation(InterceptorChain.class);
37          if (chain == null)
38          {
39              // Next check the class
40              chain = m.getDeclaringClass().getAnnotation(InterceptorChain.class);
41              if (chain == null)
42              {
43                  // Finally, check the package
44                  chain = m.getDeclaringClass().getPackage().getAnnotation(InterceptorChain.class);
45              }
46          }
47  
48          if (chain != null)
49          {
50              return buildFromClass(chain.value());
51          }
52          else
53          {
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      {
61          List<ResourceInterceptor> resourceInterceptors = new ArrayList<ResourceInterceptor>();
62          for (Class<? extends ResourceInterceptor> resourceInterceptorClass : resourceInterceptorClasses)
63          {
64              if (defaultResourceInterceptors.containsKey(resourceInterceptorClass))
65              {
66                  resourceInterceptors.add(defaultResourceInterceptors.get(resourceInterceptorClass));
67              }
68              else
69              {
70                  resourceInterceptors.add(plugin.autowire(resourceInterceptorClass));
71  
72                  // todo: we should find a way to autowire from jersey injectables
73              }
74          }
75          return resourceInterceptors;
76      }
77  }