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
28
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
133 final boolean doNotBatch = "false".equalsIgnoreCase(resourceDescriptor.getParameter(RESOURCE_BATCH_PARAM));
134 return doNotBatch || "webContext".equalsIgnoreCase(resourceDescriptor.getParameter(RESOURCE_SOURCE_PARAM));
135 }
136 }