1 package com.atlassian.plugin.web;
2
3 import com.atlassian.plugin.PluginManager;
4 import com.atlassian.plugin.PluginAccessor;
5 import com.atlassian.plugin.web.descriptors.*;
6
7 import java.util.*;
8
9 import com.atlassian.plugin.web.model.WebPanel;
10 import com.google.common.base.Function;
11 import com.google.common.collect.Lists;
12 import org.slf4j.Logger;
13 import org.slf4j.LoggerFactory;
14
15
16
17
18 public class DefaultWebInterfaceManager implements WebInterfaceManager
19 {
20 private PluginAccessor pluginAccessor;
21 private WebFragmentHelper webFragmentHelper;
22 private Map<String, List<WebSectionModuleDescriptor>> sections;
23 private Map<String, List<WebItemModuleDescriptor>> items;
24 private Map<String, List<WebPanelModuleDescriptor>> panels;
25 private static final Logger log = LoggerFactory.getLogger(DefaultWebInterfaceManager.class);
26
27 public static final WeightedDescriptorComparator WEIGHTED_DESCRIPTOR_COMPARATOR = new WeightedDescriptorComparator();
28
29 public DefaultWebInterfaceManager()
30 {
31 refresh();
32 }
33
34 public DefaultWebInterfaceManager(PluginAccessor pluginAccessor, WebFragmentHelper webFragmentHelper)
35 {
36 this.pluginAccessor = pluginAccessor;
37 this.webFragmentHelper = webFragmentHelper;
38 refresh();
39 }
40
41 public boolean hasSectionsForLocation(String location)
42 {
43 return !getSections(location).isEmpty();
44 }
45
46 public List<WebSectionModuleDescriptor> getSections(String location)
47 {
48 if (location == null)
49 {
50 return Collections.emptyList();
51 }
52
53 List<WebSectionModuleDescriptor> result = sections.get(location);
54
55 if (result == null)
56 {
57 result = new ArrayList<WebSectionModuleDescriptor>();
58 List<WebSectionModuleDescriptor> descriptors = pluginAccessor.getEnabledModuleDescriptorsByClass(WebSectionModuleDescriptor.class);
59 for (WebSectionModuleDescriptor descriptor : descriptors) {
60 if (location.equalsIgnoreCase(descriptor.getLocation()))
61 result.add(descriptor);
62 }
63
64 Collections.sort(result, WEIGHTED_DESCRIPTOR_COMPARATOR);
65 sections.put(location, result);
66 }
67
68 return result;
69 }
70
71 public List<WebSectionModuleDescriptor> getDisplayableSections(String location, Map<String,Object> context)
72 {
73 return filterFragmentsByCondition(getSections(location), context);
74 }
75
76 public List<WebItemModuleDescriptor> getItems(String section)
77 {
78 if (section == null)
79 {
80 return Collections.emptyList();
81 }
82
83 List<WebItemModuleDescriptor> result = items.get(section);
84
85 if (result == null)
86 {
87 result = new ArrayList<WebItemModuleDescriptor>();
88 List<WebItemModuleDescriptor> descriptors = pluginAccessor.getEnabledModuleDescriptorsByClass(WebItemModuleDescriptor.class);
89 for (WebItemModuleDescriptor descriptor : descriptors) {
90 if (section.equalsIgnoreCase(descriptor.getSection()))
91 result.add(descriptor);
92 }
93
94 Collections.sort(result, WEIGHTED_DESCRIPTOR_COMPARATOR);
95 items.put(section, result);
96 }
97
98 return result;
99 }
100
101 public List<WebItemModuleDescriptor> getDisplayableItems(String section, Map<String,Object> context)
102 {
103 return filterFragmentsByCondition(getItems(section), context);
104 }
105
106 public List<WebPanel> getDisplayableWebPanels(String location, Map<String, Object> context)
107 {
108 return toWebPanels(getDisplayableWebPanelDescriptors(location, context));
109 }
110
111 public List<WebPanelModuleDescriptor> getDisplayableWebPanelDescriptors(String location, Map<String, Object> context)
112 {
113 return filterFragmentsByCondition(getWebPanelDescriptors(location), context);
114 }
115
116 public List<WebPanel> getWebPanels(String location)
117 {
118 return toWebPanels(getWebPanelDescriptors(location));
119 }
120
121 private List<WebPanel> toWebPanels(List<WebPanelModuleDescriptor> descriptors)
122 {
123 return Lists.transform(descriptors, new Function<WebPanelModuleDescriptor, WebPanel>()
124 {
125 public WebPanel apply(WebPanelModuleDescriptor from)
126 {
127 return from.getModule();
128 }
129 });
130 }
131
132 public List<WebPanelModuleDescriptor> getWebPanelDescriptors(String location)
133 {
134 if (location == null)
135 {
136 return Collections.emptyList();
137 }
138 else
139 {
140 List<WebPanelModuleDescriptor> result = panels.get(location);
141 if (result == null) {
142 result = new ArrayList<WebPanelModuleDescriptor>();
143
144 List<WebPanelModuleDescriptor> descriptors = pluginAccessor.getEnabledModuleDescriptorsByClass(WebPanelModuleDescriptor.class);
145 for (WebPanelModuleDescriptor descriptor : descriptors)
146 {
147 if (location.equalsIgnoreCase(descriptor.getLocation()))
148 {
149 result.add(descriptor);
150 }
151 }
152 Collections.sort(result, WEIGHTED_DESCRIPTOR_COMPARATOR);
153 panels.put(location, result);
154 }
155 return result;
156 }
157 }
158
159 private <T extends ConditionalDescriptor> List<T> filterFragmentsByCondition(List<T> relevantItems, Map<String,Object> context)
160 {
161 if (relevantItems.isEmpty())
162 {
163 return relevantItems;
164 }
165
166 List<T> result = new ArrayList<T>(relevantItems);
167 for (Iterator<T> iterator = result.iterator(); iterator.hasNext();)
168 {
169 ConditionalDescriptor descriptor = iterator.next();
170 try
171 {
172 if (descriptor.getCondition() != null && !descriptor.getCondition().shouldDisplay(context))
173 {
174 iterator.remove();
175 }
176 }
177 catch (Throwable t)
178 {
179 log.error("Could not evaluate condition '" + descriptor.getCondition() + "' for descriptor: " + descriptor, t);
180 iterator.remove();
181 }
182 }
183
184 return result;
185 }
186
187 public void refresh()
188 {
189 sections = Collections.synchronizedMap(new HashMap<String, List<WebSectionModuleDescriptor>>());
190 items = Collections.synchronizedMap(new HashMap<String, List<WebItemModuleDescriptor>>());
191 panels = Collections.synchronizedMap(new HashMap<String, List<WebPanelModuleDescriptor>>());
192 }
193
194
195
196
197
198 @Deprecated
199 public void setPluginManager(PluginManager pluginManager)
200 {
201 setPluginAccessor(pluginManager);
202 }
203
204
205
206
207
208 public void setPluginAccessor(PluginAccessor pluginAccessor)
209 {
210 this.pluginAccessor = pluginAccessor;
211 }
212
213 public void setWebFragmentHelper(WebFragmentHelper webFragmentHelper)
214 {
215 this.webFragmentHelper = webFragmentHelper;
216 }
217
218 public WebFragmentHelper getWebFragmentHelper()
219 {
220 return webFragmentHelper;
221 }
222
223 }