1 package com.atlassian.plugin.webresource;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.HashSet;
6 import java.util.LinkedHashSet;
7 import java.util.Set;
8
9 import org.apache.commons.collections.CollectionUtils;
10
11 import com.google.common.collect.Iterables;
12
13
14
15
16 class ContextBatchOperations
17 {
18 static final String CONTEXT_SEPARATOR = ",";
19 static final String CONTEXT_SUBTRACTION = "-";
20
21 private PluginResourceLocator pluginResourceLocator;
22 private final WebResourceFilter filter;
23
24
25
26
27
28
29
30
31 static void parseContexts(final String key, LinkedHashSet<String> included, Set<String> excluded)
32 {
33 String[] split = key.split(CONTEXT_SEPARATOR);
34 for (String s : split)
35 {
36 if (s.startsWith(CONTEXT_SUBTRACTION))
37 {
38 excluded.add(s.substring(1));
39 }
40 else
41 {
42 included.add(s);
43 }
44 }
45 }
46
47 ContextBatchOperations(PluginResourceLocator pluginResourceLocator, WebResourceFilter filter)
48 {
49 this.pluginResourceLocator = pluginResourceLocator;
50 this.filter = filter;
51 }
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 ContextBatch merge(final Collection<ContextBatch> batchesToMerge)
67 {
68 if (CollectionUtils.isEmpty(batchesToMerge))
69 return null;
70
71 if (batchesToMerge.size() == 1)
72 return batchesToMerge.iterator().next();
73
74 final StringBuilder mergedKey = new StringBuilder();
75
76 final LinkedHashSet<String> includedContexts = new LinkedHashSet<String>();
77 final Set<WebResourceModuleDescriptor> resources = new HashSet<WebResourceModuleDescriptor>();
78 final Set<PluginResourceBatchParams> batchResourceParams = new HashSet<PluginResourceBatchParams>();
79
80 for (ContextBatch batch : batchesToMerge)
81 {
82 if (!Iterables.isEmpty(batch.getExcludedContexts()))
83 throw new IllegalArgumentException("The ContextBatch " + batch.getKey() + " has excludedContexts.");
84
85 mergedKey.append(batch.getKey()).append(CONTEXT_SEPARATOR);
86 includedContexts.addAll(batch.getContexts());
87 Iterables.addAll(resources, batch.getResources());
88 Iterables.addAll(batchResourceParams, batch.getResourceParams());
89 }
90
91 mergedKey.deleteCharAt(mergedKey.length() - 1);
92
93 return new ContextBatch(mergedKey.toString(), new ArrayList<String>(includedContexts), null, resources, batchResourceParams);
94 }
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115 ContextBatch subtract(final ContextBatch operand, final Collection<ContextBatch> batchesToSubtract)
116 {
117 if (CollectionUtils.isEmpty(batchesToSubtract))
118 return operand;
119
120 Collection<String> excludedContexts = new HashSet<String>();
121 Iterables.addAll(excludedContexts, operand.getExcludedContexts());
122 final Collection<WebResourceModuleDescriptor> resources = new HashSet<WebResourceModuleDescriptor>();
123 Iterables.addAll(resources, operand.getResources());
124
125 for (ContextBatch subtract : batchesToSubtract)
126 {
127 if (!Iterables.isEmpty(subtract.getExcludedContexts()))
128 {
129 throw new IllegalArgumentException("The ContextBatch " + subtract.getKey() + " has excludedContexts.");
130 }
131
132 Iterables.addAll(excludedContexts, subtract.getContexts());
133 Iterable<WebResourceModuleDescriptor> subtractResources = subtract.getResources();
134 for (WebResourceModuleDescriptor resource : subtractResources)
135 {
136 resources.remove(resource);
137 }
138 }
139
140 StringBuilder key = new StringBuilder();
141 for (String includedContext : operand.getContexts())
142 {
143 key.append(includedContext).append(CONTEXT_SEPARATOR);
144 }
145
146 for (String excludedContext : excludedContexts)
147 {
148 key.append(CONTEXT_SUBTRACTION).append(excludedContext).append(CONTEXT_SEPARATOR);
149 }
150
151 key.deleteCharAt(key.length() - 1);
152 ContextBatch subtractionResult = new ContextBatch(key.toString(), operand.getContexts(),excludedContexts, resources, new HashSet<PluginResourceBatchParams>());
153
154
155 for (WebResourceModuleDescriptor resource : resources)
156 {
157 for (final PluginResource pluginResource : pluginResourceLocator.getPluginResources(resource.getCompleteKey()))
158 {
159 if (filter.matches(pluginResource.getResourceName()))
160 {
161 subtractionResult.addResourceType(pluginResource);
162 }
163 }
164 }
165
166 return subtractionResult;
167 }
168 }