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.metadata.dublincore;
23
24 import org.apache.commons.lang3.StringUtils;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28 import java.text.SimpleDateFormat;
29 import java.util.ArrayList;
30 import java.util.Map;
31 import java.util.TimeZone;
32
33
34
35
36
37 public class MetadataField {
38
39 private static final Logger logger = LoggerFactory.getLogger(MetadataField.class);
40
41
42 public static final String CONFIG_COLLECTION_ID_KEY = "collectionID";
43 private static final String CONFIG_PATTERN_KEY = "pattern";
44 private static final String CONFIG_DELIMITER_KEY = "delimiter";
45 public static final String CONFIG_INPUT_ID_KEY = "inputID";
46 public static final String CONFIG_LABEL_KEY = "label";
47 public static final String CONFIG_LIST_PROVIDER_KEY = "listprovider";
48 private static final String CONFIG_NAMESPACE_KEY = "namespace";
49 private static final String CONFIG_ORDER_KEY = "order";
50 private static final String CONFIG_OUTPUT_ID_KEY = "outputID";
51 public static final String CONFIG_PROPERTY_PREFIX = "property";
52 public static final String CONFIG_READ_ONLY_KEY = "readOnly";
53 public static final String CONFIG_REQUIRED_KEY = "required";
54 public static final String CONFIG_TYPE_KEY = "type";
55
56
57
58
59
60 public enum Type {
61 BOOLEAN, DATE, DURATION, ITERABLE_TEXT, MIXED_TEXT, ORDERED_TEXT, LONG, START_DATE, START_TIME, TEXT, TEXT_LONG
62 }
63
64
65 private String collectionID;
66
67 private String pattern;
68
69 private String delimiter;
70
71 private final String inputID;
72
73 private final String label;
74
75 private final String listprovider;
76
77 private final String namespace;
78
79
80
81
82 private final Integer order;
83
84 private final String outputID;
85
86 private boolean readOnly;
87
88 private final boolean required;
89
90 private Type type;
91
92 private Object value;
93 private Boolean translatable;
94 private boolean updated = false;
95 private Map<String, String> collection;
96
97
98 private Boolean hasDifferentValues = null;
99
100
101
102
103
104
105
106 public MetadataField(final MetadataField other) {
107 this.inputID = other.inputID;
108 this.outputID = other.outputID;
109 this.label = other.label;
110 this.readOnly = other.readOnly;
111 this.required = other.required;
112 this.value = other.value;
113 this.translatable = other.translatable;
114 this.hasDifferentValues = other.hasDifferentValues;
115 this.type = other.type;
116 this.collection = other.collection;
117 this.collectionID = other.collectionID;
118 this.order = other.order;
119 this.namespace = other.namespace;
120 this.updated = other.updated;
121 this.pattern = other.pattern;
122 this.delimiter = other.delimiter;
123 this.listprovider = other.listprovider;
124 }
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153 public MetadataField(
154 final String inputID,
155 final String outputID,
156 final String label,
157 final boolean readOnly,
158 final boolean required,
159 final Object value,
160 final Boolean translatable,
161 final Type type,
162 final Map<String, String> collection,
163 final String collectionID,
164 final Integer order,
165 final String namespace,
166 final String listprovider,
167 final String pattern,
168 final String delimiter) throws IllegalArgumentException {
169 if (StringUtils.isBlank(inputID))
170 throw new IllegalArgumentException("The metadata input id must not be null.");
171 if (StringUtils.isBlank(label))
172 throw new IllegalArgumentException("The metadata label must not be null.");
173 if (type == null)
174 throw new IllegalArgumentException("The metadata type must not be null.");
175 this.inputID = inputID;
176 this.outputID = outputID;
177 this.label = label;
178 this.readOnly = readOnly;
179 this.required = required;
180 this.value = value;
181 this.translatable = translatable;
182 this.type = type;
183 this.collection = collection;
184 this.collectionID = collectionID;
185 this.order = order;
186 this.namespace = namespace;
187 this.listprovider = listprovider;
188 this.pattern = pattern;
189 this.delimiter = delimiter;
190 }
191
192
193
194
195
196
197
198 public void setCollection(final Map<String, String> collection) {
199 this.collection = collection;
200 }
201
202 public Map<String, String> getCollection() {
203 return collection;
204 }
205
206 public Object getValue() {
207 return value;
208 }
209
210 public Boolean isTranslatable() {
211 return translatable;
212 }
213
214 public boolean isUpdated() {
215 return updated;
216 }
217
218 public void setValue(final Object value) {
219 setValue(value, true);
220 }
221
222 public void setValue(final Object value, final boolean setUpdated) {
223 this.value = value;
224
225 if (setUpdated) {
226 this.updated = true;
227 }
228 }
229
230 public void setIsTranslatable(final Boolean translatable) {
231 this.translatable = translatable;
232 }
233
234 public static SimpleDateFormat getSimpleDateFormatter(final String pattern) {
235 final SimpleDateFormat dateFormat;
236 if (StringUtils.isNotBlank(pattern)) {
237 dateFormat = new SimpleDateFormat(pattern);
238 } else {
239 dateFormat = new SimpleDateFormat();
240 }
241 dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
242 return dateFormat;
243 }
244
245 public static MetadataField createMetadataField(final Map<String,String> configuration) {
246 final String inputID = configuration.get(CONFIG_INPUT_ID_KEY);
247 final String label = configuration.get(CONFIG_LABEL_KEY);
248
249 final String collectionID = configuration.get(CONFIG_COLLECTION_ID_KEY);
250 final String delimiter = configuration.get(CONFIG_DELIMITER_KEY);
251 final String outputID = configuration.get(CONFIG_OUTPUT_ID_KEY);
252 final String listprovider = configuration.get(CONFIG_LIST_PROVIDER_KEY);
253 final String namespace = configuration.get(CONFIG_NAMESPACE_KEY);
254
255 final Type type = configuration.containsKey(CONFIG_TYPE_KEY)
256 ? Type.valueOf(configuration.get(CONFIG_TYPE_KEY).toUpperCase()) : null;
257 final boolean required = configuration.containsKey(CONFIG_REQUIRED_KEY) && Boolean
258 .parseBoolean(configuration.get(CONFIG_REQUIRED_KEY).toUpperCase());
259 final boolean readOnly = configuration.containsKey(CONFIG_READ_ONLY_KEY) && Boolean
260 .parseBoolean(configuration.get(CONFIG_READ_ONLY_KEY).toUpperCase());
261
262 final String pattern = configuration.getOrDefault(CONFIG_PATTERN_KEY, "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
263
264 Integer order = null;
265 if (configuration.containsKey(CONFIG_ORDER_KEY)) {
266 try {
267 order = Integer.parseInt(configuration.get(CONFIG_ORDER_KEY));
268 } catch (final NumberFormatException e) {
269 logger.warn("Unable to parse order value {} of metadata field {}", configuration.get(CONFIG_ORDER_KEY),
270 inputID, e);
271 }
272 }
273
274 if (type == null)
275 throw new IllegalArgumentException("type is null");
276
277 switch (type) {
278 case BOOLEAN:
279 return new MetadataField(
280 inputID,
281 outputID,
282 label,
283 readOnly,
284 required,
285 null,
286 null,
287 type,
288 null,
289 null,
290 order,
291 namespace,
292 listprovider,
293 null,
294 null);
295 case DATE:
296 return new MetadataField(
297 inputID,
298 outputID,
299 label,
300 readOnly,
301 required,
302 null,
303 null,
304 type,
305 null,
306 null,
307 order,
308 namespace,
309 listprovider,
310 StringUtils.isNotBlank(pattern) ? pattern : null,
311 null);
312 case DURATION:
313 case TEXT:
314 case ORDERED_TEXT:
315 case TEXT_LONG:
316 return new MetadataField(
317 inputID,
318 outputID,
319 label,
320 readOnly,
321 required,
322 "",
323 null,
324 type,
325 null,
326 collectionID,
327 order,
328 namespace,
329 listprovider,
330 null,
331 null);
332 case ITERABLE_TEXT:
333 case MIXED_TEXT:
334 return new MetadataField(
335 inputID,
336 outputID,
337 label,
338 readOnly,
339 required,
340 new ArrayList<>(),
341 null,
342 type,
343 null,
344 collectionID,
345 order,
346 namespace,
347 listprovider,
348 null,
349 delimiter);
350 case LONG:
351 return new MetadataField(
352 inputID,
353 outputID,
354 label,
355 readOnly,
356 required,
357 0L,
358 null,
359 Type.LONG,
360 null,
361 collectionID,
362 order,
363 namespace,
364 listprovider,
365 null, null);
366 case START_DATE:
367 case START_TIME:
368 if (StringUtils.isBlank(pattern)) {
369 throw new IllegalArgumentException(
370 "For temporal metadata field " + inputID + " of type " + type + " there needs to be a pattern.");
371 }
372
373 return new MetadataField(
374 inputID,
375 outputID,
376 label,
377 readOnly,
378 required,
379 null,
380 null,
381 type,
382 null,
383 null,
384 order,
385 namespace,
386 listprovider,
387 pattern,
388 null);
389 default:
390 throw new IllegalArgumentException("Unknown metadata type! " + type);
391 }
392 }
393
394 public String getCollectionID() {
395 return collectionID;
396 }
397
398 public void setCollectionID(final String collectionID) {
399 this.collectionID = collectionID;
400 }
401
402 public String getInputID() {
403 return inputID;
404 }
405
406 public String getLabel() {
407 return label;
408 }
409
410 public String getListprovider() {
411 return listprovider;
412 }
413
414 public String getNamespace() {
415 return namespace;
416 }
417
418 public Integer getOrder() {
419 return order;
420 }
421
422
423
424
425 public String getOutputID() {
426 if (outputID != null) {
427 return outputID;
428 }
429 return inputID;
430 }
431
432 public String getPattern() {
433 return pattern;
434 }
435
436 public void setPattern(final String pattern) {
437 this.pattern = pattern;
438 }
439
440 public String getDelimiter() {
441 return delimiter;
442 }
443
444 public void setDelimiter(final String delimiter) {
445 this.delimiter = delimiter;
446 }
447
448 public void setReadOnly(final boolean readOnly) {
449 this.readOnly = readOnly;
450 }
451
452 public boolean isReadOnly() {
453 return readOnly;
454 }
455
456 public boolean isRequired() {
457 return required;
458 }
459
460 public void setUpdated(final boolean updated) {
461 this.updated = updated;
462 }
463
464 public Type getType() {
465 return type;
466 }
467
468 public void setType(final Type type) {
469 this.type = type;
470 }
471
472 public void setDifferentValues() {
473 value = null;
474 hasDifferentValues = true;
475 }
476
477 public Boolean hasDifferentValues() {
478 return hasDifferentValues;
479 }
480
481 public MetadataField readOnlyCopy() {
482 final MetadataField metadataField = new MetadataField(this);
483 metadataField.setReadOnly(true);
484 return metadataField;
485 }
486 }