1 package com.atlassian.plugin.webresource;
2
3 import com.atlassian.plugin.ModuleDescriptor;
4
5 import java.util.LinkedHashSet;
6 import java.util.List;
7 import java.util.Stack;
8 import java.util.Collections;
9 import java.util.Set;
10
11 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory;
13
14 class DefaultResourceDependencyResolver implements ResourceDependencyResolver
15 {
16 private static final Logger log = LoggerFactory.getLogger(DefaultResourceDependencyResolver.class);
17
18 private final WebResourceIntegration webResourceIntegration;
19 private final ResourceBatchingConfiguration batchingConfiguration;
20
21 private String superBatchVersion;
22 private LinkedHashSet<String> superBatchResources;
23
24 public DefaultResourceDependencyResolver(WebResourceIntegration webResourceIntegration, ResourceBatchingConfiguration batchingConfiguration)
25 {
26 this.webResourceIntegration = webResourceIntegration;
27 this.batchingConfiguration = batchingConfiguration;
28 }
29
30 public LinkedHashSet<String> getSuperBatchDependencies()
31 {
32 if (!batchingConfiguration.isSuperBatchingEnabled())
33 {
34 log.warn("Super batching not enabled, but getSuperBatchDependencies() called. Returning empty set.");
35 return new LinkedHashSet<String>();
36 }
37
38 String version = webResourceIntegration.getSuperBatchVersion();
39 if (superBatchVersion == null || !superBatchVersion.equals(version))
40 {
41 LinkedHashSet<String> webResourceNames = new LinkedHashSet<String>();
42 if (batchingConfiguration.getSuperBatchModuleCompleteKeys() != null)
43 {
44 for (String moduleKey : batchingConfiguration.getSuperBatchModuleCompleteKeys())
45 {
46 resolveDependencies(moduleKey, webResourceNames, Collections.emptySet(), new Stack<String>());
47 }
48 }
49 synchronized (this)
50 {
51 superBatchResources = webResourceNames;
52 superBatchVersion = version;
53 }
54 }
55 return new LinkedHashSet(superBatchResources);
56 }
57
58 public LinkedHashSet<String> getDependencies(String moduleKey, boolean excludeSuperBatchedResources)
59 {
60 LinkedHashSet<String> orderedResourceKeys = new LinkedHashSet<String>();
61 Set<String> superBatchResources = excludeSuperBatchedResources ? getSuperBatchDependencies() : Collections.<String>emptySet();
62 resolveDependencies(moduleKey, orderedResourceKeys, superBatchResources, new Stack<String>());
63 return orderedResourceKeys;
64 }
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79 private void resolveDependencies(final String moduleKey, final LinkedHashSet<String> orderedResourceKeys,
80 final Set superBatchResources, final Stack<String> stack)
81 {
82 if (superBatchResources.contains(moduleKey))
83 {
84 log.debug("Not requiring resource: " + moduleKey + " because it is part of a super-batch");
85 return;
86 }
87 if (stack.contains(moduleKey))
88 {
89 log.warn("Cyclic plugin resource dependency has been detected with: " + moduleKey + "\n" + "Stack trace: " + stack);
90 return;
91 }
92
93 final ModuleDescriptor<?> moduleDescriptor = webResourceIntegration.getPluginAccessor().getEnabledPluginModule(moduleKey);
94 if (!(moduleDescriptor instanceof WebResourceModuleDescriptor))
95 {
96 if (webResourceIntegration.getPluginAccessor().getPluginModule(moduleKey) != null)
97 log.warn("Cannot include disabled web resource module: " + moduleKey);
98 else
99 log.warn("Cannot find web resource module for: " + moduleKey);
100 return;
101 }
102
103 final List<String> dependencies = ((WebResourceModuleDescriptor) moduleDescriptor).getDependencies();
104 if (log.isDebugEnabled())
105 {
106 log.debug("About to add resource [" + moduleKey + "] and its dependencies: " + dependencies);
107 }
108 stack.push(moduleKey);
109 try
110 {
111 for (final String dependency : dependencies)
112 {
113 if (!orderedResourceKeys.contains(dependency))
114 {
115 resolveDependencies(dependency, orderedResourceKeys, superBatchResources, stack);
116 }
117 }
118 }
119 finally
120 {
121 stack.pop();
122 }
123 orderedResourceKeys.add(moduleKey);
124 }
125 }