1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.opencastproject.list.common.provider;
23
24 import org.opencastproject.elasticsearch.index.ElasticsearchIndex;
25 import org.opencastproject.elasticsearch.index.objects.event.Event;
26 import org.opencastproject.elasticsearch.index.objects.event.EventIndexSchema;
27 import org.opencastproject.elasticsearch.index.objects.series.Series;
28 import org.opencastproject.elasticsearch.index.objects.series.SeriesIndexSchema;
29 import org.opencastproject.list.api.ResourceListProvider;
30 import org.opencastproject.list.api.ResourceListQuery;
31 import org.opencastproject.list.util.ListProviderUtil;
32 import org.opencastproject.security.api.User;
33 import org.opencastproject.security.api.UserDirectoryService;
34
35 import org.apache.commons.lang3.StringUtils;
36 import org.osgi.service.component.annotations.Activate;
37 import org.osgi.service.component.annotations.Component;
38 import org.osgi.service.component.annotations.Modified;
39 import org.osgi.service.component.annotations.Reference;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42
43 import java.util.ArrayList;
44 import java.util.Collection;
45 import java.util.Collections;
46 import java.util.Comparator;
47 import java.util.HashMap;
48 import java.util.HashSet;
49 import java.util.Iterator;
50 import java.util.LinkedHashMap;
51 import java.util.List;
52 import java.util.Map;
53 import java.util.Set;
54 import java.util.SortedSet;
55 import java.util.TreeSet;
56
57 @Component(
58 service = ResourceListProvider.class,
59 property = {
60 "service.description=Contributors list provider",
61 "opencast.service.type=org.opencastproject.list.provider.ContributorsListProvider"
62 }
63 )
64 public class ContributorsListProvider implements ResourceListProvider {
65
66 private static final String CONFIGURATION_KEY_EXCLUDE_USER_PROVIDER = "exclude.user.provider";
67 private static final String ALL_USER_PROVIDERS_VALUE = "*";
68
69 private static final String PROVIDER_PREFIX = "CONTRIBUTORS";
70
71 public static final String DEFAULT = PROVIDER_PREFIX;
72 public static final String NAMES_TO_USERNAMES = PROVIDER_PREFIX + ".NAMES.TO.USERNAMES";
73 public static final String USERNAMES = PROVIDER_PREFIX + ".USERNAMES";
74
75 protected static final String[] NAMES = { PROVIDER_PREFIX, USERNAMES, NAMES_TO_USERNAMES };
76
77 private static final Logger logger = LoggerFactory.getLogger(ContributorsListProvider.class);
78
79 private final Set<String> excludeUserProvider = new HashSet<>();
80 private UserDirectoryService userDirectoryService;
81 private ElasticsearchIndex searchIndex;
82
83 @Activate
84 protected void activate(Map<String, Object> properties) {
85 modified(properties);
86 logger.info("Contributors list provider activated!");
87 }
88
89 @Modified
90 public void modified(Map<String, Object> properties) {
91 Object excludeUserProviderValue = properties.get(CONFIGURATION_KEY_EXCLUDE_USER_PROVIDER);
92 excludeUserProvider.clear();
93 if (excludeUserProviderValue != null) {
94 for (String userProvider : StringUtils.split(excludeUserProviderValue.toString(), ',')) {
95 if (StringUtils.trimToNull(userProvider) != null) {
96 excludeUserProvider.add(StringUtils.trimToNull(userProvider));
97 }
98 }
99 }
100 logger.debug("Excluded user providers: {}", excludeUserProvider);
101 }
102
103
104 @Reference
105 public void setUserDirectoryService(UserDirectoryService userDirectoryService) {
106 this.userDirectoryService = userDirectoryService;
107 }
108
109
110 @Reference
111 public void setIndex(ElasticsearchIndex index) {
112 this.searchIndex = index;
113 }
114
115 @Override
116 public String[] getListNames() {
117 return NAMES;
118 }
119
120 @Override
121 public Map<String, String> getList(String listName, ResourceListQuery query) {
122 if (listName.equalsIgnoreCase(USERNAMES)) {
123 return getListWithUserNames(query);
124 } else if (listName.equalsIgnoreCase(NAMES_TO_USERNAMES)) {
125 return getListWithTechnicalPresenters(query);
126 } else {
127 return getList(query);
128 }
129 }
130
131
132
133
134
135
136
137
138 protected Map<String, String> getList(ResourceListQuery query) {
139 Map<String, String> usersList = new HashMap<String, String>();
140 int offset = 0;
141 int limit = 0;
142 SortedSet<String> contributorsList = new TreeSet<String>(new Comparator<String>() {
143 @Override
144 public int compare(String name1, String name2) {
145 return name1.compareTo(name2);
146 }
147 });
148
149 if (!excludeUserProvider.contains(ALL_USER_PROVIDERS_VALUE)) {
150 Iterator<User> users = userDirectoryService.findUsers("%", offset, limit);
151 while (users.hasNext()) {
152 User u = users.next();
153 if (!excludeUserProvider.contains(u.getProvider()) && StringUtils.isNotBlank(u.getName())) {
154 contributorsList.add(u.getName());
155 }
156 }
157 }
158
159 contributorsList.addAll(searchIndex.getTermsForField(EventIndexSchema.CONTRIBUTOR,
160 Event.DOCUMENT_TYPE));
161 contributorsList.addAll(searchIndex.getTermsForField(EventIndexSchema.PRESENTER,
162 Event.DOCUMENT_TYPE));
163 contributorsList.addAll(searchIndex.getTermsForField(EventIndexSchema.PUBLISHER,
164 Event.DOCUMENT_TYPE));
165 contributorsList.addAll(searchIndex.getTermsForField(SeriesIndexSchema.CONTRIBUTORS,
166 Series.DOCUMENT_TYPE));
167 contributorsList.addAll(searchIndex.getTermsForField(SeriesIndexSchema.ORGANIZERS,
168 Series.DOCUMENT_TYPE));
169 contributorsList.addAll(searchIndex.getTermsForField(SeriesIndexSchema.PUBLISHERS,
170 Series.DOCUMENT_TYPE));
171
172
173
174
175 if (query != null) {
176 if (query.getLimit().isPresent()) {
177 limit = query.getLimit().get();
178 }
179
180 if (query.getOffset().isPresent()) {
181 offset = query.getOffset().get();
182 }
183 }
184
185 int i = 0;
186
187 for (String contributor : contributorsList) {
188 if (i >= offset && (limit == 0 || i < limit)) {
189 usersList.put(contributor, contributor);
190 }
191 i++;
192 }
193
194 return usersList;
195 }
196
197
198
199
200
201
202
203
204 protected Map<String, String> getListWithTechnicalPresenters(ResourceListQuery query) {
205 int offset = 0;
206 int limit = 0;
207
208 List<Contributor> contributorsList = new ArrayList<Contributor>();
209
210 HashSet<String> labels = new HashSet<String>();
211
212 if (!excludeUserProvider.contains(ALL_USER_PROVIDERS_VALUE)) {
213 Iterator<User> users = userDirectoryService.findUsers("%", offset, limit);
214 while (users.hasNext()) {
215 User u = users.next();
216 if (!excludeUserProvider.contains(u.getProvider())) {
217 if (StringUtils.isNotBlank(u.getName())) {
218 contributorsList.add(new Contributor(u.getUsername(), u.getName()));
219 labels.add(u.getName());
220 } else {
221 contributorsList.add(new Contributor(u.getUsername(), u.getUsername()));
222 labels.add(u.getUsername());
223 }
224 }
225 }
226 }
227
228 addIndexNamesToMap(labels, contributorsList, searchIndex
229 .getTermsForField(EventIndexSchema.PRESENTER, Event.DOCUMENT_TYPE));
230 addIndexNamesToMap(labels, contributorsList, searchIndex
231 .getTermsForField(EventIndexSchema.CONTRIBUTOR, Event.DOCUMENT_TYPE));
232 addIndexNamesToMap(labels, contributorsList, searchIndex
233 .getTermsForField(SeriesIndexSchema.CONTRIBUTORS, Event.DOCUMENT_TYPE));
234 addIndexNamesToMap(labels, contributorsList, searchIndex
235 .getTermsForField(SeriesIndexSchema.ORGANIZERS, Event.DOCUMENT_TYPE));
236 addIndexNamesToMap(labels, contributorsList, searchIndex
237 .getTermsForField(SeriesIndexSchema.PUBLISHERS, Event.DOCUMENT_TYPE));
238
239 Collections.sort(contributorsList, new Comparator<Contributor>() {
240 @Override
241 public int compare(Contributor contributor1, Contributor contributor2) {
242 return contributor1.getLabel().compareTo(contributor2.getLabel());
243 }
244 });
245
246 Map<String, String> contributorMap = new LinkedHashMap<>();
247 for (Contributor contributor : contributorsList) {
248 contributorMap.put(contributor.getKey(), contributor.getLabel());
249 }
250
251 return ListProviderUtil.filterMap(contributorMap, query);
252 }
253
254
255
256
257
258
259
260
261 protected Map<String, String> getListWithUserNames(ResourceListQuery query) {
262
263 int offset = 0;
264 int limit = 0;
265
266 List<Contributor> contributorsList = new ArrayList<Contributor>();
267
268 HashSet<String> labels = new HashSet<String>();
269
270 if (!excludeUserProvider.contains(ALL_USER_PROVIDERS_VALUE)) {
271 Iterator<User> users = userDirectoryService.findUsers("%", offset, limit);
272 while (users.hasNext()) {
273 User u = users.next();
274 if (!excludeUserProvider.contains(u.getProvider())) {
275 if (StringUtils.isNotBlank(u.getName())) {
276 contributorsList.add(new Contributor(u.getUsername(), u.getName()));
277 labels.add(u.getName());
278 } else {
279 contributorsList.add(new Contributor(u.getUsername(), u.getUsername()));
280 labels.add(u.getUsername());
281 }
282 }
283 }
284 }
285
286 Collections.sort(contributorsList, new Comparator<Contributor>() {
287 @Override
288 public int compare(Contributor contributor1, Contributor contributor2) {
289 return contributor1.getLabel().compareTo(contributor2.getLabel());
290 }
291 });
292
293 Map<String, String> contributorMap = new LinkedHashMap<>();
294 for (Contributor contributor : contributorsList) {
295 contributorMap.put(contributor.getKey(), contributor.getLabel());
296 }
297
298 return ListProviderUtil.filterMap(contributorMap, query);
299 }
300
301
302
303
304
305
306
307
308
309
310
311 protected void addIndexNamesToMap(Set<String> userLabels, Collection<Contributor> contributors,
312 List<String> indexNames) {
313 for (String indexName : indexNames) {
314 if (!userLabels.contains(indexName)) {
315 contributors.add(new Contributor(indexName, indexName));
316 }
317 }
318 }
319
320 @Override
321 public boolean isTranslatable(String listName) {
322 return false;
323 }
324
325 @Override
326 public String getDefault() {
327 return null;
328 }
329
330 private class Contributor {
331 public String getKey() {
332 return key;
333 }
334
335 public String getLabel() {
336 return label;
337 }
338
339 private String key;
340 private String label;
341
342 Contributor(String key, String label) {
343 this.key = key;
344 this.label = label;
345 }
346
347 @Override
348 public String toString() {
349 return key + ":" + label;
350 }
351 }
352 }