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.elasticsearch.index.objects.series;
23
24 import org.opencastproject.elasticsearch.api.SearchMetadata;
25 import org.opencastproject.elasticsearch.impl.SearchMetadataCollection;
26 import org.opencastproject.security.api.AccessControlEntry;
27 import org.opencastproject.security.api.AccessControlList;
28 import org.opencastproject.security.api.AccessControlParser;
29 import org.opencastproject.security.api.Permissions;
30 import org.opencastproject.security.api.Permissions.Action;
31 import org.opencastproject.util.DateTimeSupport;
32
33 import org.apache.commons.io.IOUtils;
34 import org.apache.commons.lang3.StringUtils;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 import java.io.IOException;
39 import java.nio.charset.Charset;
40 import java.util.ArrayList;
41 import java.util.HashMap;
42 import java.util.List;
43 import java.util.Map;
44
45 import javax.xml.bind.Unmarshaller;
46
47
48
49
50 public final class SeriesIndexUtils {
51
52 private static final Logger logger = LoggerFactory.getLogger(SeriesIndexUtils.class);
53
54
55
56
57 private SeriesIndexUtils() {
58 }
59
60
61
62
63
64
65
66
67
68
69
70 public static Series toSeries(SearchMetadataCollection metadata, Unmarshaller unmarshaller) throws IOException {
71 Map<String, SearchMetadata<?>> metadataMap = metadata.toMap();
72 String seriesXml = (String) metadataMap.get(SeriesIndexSchema.OBJECT).getValue();
73 return Series.valueOf(IOUtils.toInputStream(seriesXml, Charset.defaultCharset()), unmarshaller);
74 }
75
76
77
78
79
80
81
82
83 public static SearchMetadataCollection toSearchMetadata(Series series) {
84 SearchMetadataCollection metadata = new SearchMetadataCollection(
85 series.getIdentifier().concat(series.getOrganization()), Series.DOCUMENT_TYPE);
86 metadata.addField(SeriesIndexSchema.UID, series.getIdentifier(), true);
87 metadata.addField(SeriesIndexSchema.ORGANIZATION, series.getOrganization(), false);
88 metadata.addField(SeriesIndexSchema.OBJECT, series.toXML(), false);
89 metadata.addField(SeriesIndexSchema.TITLE, series.getTitle(), true);
90 if (StringUtils.trimToNull(series.getDescription()) != null) {
91 metadata.addField(SeriesIndexSchema.DESCRIPTION, series.getDescription(), true);
92 }
93 if (StringUtils.trimToNull(series.getSubject()) != null) {
94 metadata.addField(SeriesIndexSchema.SUBJECT, series.getSubject(), true);
95 }
96 if (StringUtils.trimToNull(series.getLanguage()) != null) {
97 metadata.addField(SeriesIndexSchema.LANGUAGE, series.getLanguage(), true);
98 }
99 if (StringUtils.trimToNull(series.getCreator()) != null) {
100 metadata.addField(SeriesIndexSchema.CREATOR, series.getCreator(), true);
101 }
102 if (StringUtils.trimToNull(series.getLicense()) != null) {
103 metadata.addField(SeriesIndexSchema.LICENSE, series.getLicense(), true);
104 }
105 if (StringUtils.trimToNull(series.getManagedAcl()) != null) {
106 metadata.addField(SeriesIndexSchema.MANAGED_ACL, series.getManagedAcl(), true);
107 }
108 if (series.getCreatedDateTime() != null) {
109 metadata.addField(SeriesIndexSchema.CREATED_DATE_TIME,
110 DateTimeSupport.toUTC(series.getCreatedDateTime().getTime()), true);
111 }
112 if (series.getOrganizers() != null) {
113 metadata.addField(SeriesIndexSchema.ORGANIZERS, series.getOrganizers().toArray(), true);
114 }
115 if (series.getContributors() != null) {
116 metadata.addField(SeriesIndexSchema.CONTRIBUTORS, series.getContributors().toArray(), true);
117 }
118 if (series.getPublishers() != null) {
119 metadata.addField(SeriesIndexSchema.PUBLISHERS, series.getPublishers().toArray(), true);
120 }
121 if (series.getRightsHolder() != null) {
122 metadata.addField(SeriesIndexSchema.RIGHTS_HOLDER, series.getRightsHolder(), true);
123 }
124
125 if (!series.getExtendedMetadata().isEmpty()) {
126 addExtendedMetadata(metadata, series.getExtendedMetadata());
127 }
128
129 if (StringUtils.trimToNull(series.getAccessPolicy()) != null) {
130 metadata.addField(SeriesIndexSchema.ACCESS_POLICY, series.getAccessPolicy(), false);
131 addAuthorization(metadata, series.getAccessPolicy());
132 }
133 if (series.getTheme() != null) {
134 metadata.addField(SeriesIndexSchema.THEME, series.getTheme(), false);
135 }
136 return metadata;
137 }
138
139
140
141
142
143
144
145
146
147 private static void addExtendedMetadata(SearchMetadataCollection doc, Map<String, Map<String,
148 List<String>>> extendedMetadata) {
149 for (String type: extendedMetadata.keySet()) {
150 Map<String, List<String>> extendedMetadataByType = extendedMetadata.get(type);
151 for (String name: extendedMetadataByType.keySet()) {
152 List<String> values = extendedMetadataByType.get(name);
153 String fieldName = SeriesIndexSchema.EXTENDED_METADATA_PREFIX.concat(type + "_" + name);
154 doc.addField(fieldName, values, true);
155 }
156 }
157 }
158
159
160
161
162
163
164
165
166
167 private static void addAuthorization(SearchMetadataCollection doc, String aclString) {
168 Map<String, List<String>> permissions = new HashMap<>();
169
170
171 for (Action action : Permissions.Action.values()) {
172 permissions.put(action.toString(), new ArrayList<>());
173 }
174
175 AccessControlList acl = AccessControlParser.parseAclSilent(aclString);
176 for (AccessControlEntry entry : acl.getEntries()) {
177 if (!entry.isAllow()) {
178 logger.info("Series index does not support denial via ACL, ignoring {}", entry);
179 continue;
180 }
181 List<String> actionPermissions = permissions.get(entry.getAction());
182 if (actionPermissions == null) {
183 actionPermissions = new ArrayList<>();
184 permissions.put(entry.getAction(), actionPermissions);
185 }
186 actionPermissions.add(entry.getRole());
187 }
188
189
190 for (Map.Entry<String, List<String>> entry : permissions.entrySet()) {
191 String fieldName = SeriesIndexSchema.ACL_PERMISSION_PREFIX.concat(entry.getKey());
192 doc.addField(fieldName, entry.getValue(), false);
193 }
194 }
195 }