1 package com.atlassian.plugin.webresource;
2
3 import static com.atlassian.plugin.servlet.AbstractFileServerServlet.PATH_SEPARATOR;
4 import static com.atlassian.plugin.util.EfficientStringUtils.endsWith;
5 import static com.atlassian.plugin.webresource.ContextBatchPluginResource.URL_PREFIX;
6 import static com.atlassian.plugin.webresource.SuperBatchPluginResource.DEFAULT_RESOURCE_NAME_PREFIX;
7 import static com.google.common.collect.Sets.newHashSet;
8
9 import com.atlassian.plugin.PluginAccessor;
10 import com.atlassian.plugin.cache.filecache.FileCache;
11 import com.atlassian.plugin.servlet.DownloadableResource;
12
13 import com.atlassian.plugin.webresource.cache.CacheHandle;
14 import com.atlassian.plugin.webresource.cache.FileCacheKey;
15 import com.google.common.collect.Iterables;
16
17 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory;
19
20 import java.util.ArrayList;
21 import java.util.HashSet;
22 import java.util.LinkedHashSet;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Set;
26
27
28
29
30
31
32 class ContextBatchDownloadableResourceBuilder extends AbstractBatchResourceBuilder
33 {
34 private final ResourceDependencyResolver dependencyResolver;
35
36 ContextBatchDownloadableResourceBuilder(final ResourceDependencyResolver dependencyResolver, final PluginAccessor pluginAccessor, final WebResourceUrlProvider webResourceUrlProvider,
37 final DownloadableResourceFinder resourceFinder, final FileCache<FileCacheKey> cache)
38 {
39 super(pluginAccessor, webResourceUrlProvider, resourceFinder, cache);
40 this.dependencyResolver = dependencyResolver;
41 }
42
43 public boolean matches(final String path)
44 {
45 final String type = ResourceUtils.getType(path);
46 return (path.indexOf(URL_PREFIX + type) > -1) && endsWith(path, DEFAULT_RESOURCE_NAME_PREFIX, ".", type);
47 }
48
49 public ContextBatchDownloadableResource parse(final String path, final Map<String, String> params)
50 {
51 final String type = ResourceUtils.getType(path);
52 final String key = getKey(path);
53 final LinkedHashSet<String> includedContexts = new LinkedHashSet<String>();
54 final Set<String> excludedContexts = new HashSet<String>();
55
56 ContextBatchOperations.parseContexts(key, includedContexts, excludedContexts);
57
58 LinkedHashSet<WebResourceModuleDescriptor> moduleDescriptors = new LinkedHashSet<WebResourceModuleDescriptor>();
59
60 for (final String context : includedContexts)
61 {
62 Iterables.addAll(moduleDescriptors, dependencyResolver.getDependenciesInContext(context));
63 }
64
65 for (final String context : excludedContexts)
66 {
67 List<WebResourceModuleDescriptor> dependencies = new ArrayList<WebResourceModuleDescriptor>();
68 Iterables.addAll(dependencies, dependencyResolver.getDependenciesInContext(context));
69
70 moduleDescriptors.removeAll(dependencies);
71 }
72
73 final Set<String> alreadyIncluded = newHashSet();
74 List<DownloadableResource> resources = new ArrayList<DownloadableResource>();
75 for (final WebResourceModuleDescriptor moduleDescriptor : moduleDescriptors)
76 {
77 String moduleKey = moduleDescriptor.getCompleteKey();
78 if (!alreadyIncluded.contains(moduleKey))
79 {
80 Iterables.addAll(resources, resolve(moduleDescriptor, type, params));
81 alreadyIncluded.add(moduleKey);
82 }
83 }
84 final CacheHandle cacher = CacheHandle.Builder.forRequest(cache, "context", path, params);
85 return new ContextBatchDownloadableResource(type, params, resources, cacher);
86 }
87
88 private String getKey(final String path)
89 {
90 final int secondSlashIndex = path.lastIndexOf(PATH_SEPARATOR);
91 final int firstSlashIndex = path.lastIndexOf(PATH_SEPARATOR, secondSlashIndex - 1);
92 return path.substring(firstSlashIndex + 1, secondSlashIndex);
93 }
94 }