1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.opencastproject.index.service.catalog.adapter;
22
23 import static org.opencastproject.index.service.catalog.adapter.CatalogUIAdapterFactory.CONF_FLAVOR_KEY;
24 import static org.opencastproject.index.service.catalog.adapter.CatalogUIAdapterFactory.CONF_ORGANIZATION_KEY;
25 import static org.opencastproject.index.service.catalog.adapter.CatalogUIAdapterFactory.CONF_TITLE_KEY;
26 import static org.opencastproject.util.OsgiUtil.getCfg;
27
28 import org.opencastproject.list.api.ListProviderException;
29 import org.opencastproject.list.api.ListProvidersService;
30 import org.opencastproject.list.api.ResourceListQuery;
31 import org.opencastproject.mediapackage.EName;
32 import org.opencastproject.mediapackage.MediaPackageElementFlavor;
33 import org.opencastproject.metadata.dublincore.CatalogUIAdapter;
34 import org.opencastproject.metadata.dublincore.DublinCore;
35 import org.opencastproject.metadata.dublincore.DublinCoreCatalog;
36 import org.opencastproject.metadata.dublincore.DublinCoreMetadataCollection;
37 import org.opencastproject.metadata.dublincore.DublinCoreValue;
38 import org.opencastproject.metadata.dublincore.MetadataField;
39 import org.opencastproject.metadata.dublincore.SeriesCatalogUIAdapter;
40
41 import org.osgi.service.cm.ConfigurationException;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44
45 import java.util.ArrayList;
46 import java.util.Collections;
47 import java.util.Dictionary;
48 import java.util.HashMap;
49 import java.util.List;
50 import java.util.Map;
51 import java.util.Optional;
52 import java.util.stream.Collectors;
53
54 public abstract class ConfigurableDCCatalogUIAdapter implements CatalogUIAdapter {
55
56 private static final Logger logger = LoggerFactory.getLogger(ConfigurableDCCatalogUIAdapter.class);
57
58
59 protected CatalogUIAdapterConfiguration config;
60
61
62 protected String organization;
63
64
65 protected MediaPackageElementFlavor flavor;
66
67
68 protected String title;
69
70
71 protected Map<String, MetadataField> dublinCoreProperties;
72
73
74 protected ListProvidersService listProvidersService;
75
76
77
78
79
80
81
82
83
84 public void updated(Dictionary<String, ?> properties) throws ConfigurationException {
85 config = CatalogUIAdapterConfiguration.loadFromDictionary(properties);
86 organization = getCfg(properties, CONF_ORGANIZATION_KEY);
87 flavor = MediaPackageElementFlavor.parseFlavor(getCfg(properties, CONF_FLAVOR_KEY));
88 title = getCfg(properties, CONF_TITLE_KEY);
89 dublinCoreProperties = DublinCoreMetadataUtil.getDublinCoreProperties(properties);
90 }
91
92
93
94
95
96
97
98 private String getCollectionDefault(MetadataField metadataField,
99 ListProvidersService listProvidersService) {
100 if (listProvidersService != null && metadataField.getListprovider() != null) {
101 try {
102 return listProvidersService.getDefault(metadataField.getListprovider());
103
104 } catch (ListProviderException ex) {
105
106
107 }
108 }
109 return null;
110 }
111
112 @Override
113 public DublinCoreMetadataCollection getRawFields() {
114 return getRawFields(Collections.emptyMap());
115 }
116
117 @Override
118 public DublinCoreMetadataCollection getRawFields(Map<String, ResourceListQuery> collectionQueryOverrides) {
119 DublinCoreMetadataCollection rawFields = new DublinCoreMetadataCollection();
120 for (MetadataField metadataField : dublinCoreProperties.values()) {
121 try {
122 String defaultKey = getCollectionDefault(metadataField, listProvidersService);
123 ResourceListQuery collectionQueryOverride = collectionQueryOverrides.get(metadataField.getOutputID());
124
125 rawFields.addField(new MetadataField(metadataField), Optional.ofNullable(defaultKey),
126 Optional.ofNullable(collectionQueryOverride), listProvidersService);
127 } catch (IllegalArgumentException e) {
128 logger.error("Skipping metadata field '{}' because of error", metadataField, e);
129 }
130 }
131 return rawFields;
132 }
133
134 @Override
135 public DublinCoreMetadataCollection getRawFields(ResourceListQuery collectionQueryOverride) {
136 DublinCoreMetadataCollection rawFields = new DublinCoreMetadataCollection();
137 for (MetadataField metadataField : dublinCoreProperties.values()) {
138 try {
139 String defaultKey = getCollectionDefault(metadataField, listProvidersService);
140
141 rawFields.addField(new MetadataField(metadataField), Optional.ofNullable(defaultKey),
142 Optional.ofNullable(collectionQueryOverride), listProvidersService);
143 } catch (IllegalArgumentException e) {
144 logger.error("Skipping metadata field '{}' because of error", metadataField, e);
145 }
146 }
147 return rawFields;
148 }
149
150 protected DublinCoreMetadataCollection getFieldsFromCatalogs(List<DublinCoreCatalog> dcCatalogs) {
151 Map<String,List<MetadataField>> metadataFields = new HashMap<>();
152 List<MetadataField> emptyFields = new ArrayList<>(dublinCoreProperties.values());
153
154 for (MetadataField metadataField: dublinCoreProperties.values()) {
155
156 String namespace = DublinCore.TERMS_NS_URI;
157 if (metadataField.getNamespace() != null) {
158 namespace = metadataField.getNamespace();
159 }
160
161 String metadataFieldKey = namespace.toLowerCase() + ":" + metadataField.getInputID().toLowerCase();
162
163 List<MetadataField> metadataFieldList = metadataFields.computeIfAbsent(metadataFieldKey,
164 key -> new ArrayList<>());
165 metadataFieldList.add(metadataField);
166 }
167
168 DublinCoreMetadataCollection dublinCoreMetadata = new DublinCoreMetadataCollection();
169 for (DublinCoreCatalog dc : dcCatalogs) {
170 getFieldsFromCatalog(metadataFields, emptyFields, dublinCoreMetadata, dc);
171 }
172
173
174 for (MetadataField metadataField: emptyFields) {
175 try {
176 dublinCoreMetadata.addEmptyField(new MetadataField(metadataField), getListProvidersService());
177 } catch (IllegalArgumentException e) {
178 logger.error("Skipping metadata field '{}' because of error", metadataField, e);
179 }
180 }
181 return dublinCoreMetadata;
182 }
183
184 private void getFieldsFromCatalog(
185 Map<String, List<MetadataField>> metadataFields,
186 List<MetadataField> emptyFields,
187 DublinCoreMetadataCollection dublinCoreMetadata,
188 DublinCoreCatalog dc) {
189 for (EName propertyKey : dc.getValues().keySet()) {
190
191 final String metadataFieldKey = propertyKey.getNamespaceURI().toLowerCase() + ":"
192 + propertyKey.getLocalName().toLowerCase();
193 if (metadataFields.containsKey(metadataFieldKey)) {
194
195
196 for (MetadataField metadataField : metadataFields.get(metadataFieldKey)) {
197 List<DublinCoreValue> values = dc.get(propertyKey);
198 if (!values.isEmpty()) {
199 try {
200 dublinCoreMetadata.addField(
201 new MetadataField(metadataField),
202 values.stream().map(DublinCoreValue::getValue).collect(Collectors.toList()),
203 getListProvidersService());
204 emptyFields.remove(metadataField);
205 } catch (IllegalArgumentException e) {
206 logger.error("Skipping metadata field '{}' because of error:", metadataField.getInputID(), e);
207 }
208 }
209 }
210 }
211 }
212 }
213
214 @Override
215 public String getOrganization() {
216 return organization;
217 }
218
219 @Override
220 public boolean handlesOrganization(String organization) {
221 return ORGANIZATION_WILDCARD.equals(this.organization) || organization.equals(this.organization);
222 }
223
224 @Override
225 public MediaPackageElementFlavor getFlavor() {
226 return flavor;
227 }
228
229 @Override
230 public String getUITitle() {
231 return title;
232 }
233
234 public void setListProvidersService(ListProvidersService listProvidersService) {
235 this.listProvidersService = listProvidersService;
236 }
237
238 protected ListProvidersService getListProvidersService() {
239 return listProvidersService;
240 }
241 }