View Javadoc
1   package com.atlassian.plugin.servlet.download.plugin;
2   
3   import com.atlassian.plugin.ModuleDescriptor;
4   import com.atlassian.plugin.event.PluginEventListener;
5   import com.atlassian.plugin.event.PluginEventManager;
6   import com.atlassian.plugin.event.events.PluginModuleDisabledEvent;
7   import com.atlassian.plugin.event.events.PluginModuleEnabledEvent;
8   import com.atlassian.plugin.servlet.DownloadException;
9   import com.atlassian.plugin.servlet.DownloadStrategy;
10  import org.slf4j.Logger;
11  import org.slf4j.LoggerFactory;
12  
13  import javax.servlet.http.HttpServletRequest;
14  import javax.servlet.http.HttpServletResponse;
15  import java.util.Map;
16  import java.util.concurrent.ConcurrentHashMap;
17  
18  /**
19   * A download strategy which maintains a list of {@link DownloadStrategyModuleDescriptor}s
20   * and delegates to them in order.
21   *
22   * @see DownloadStrategyModuleDescriptor
23   * @see DownloadStrategy
24   * @since 2.2.0
25   */
26  public class PluggableDownloadStrategy implements DownloadStrategy {
27      private static final Logger log = LoggerFactory.getLogger(PluggableDownloadStrategy.class);
28      private final Map<String, DownloadStrategy> strategies = new ConcurrentHashMap<>();
29  
30      public PluggableDownloadStrategy(final PluginEventManager pluginEventManager) {
31          pluginEventManager.register(this);
32      }
33  
34      public boolean matches(final String urlPath) {
35          for (final DownloadStrategy strategy : strategies.values()) {
36              if (strategy.matches(urlPath)) {
37                  log.debug("Matched plugin download strategy: {}", strategy.getClass().getName());
38                  return true;
39              }
40          }
41          return false;
42      }
43  
44      public void serveFile(final HttpServletRequest request, final HttpServletResponse response) throws DownloadException {
45          for (final DownloadStrategy strategy : strategies.values()) {
46              if (strategy.matches(request.getRequestURI().toLowerCase())) {
47                  strategy.serveFile(request, response);
48                  return;
49              }
50          }
51          throw new DownloadException(
52                  "Found plugin download strategy during matching but not when trying to serve. Enable debug logging for more information.");
53      }
54  
55      public void register(final String key, final DownloadStrategy strategy) {
56          if (strategies.containsKey(key)) {
57              log.warn("Replacing existing download strategy with module key: {}", key);
58          }
59          strategies.put(key, strategy);
60      }
61  
62      public void unregister(final String key) {
63          strategies.remove(key);
64      }
65  
66      @PluginEventListener
67      public void pluginModuleEnabled(final PluginModuleEnabledEvent event) {
68          final ModuleDescriptor<?> module = event.getModule();
69          if (!(module instanceof DownloadStrategyModuleDescriptor)) {
70              return;
71          }
72  
73          register(module.getCompleteKey(), (DownloadStrategy) module.getModule());
74      }
75  
76      @PluginEventListener
77      public void pluginModuleDisabled(final PluginModuleDisabledEvent event) {
78          final ModuleDescriptor<?> module = event.getModule();
79          if (!(module instanceof DownloadStrategyModuleDescriptor)) {
80              return;
81          }
82  
83          unregister(module.getCompleteKey());
84      }
85  }