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 public void setCreated(Date date) {
241
242
243
244 if (getTemporal().isEmpty()) {
245 setDate(PROPERTY_CREATED, date, Precision.Day);
246 }
247 }
248
249
250 public void setCreated(Temporal t) {
251
252
253
254 if (getTemporal().isEmpty()) {
255 t.fold(new Temporal.Match<Void>() {
256 @Override
257 public Void period(DCMIPeriod period) {
258 setCreated(period.getStart());
259 return null;
260 }
261
262 @Override
263 public Void instant(Date instant) {
264 setCreated(instant);
265 return null;
266 }
267
268 @Override
269 public Void duration(long duration) {
270
271 return null;
272 }
273 });
274 }
275 }
276
277
278
279 public void removeCreated() {
280 dc.remove(PROPERTY_CREATED);
281 }
282
283
284
285
286 @Nonnull public List<String> getCreators() {
287 return get(PROPERTY_CREATOR);
288 }
289
290
291 public void setCreators(List<String> creators) {
292 set(PROPERTY_CREATOR, creators);
293 }
294
295
296 public void setCreator(String creator) {
297 set(PROPERTY_CREATOR, creator);
298 }
299
300
301 public void addCreator(String name) {
302 add(PROPERTY_CREATOR, name);
303 }
304
305
306 public void updateCreator(Optional<String> name) {
307 update(PROPERTY_CREATOR, name);
308 }
309
310
311 public void removeCreators() {
312 dc.remove(PROPERTY_CREATOR);
313 }
314
315
316
317
318 @Nonnull public Optional<Long> getExtent() {
319 return getFirst(PROPERTY_EXTENT).map(OpencastMetadataCodec.decodeDuration);
320 }
321
322
323 public void setExtent(Long extent) {
324 dc.set(PROPERTY_EXTENT, OpencastMetadataCodec.encodeDuration(extent));
325 }
326
327
328 public void removeExtent() {
329 dc.remove(PROPERTY_EXTENT);
330 }
331
332
333
334
335 @Nonnull public Optional<Date> getIssued() {
336 return getFirst(PROPERTY_ISSUED).map(OpencastMetadataCodec.decodeDate);
337 }
338
339
340 public void setIssued(Date date) {
341 setDate(PROPERTY_ISSUED, date, Precision.Day);
342 }
343
344
345 public void updateIssued(Optional<Date> date) {
346 updateDate(PROPERTY_ISSUED, date, Precision.Day);
347 }
348
349
350 public void removeIssued() {
351 dc.remove(PROPERTY_ISSUED);
352 }
353
354
355
356
357 @Nonnull public Optional<String> getLanguage() {
358 return getFirst(PROPERTY_LANGUAGE);
359 }
360
361
362
363
364
365
366 public void setLanguage(String lang) {
367 if (StringUtils.isNotBlank(lang)) {
368 String doLang = lang;
369 if (lang.length() == 2) {
370 try {
371 doLang = new Locale(lang).getISO3Language();
372 } catch (MissingResourceException ignore) {
373 }
374 }
375 set(PROPERTY_LANGUAGE, doLang);
376 }
377 }
378
379
380 public void removeLanguage() {
381 dc.remove(PROPERTY_LANGUAGE);
382 }
383
384
385
386
387 @Nonnull public Optional<String> getSpatial() {
388 return getFirst(PROPERTY_SPATIAL);
389 }
390
391
392 public void setSpatial(String spatial) {
393 set(PROPERTY_SPATIAL, spatial);
394 }
395
396
397 public void updateSpatial(Optional<String> spatial) {
398 update(PROPERTY_SPATIAL, spatial);
399 }
400
401
402 public void removeSpatial() {
403 dc.remove(PROPERTY_SPATIAL);
404 }
405
406
407
408
409 @Nonnull public Optional<String> getSource() {
410 return getFirst(PROPERTY_SOURCE);
411 }
412
413
414 public void setSource(String source) {
415 set(PROPERTY_SOURCE, source);
416 }
417
418
419 public void removeSource() {
420 dc.remove(PROPERTY_SOURCE);
421 }
422
423
424
425
426 @Nonnull public List<String> getContributors() {
427 return get(PROPERTY_CONTRIBUTOR);
428 }
429
430
431 public void setContributors(List<String> contributors) {
432 set(PROPERTY_CONTRIBUTOR, contributors);
433 }
434
435
436 public void setContributor(String contributor) {
437 set(PROPERTY_CONTRIBUTOR, contributor);
438 }
439
440
441 public void addContributor(String contributor) {
442 add(PROPERTY_CONTRIBUTOR, contributor);
443 }
444
445
446 public void updateContributor(Optional<String> contributor) {
447 update(PROPERTY_CONTRIBUTOR, contributor);
448 }
449
450
451 public void removeContributors() {
452 dc.remove(PROPERTY_CONTRIBUTOR);
453 }
454
455
456
457
458 @Nonnull public Optional<Temporal> getTemporal() {
459 return getFirstVal(PROPERTY_TEMPORAL).map(OpencastMetadataCodec.decodeTemporal);
460 }
461
462
463
464
465
466 public void setTemporal(Date from, Date to) {
467 setPeriod(PROPERTY_TEMPORAL, from, to, Precision.Second);
468
469
470 setDate(PROPERTY_CREATED, from, Precision.Day);
471 }
472
473
474 public void removeTemporal() {
475 dc.remove(PROPERTY_TEMPORAL);
476 }
477
478
479
480
481 @Nonnull public Optional<Stream<String>> getType() {
482 return getFirst(PROPERTY_TYPE).map(s -> Stream.of(s.split("/")));
483 }
484
485
486 @Nonnull public Optional<String> getTypeCombined() {
487 return getFirst(PROPERTY_TYPE);
488 }
489
490
491
492
493
494 public void setType(String type, String subtype) {
495 set(PROPERTY_TYPE, type + "/" + subtype);
496 }
497
498
499 public void setType(String type) {
500 set(PROPERTY_TYPE, type);
501 }
502
503
504 public void removeType() {
505 dc.remove(PROPERTY_TYPE);
506 }
507
508
509
510 public static final class Episode extends OpencastDctermsDublinCore {
511
512 public Episode(DublinCoreCatalog dc) {
513 super(dc);
514 }
515
516
517 @Nonnull public Optional<String> getIsPartOf() {
518 return getFirst(PROPERTY_IS_PART_OF);
519 }
520
521
522 public void setIsPartOf(String seriesID) {
523 set(PROPERTY_IS_PART_OF, seriesID);
524 }
525
526
527 public void updateIsPartOf(Optional<String> seriesID) {
528 update(PROPERTY_IS_PART_OF, seriesID);
529 }
530
531
532 public void removeIsPartOf() {
533 dc.remove(PROPERTY_IS_PART_OF);
534 }
535
536 }
537
538
539
540 public static final class Series extends OpencastDctermsDublinCore {
541 public Series(DublinCoreCatalog dc) {
542 super(dc);
543 }
544 }
545
546
547
548 protected void setDate(EName property, Date date, Precision p) {
549 dc.set(property, OpencastMetadataCodec.encodeDate(date, p));
550 }
551
552 protected void updateDate(EName property, Optional<Date> date, Precision p) {
553 if (date.isPresent()) {
554 setDate(property, date.get(), p);
555 }
556 }
557
558
559 protected void setPeriod(EName property, Date from, Date to, Precision p) {
560 dc.set(property, OpencastMetadataCodec.encodePeriod(from, to, p));
561 }
562
563 protected List<String> get(EName property) {
564 return dc.get(property, LANGUAGE_ANY);
565 }
566
567
568 protected Optional<String> getFirst(EName property) {
569 return Optional.ofNullable(dc.getFirst(property));
570 }
571
572
573 protected Optional<DublinCoreValue> getFirstVal(EName property) {
574 return Optional.ofNullable(dc.getFirstVal(property));
575 }
576
577 public void set(EName property, String value) {
578 if (StringUtils.isNotBlank(value)) {
579 dc.set(property, value);
580 }
581 }
582
583 public void set(EName property, List<String> values) {
584 List<DublinCoreValue> valuesFiltered = values.stream()
585 .filter(s -> s != null && !s.trim().isEmpty())
586 .map(DublinCoreValue::mk)
587 .collect(Collectors.toList());
588 if (!valuesFiltered.isEmpty()) {
589 dc.remove(property);
590 dc.set(property, valuesFiltered);
591 }
592 }
593
594 protected void add(EName property, String value) {
595 if (StringUtils.isNotBlank(value)) {
596 dc.add(property, value);
597 }
598 }
599
600 protected void update(EName property, Optional<String> value) {
601 if (value.isPresent()) {
602 set(property, value.get());
603 }
604 }
605 }