1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.opencastproject.metadata.dublincore;
22
23 import static org.opencastproject.metadata.dublincore.DublinCore.LANGUAGE_ANY;
24 import static org.opencastproject.metadata.dublincore.DublinCore.PROPERTY_AUDIENCE;
25 import static org.opencastproject.metadata.dublincore.DublinCore.PROPERTY_CONTRIBUTOR;
26 import static org.opencastproject.metadata.dublincore.DublinCore.PROPERTY_CREATED;
27 import static org.opencastproject.metadata.dublincore.DublinCore.PROPERTY_CREATOR;
28 import static org.opencastproject.metadata.dublincore.DublinCore.PROPERTY_DESCRIPTION;
29 import static org.opencastproject.metadata.dublincore.DublinCore.PROPERTY_EXTENT;
30 import static org.opencastproject.metadata.dublincore.DublinCore.PROPERTY_IDENTIFIER;
31 import static org.opencastproject.metadata.dublincore.DublinCore.PROPERTY_ISSUED;
32 import static org.opencastproject.metadata.dublincore.DublinCore.PROPERTY_IS_PART_OF;
33 import static org.opencastproject.metadata.dublincore.DublinCore.PROPERTY_LANGUAGE;
34 import static org.opencastproject.metadata.dublincore.DublinCore.PROPERTY_LICENSE;
35 import static org.opencastproject.metadata.dublincore.DublinCore.PROPERTY_PUBLISHER;
36 import static org.opencastproject.metadata.dublincore.DublinCore.PROPERTY_RIGHTS_HOLDER;
37 import static org.opencastproject.metadata.dublincore.DublinCore.PROPERTY_SOURCE;
38 import static org.opencastproject.metadata.dublincore.DublinCore.PROPERTY_SPATIAL;
39 import static org.opencastproject.metadata.dublincore.DublinCore.PROPERTY_TEMPORAL;
40 import static org.opencastproject.metadata.dublincore.DublinCore.PROPERTY_TITLE;
41 import static org.opencastproject.metadata.dublincore.DublinCore.PROPERTY_TYPE;
42
43 import org.opencastproject.mediapackage.EName;
44
45 import org.apache.commons.lang3.StringUtils;
46
47 import java.util.Date;
48 import java.util.List;
49 import java.util.Locale;
50 import java.util.MissingResourceException;
51 import java.util.Optional;
52 import java.util.stream.Collectors;
53 import java.util.stream.Stream;
54
55 import javax.annotation.Nonnull;
56 import javax.annotation.ParametersAreNonnullByDefault;
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 @ParametersAreNonnullByDefault
72 public abstract class OpencastDctermsDublinCore {
73 protected final DublinCoreCatalog dc;
74
75 private OpencastDctermsDublinCore(DublinCoreCatalog dc) {
76 this.dc = dc;
77 }
78
79
80 public DublinCoreCatalog getCatalog() {
81 return dc;
82 }
83
84
85
86 @Nonnull public List<String> getPublishers() {
87 return get(PROPERTY_PUBLISHER);
88 }
89
90 public void setPublishers(List<String> publishers) {
91 set(PROPERTY_PUBLISHER, publishers);
92 }
93
94 public void addPublisher(String publisher) {
95 add(PROPERTY_PUBLISHER, publisher);
96 }
97
98 public void removePublishers() {
99 dc.remove(PROPERTY_PUBLISHER);
100 }
101
102
103
104 @Nonnull public List<String> getRightsHolders() {
105 return get(PROPERTY_RIGHTS_HOLDER);
106 }
107
108 public void setRightsHolders(List<String> rightsHolders) {
109 set(PROPERTY_RIGHTS_HOLDER, rightsHolders);
110 }
111
112 public void addRightsHolder(String rightsHolder) {
113 add(PROPERTY_RIGHTS_HOLDER, rightsHolder);
114 }
115
116 public void removeRightsHolders() {
117 dc.remove(PROPERTY_RIGHTS_HOLDER);
118 }
119
120
121
122 @Nonnull public Optional<String> getLicense() {
123 return getFirst(PROPERTY_LICENSE);
124 }
125
126 public void setLicense(String license) {
127 set(PROPERTY_LICENSE, license);
128 }
129
130 public void removeLicense() {
131 dc.remove(PROPERTY_LICENSE);
132 }
133
134
135
136
137 @Nonnull public Optional<String> getDcIdentifier() {
138 return getFirst(PROPERTY_IDENTIFIER);
139 }
140
141
142 public void setDcIdentifier(String id) {
143 set(PROPERTY_IDENTIFIER, id);
144 }
145
146
147 public void updateDcIdentifier(Optional<String> id) {
148 update(PROPERTY_IDENTIFIER, id);
149 }
150
151
152 public void removeDcIdentifier() {
153 dc.remove(PROPERTY_IDENTIFIER);
154 }
155
156
157
158
159 @Nonnull public Optional<String> getTitle() {
160 return getFirst(PROPERTY_TITLE);
161 }
162
163
164 public void setTitle(String title) {
165 set(PROPERTY_TITLE, title);
166 }
167
168
169 public void updateTitle(Optional<String> title) {
170 update(PROPERTY_TITLE, title);
171 }
172
173
174 public void removeTitle() {
175 dc.remove(PROPERTY_TITLE);
176 }
177
178
179
180
181 @Nonnull public Optional<String> getDescription() {
182 return getFirst(PROPERTY_DESCRIPTION);
183 }
184
185
186 public void setDescription(String description) {
187 set(PROPERTY_DESCRIPTION, description);
188 }
189
190
191 public void updateDescription(Optional<String> description) {
192 update(PROPERTY_DESCRIPTION, description);
193 }
194
195
196 public void removeDescription() {
197 dc.remove(PROPERTY_DESCRIPTION);
198 }
199
200
201
202
203 @Nonnull public List<String> getAudiences() {
204 return get(PROPERTY_AUDIENCE);
205 }
206
207
208 public void setAudiences(List<String> audiences) {
209 set(PROPERTY_AUDIENCE, audiences);
210 }
211
212
213 public void setAudience(String audience) {
214 set(PROPERTY_AUDIENCE, audience);
215 }
216
217
218 public void addAudience(String audience) {
219 add(PROPERTY_AUDIENCE, audience);
220 }
221
222
223 public void updateAudience(Optional<String> audience) {
224 update(PROPERTY_AUDIENCE, audience);
225 }
226
227
228 public void removeAudiences() {
229 dc.remove(PROPERTY_AUDIENCE);
230 }
231
232
233
234
235 @Nonnull public Optional<Temporal> getCreated() {
236 return getFirstVal(PROPERTY_CREATED).map(OpencastMetadataCodec.decodeTemporal);
237 }
238
239
240
241 public void setCreated(Date date) {
242
243
244
245 if (getTemporal().isEmpty()) {
246 setDate(PROPERTY_CREATED, date, Precision.Day);
247 }
248 }
249
250
251
252 public void setCreated(Temporal t) {
253
254
255
256 if (getTemporal().isEmpty()) {
257 t.fold(new Temporal.Match<Void>() {
258 @Override
259 public Void period(DCMIPeriod period) {
260 setCreated(period.getStart());
261 return null;
262 }
263
264 @Override
265 public Void instant(Date instant) {
266 setCreated(instant);
267 return null;
268 }
269
270 @Override
271 public Void duration(long duration) {
272
273 return null;
274 }
275 });
276 }
277 }
278
279
280
281 public void removeCreated() {
282 dc.remove(PROPERTY_CREATED);
283 }
284
285
286
287
288 @Nonnull public List<String> getCreators() {
289 return get(PROPERTY_CREATOR);
290 }
291
292
293 public void setCreators(List<String> creators) {
294 set(PROPERTY_CREATOR, creators);
295 }
296
297
298 public void setCreator(String creator) {
299 set(PROPERTY_CREATOR, creator);
300 }
301
302
303 public void addCreator(String name) {
304 add(PROPERTY_CREATOR, name);
305 }
306
307
308 public void updateCreator(Optional<String> name) {
309 update(PROPERTY_CREATOR, name);
310 }
311
312
313 public void removeCreators() {
314 dc.remove(PROPERTY_CREATOR);
315 }
316
317
318
319
320 @Nonnull public Optional<Long> getExtent() {
321 return getFirst(PROPERTY_EXTENT).map(OpencastMetadataCodec.decodeDuration);
322 }
323
324
325 public void setExtent(Long extent) {
326 dc.set(PROPERTY_EXTENT, OpencastMetadataCodec.encodeDuration(extent));
327 }
328
329
330 public void removeExtent() {
331 dc.remove(PROPERTY_EXTENT);
332 }
333
334
335
336
337 @Nonnull public Optional<Date> getIssued() {
338 return getFirst(PROPERTY_ISSUED).map(OpencastMetadataCodec.decodeDate);
339 }
340
341
342 public void setIssued(Date date) {
343 setDate(PROPERTY_ISSUED, date, Precision.Day);
344 }
345
346
347 public void updateIssued(Optional<Date> date) {
348 updateDate(PROPERTY_ISSUED, date, Precision.Day);
349 }
350
351
352 public void removeIssued() {
353 dc.remove(PROPERTY_ISSUED);
354 }
355
356
357
358
359 @Nonnull public Optional<String> getLanguage() {
360 return getFirst(PROPERTY_LANGUAGE);
361 }
362
363
364
365
366
367
368 public void setLanguage(String lang) {
369 if (StringUtils.isNotBlank(lang)) {
370 String doLang = lang;
371 if (lang.length() == 2) {
372 try {
373 doLang = new Locale(lang).getISO3Language();
374 } catch (MissingResourceException ignore) {
375 }
376 }
377 set(PROPERTY_LANGUAGE, doLang);
378 }
379 }
380
381
382 public void removeLanguage() {
383 dc.remove(PROPERTY_LANGUAGE);
384 }
385
386
387
388
389 @Nonnull public Optional<String> getSpatial() {
390 return getFirst(PROPERTY_SPATIAL);
391 }
392
393
394 public void setSpatial(String spatial) {
395 set(PROPERTY_SPATIAL, spatial);
396 }
397
398
399 public void updateSpatial(Optional<String> spatial) {
400 update(PROPERTY_SPATIAL, spatial);
401 }
402
403
404 public void removeSpatial() {
405 dc.remove(PROPERTY_SPATIAL);
406 }
407
408
409
410
411 @Nonnull public Optional<String> getSource() {
412 return getFirst(PROPERTY_SOURCE);
413 }
414
415
416 public void setSource(String source) {
417 set(PROPERTY_SOURCE, source);
418 }
419
420
421 public void removeSource() {
422 dc.remove(PROPERTY_SOURCE);
423 }
424
425
426
427
428 @Nonnull public List<String> getContributors() {
429 return get(PROPERTY_CONTRIBUTOR);
430 }
431
432
433 public void setContributors(List<String> contributors) {
434 set(PROPERTY_CONTRIBUTOR, contributors);
435 }
436
437
438 public void setContributor(String contributor) {
439 set(PROPERTY_CONTRIBUTOR, contributor);
440 }
441
442
443 public void addContributor(String contributor) {
444 add(PROPERTY_CONTRIBUTOR, contributor);
445 }
446
447
448 public void updateContributor(Optional<String> contributor) {
449 update(PROPERTY_CONTRIBUTOR, contributor);
450 }
451
452
453 public void removeContributors() {
454 dc.remove(PROPERTY_CONTRIBUTOR);
455 }
456
457
458
459
460 @Nonnull public Optional<Temporal> getTemporal() {
461 return getFirstVal(PROPERTY_TEMPORAL).map(OpencastMetadataCodec.decodeTemporal);
462 }
463
464
465
466
467
468 public void setTemporal(Date from, Date to) {
469 setPeriod(PROPERTY_TEMPORAL, from, to, Precision.Second);
470
471
472 setDate(PROPERTY_CREATED, from, Precision.Day);
473 }
474
475
476 public void removeTemporal() {
477 dc.remove(PROPERTY_TEMPORAL);
478 }
479
480
481
482
483 @Nonnull public Optional<Stream<String>> getType() {
484 return getFirst(PROPERTY_TYPE).map(s -> Stream.of(s.split("/")));
485 }
486
487
488 @Nonnull public Optional<String> getTypeCombined() {
489 return getFirst(PROPERTY_TYPE);
490 }
491
492
493
494
495
496 public void setType(String type, String subtype) {
497 set(PROPERTY_TYPE, type + "/" + subtype);
498 }
499
500
501 public void setType(String type) {
502 set(PROPERTY_TYPE, type);
503 }
504
505
506 public void removeType() {
507 dc.remove(PROPERTY_TYPE);
508 }
509
510
511
512 public static final class Episode extends OpencastDctermsDublinCore {
513
514 public Episode(DublinCoreCatalog dc) {
515 super(dc);
516 }
517
518
519 @Nonnull public Optional<String> getIsPartOf() {
520 return getFirst(PROPERTY_IS_PART_OF);
521 }
522
523
524 public void setIsPartOf(String seriesID) {
525 set(PROPERTY_IS_PART_OF, seriesID);
526 }
527
528
529 public void updateIsPartOf(Optional<String> seriesID) {
530 update(PROPERTY_IS_PART_OF, seriesID);
531 }
532
533
534 public void removeIsPartOf() {
535 dc.remove(PROPERTY_IS_PART_OF);
536 }
537
538 }
539
540
541
542 public static final class Series extends OpencastDctermsDublinCore {
543 public Series(DublinCoreCatalog dc) {
544 super(dc);
545 }
546 }
547
548
549
550 protected void setDate(EName property, Date date, Precision p) {
551 dc.set(property, OpencastMetadataCodec.encodeDate(date, p));
552 }
553
554 protected void updateDate(EName property, Optional<Date> date, Precision p) {
555 if (date.isPresent()) {
556 setDate(property, date.get(), p);
557 }
558 }
559
560
561 protected void setPeriod(EName property, Date from, Date to, Precision p) {
562 dc.set(property, OpencastMetadataCodec.encodePeriod(from, to, p));
563 }
564
565 protected List<String> get(EName property) {
566 return dc.get(property, LANGUAGE_ANY);
567 }
568
569
570 protected Optional<String> getFirst(EName property) {
571 return Optional.ofNullable(dc.getFirst(property));
572 }
573
574
575 protected Optional<DublinCoreValue> getFirstVal(EName property) {
576 return Optional.ofNullable(dc.getFirstVal(property));
577 }
578
579 public void set(EName property, String value) {
580 if (StringUtils.isNotBlank(value)) {
581 dc.set(property, value);
582 }
583 }
584
585 public void set(EName property, List<String> values) {
586 List<DublinCoreValue> valuesFiltered = values.stream()
587 .filter(s -> s != null && !s.trim().isEmpty())
588 .map(DublinCoreValue::mk)
589 .collect(Collectors.toList());
590 if (!valuesFiltered.isEmpty()) {
591 dc.remove(property);
592 dc.set(property, valuesFiltered);
593 }
594 }
595
596 protected void add(EName property, String value) {
597 if (StringUtils.isNotBlank(value)) {
598 dc.add(property, value);
599 }
600 }
601
602 protected void update(EName property, Optional<String> value) {
603 if (value.isPresent()) {
604 set(property, value.get());
605 }
606 }
607 }