View Javadoc

1   package com.atlassian.plugin.webresource;
2   
3   import static com.atlassian.plugin.util.EfficientStringUtils.endsWith;
4   import static com.atlassian.plugin.webresource.PluginResourceLocator.BATCH_PARAMS;
5   import static com.google.common.base.Predicates.notNull;
6   import static com.google.common.collect.Iterables.filter;
7   import static com.google.common.collect.Iterables.transform;
8   import static java.util.Collections.emptyList;
9   
10  import com.atlassian.plugin.ModuleDescriptor;
11  import com.atlassian.plugin.PluginAccessor;
12  import com.atlassian.plugin.Resources.TypeFilter;
13  import com.atlassian.plugin.cache.filecache.FileCache;
14  import com.atlassian.plugin.elements.ResourceDescriptor;
15  import com.atlassian.plugin.servlet.DownloadableResource;
16  
17  import com.atlassian.plugin.webresource.cache.FileCacheKey;
18  import org.slf4j.Logger;
19  import org.slf4j.LoggerFactory;
20  
21  import com.google.common.base.Function;
22  import com.google.common.base.Predicate;
23  
24  import java.util.Map;
25  
26  /**
27   * This class is used to add individual resources into a larger batch resource.
28   * @since 2.9.0
29   */
30  abstract class AbstractBatchResourceBuilder implements DownloadableResourceBuilder
31  {
32      private static final Logger log = LoggerFactory.getLogger(AbstractBatchResourceBuilder.class);
33      private static final String RESOURCE_SOURCE_PARAM = "source";
34      private static final String RESOURCE_BATCH_PARAM = "batch";
35      private static final String DOWNLOAD_TYPE = "download";
36  
37      private final PluginAccessor pluginAccessor;
38      private final WebResourceUrlProvider webResourceUrlProvider;
39      protected DownloadableResourceFinder resourceFinder;
40      protected final FileCache<FileCacheKey> cache;
41  
42      AbstractBatchResourceBuilder(final PluginAccessor pluginAccessor, final WebResourceUrlProvider webResourceUrlProvider,
43                                   final DownloadableResourceFinder resourceFinder, final FileCache<FileCacheKey> cache)
44      {
45          this.pluginAccessor = pluginAccessor;
46          this.webResourceUrlProvider = webResourceUrlProvider;
47          this.resourceFinder = resourceFinder;
48          this.cache = cache;
49      }
50  
51      Iterable<DownloadableResource> resolve(final String moduleKey, final String batchType, final Map<String, String> batchParams)
52      {
53          final ModuleDescriptor<?> desc = pluginAccessor.getEnabledPluginModule(moduleKey);
54          if (desc == null)
55          {
56              log.info("Resource batching configuration refers to plugin that does not exist: {}", moduleKey);
57              return emptyList();
58          }
59          log.debug("searching resources in: {}", moduleKey);
60  
61          return resolve(desc, batchType, batchParams);
62      }
63  
64      Iterable<DownloadableResource> resolve(final ModuleDescriptor<?> moduleDescriptor, final String batchType, final Map<String, String> batchParams)
65      {
66          final Iterable<ResourceDescriptor> downloadDescriptors = filter(moduleDescriptor.getResourceDescriptors(), new TypeFilter(DOWNLOAD_TYPE));
67          final Iterable<ResourceDescriptor> inBatch = filter(downloadDescriptors, new Predicate<ResourceDescriptor>()
68          {
69              public boolean apply(final ResourceDescriptor resourceDescriptor)
70              {
71                  return isResourceInBatch(resourceDescriptor, batchType, batchParams);
72              }
73          });
74          final Iterable<DownloadableResource> resources = transform(inBatch, new Function<ResourceDescriptor, DownloadableResource>()
75          {
76              public DownloadableResource apply(final ResourceDescriptor from)
77              {
78                  final DownloadableResource result = resourceFinder.find(moduleDescriptor.getCompleteKey(), from.getName());
79                  if (result != null && RelativeURLTransformResource.matches(from))
80                  {
81                      return new RelativeURLTransformResource(webResourceUrlProvider, moduleDescriptor, result);
82                  }
83                  return result;
84              }
85          });
86  
87          return filter(resources, notNull());
88      }
89  
90      DownloadableResourceFinder getResourceFinder()
91      {
92          return resourceFinder;
93      }
94  
95      private boolean isResourceInBatch(final ResourceDescriptor resourceDescriptor, final String batchType, final Map<String, String> batchParams)
96      {
97          if (!descriptorTypeMatchesResourceType(resourceDescriptor, batchType))
98          {
99              return false;
100         }
101 
102         if (skipBatch(resourceDescriptor))
103         {
104             return false;
105         }
106 
107         for (final String param : BATCH_PARAMS)
108         {
109             final String batchValue = batchParams.get(param);
110             final String resourceValue = resourceDescriptor.getParameter(param);
111 
112             if ((batchValue == null) && (resourceValue != null))
113             {
114                 return false;
115             }
116 
117             if ((batchValue != null) && !batchValue.equals(resourceValue))
118             {
119                 return false;
120             }
121         }
122         return true;
123     }
124 
125     private boolean descriptorTypeMatchesResourceType(final ResourceDescriptor resourceDescriptor, final String type)
126     {
127         return endsWith(resourceDescriptor.getName(), ".", type);
128     }
129 
130     static boolean skipBatch(final ResourceDescriptor resourceDescriptor)
131     {
132         // you can't batch forwarded requests
133         final boolean doNotBatch = "false".equalsIgnoreCase(resourceDescriptor.getParameter(RESOURCE_BATCH_PARAM));
134         return doNotBatch || "webContext".equalsIgnoreCase(resourceDescriptor.getParameter(RESOURCE_SOURCE_PARAM));
135     }
136 }