1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.mycore.datamodel.metadata;
20
21 import java.util.ArrayList;
22 import java.util.Iterator;
23 import java.util.List;
24 import java.util.Optional;
25 import java.util.function.Predicate;
26 import java.util.stream.Collectors;
27 import java.util.stream.Stream;
28 import java.util.stream.StreamSupport;
29
30 import org.apache.logging.log4j.LogManager;
31 import org.apache.logging.log4j.Logger;
32 import org.jdom2.Element;
33 import org.mycore.common.MCRException;
34 import org.mycore.common.config.MCRConfiguration2;
35 import org.mycore.common.config.MCRConfigurationException;
36
37 import com.google.gson.JsonObject;
38
39
40
41
42
43
44
45
46
47
48 public class MCRObjectMetadata implements Iterable<MCRMetaElement> {
49 private static final Logger LOGGER = LogManager.getLogger();
50
51
52 private boolean heritedXML;
53
54
55 private final ArrayList<MCRMetaElement> metadataElements;
56
57
58
59
60
61
62
63
64
65 public MCRObjectMetadata() throws MCRConfigurationException {
66 heritedXML = MCRConfiguration2.getBoolean("MCR.Metadata.HeritedForXML").orElse(true);
67 metadataElements = new ArrayList<>();
68 }
69
70
71
72
73
74
75 public int size() {
76 return metadataElements.size();
77 }
78
79
80
81
82
83
84
85 public final MCRObjectMetadata getHeritableMetadata() {
86 MCRObjectMetadata heritableMetadata = new MCRObjectMetadata();
87 stream().filter(MCRMetaElement::isHeritable).map(MCRMetaElement::clone).forEach(metaElement -> {
88 metaElement.stream().forEach(MCRMetaInterface::incrementInherited);
89 heritableMetadata.setMetadataElement(metaElement);
90 });
91 return heritableMetadata;
92 }
93
94
95
96
97 public final void removeInheritedMetadata() {
98 Iterator<MCRMetaElement> elements = metadataElements.iterator();
99 while (elements.hasNext()) {
100 MCRMetaElement me = elements.next();
101 me.removeInheritedMetadata();
102
103 if (me.size() == 0) {
104 elements.remove();
105 }
106 }
107 }
108
109
110
111
112
113
114
115
116 public final void appendMetadata(MCRObjectMetadata input) {
117
118 for (MCRMetaElement newelm : input) {
119 int pos = -1;
120
121 for (int j = 0; j < size(); j++) {
122 if (metadataElements.get(j)
123 .getTag()
124 .equals(newelm.getTag())) {
125 pos = j;
126 }
127 }
128
129 if (pos != -1) {
130 if (!metadataElements.get(pos)
131 .inheritsNot()) {
132 metadataElements.get(pos)
133 .setHeritable(true);
134
135 for (int j = 0; j < newelm.size(); j++) {
136 MCRMetaInterface obj = newelm.getElement(j);
137 metadataElements.get(pos)
138 .addMetaObject(obj);
139 }
140 }
141 } else {
142 metadataElements.add(newelm);
143 }
144 }
145 }
146
147
148
149
150
151
152
153
154
155 public final MCRMetaElement getMetadataElement(String tag) {
156 for (MCRMetaElement sub : this) {
157 if (sub.getTag().equals(tag)) {
158 return sub;
159 }
160 }
161 return null;
162 }
163
164
165
166
167
168
169
170
171
172 public final MCRMetaElement getMetadataElement(int index) {
173 return metadataElements.get(index);
174 }
175
176
177
178
179
180
181
182
183 public final void setMetadataElement(MCRMetaElement obj) {
184 MCRMetaElement old = getMetadataElement(obj.getTag());
185 if (old == null) {
186 metadataElements.add(obj);
187 return;
188 }
189 int i = metadataElements.indexOf(old);
190 metadataElements.remove(i);
191 metadataElements.add(i, obj);
192 }
193
194
195
196
197
198
199
200 public final boolean removeMetadataElement(MCRMetaElement element) {
201 return metadataElements.remove(element);
202 }
203
204
205
206
207
208
209 public final MCRMetaElement removeMetadataElement(String tag) {
210 MCRMetaElement old = getMetadataElement(tag);
211 if (old != null) {
212 removeMetadataElement(old);
213 return old;
214 }
215 return null;
216 }
217
218
219
220
221
222
223 public final MCRMetaElement removeMetadataElement(int index) {
224 if (index < 0 || index > size()) {
225 return null;
226 }
227
228 return metadataElements.remove(index);
229 }
230
231
232
233
234
235
236
237 public final <T extends MCRMetaInterface> Optional<T> findFirst(String tag) {
238 return findFirst(tag, null, 0);
239 }
240
241
242
243
244
245
246
247
248
249
250 public final <T extends MCRMetaInterface> Optional<T> findFirst(String tag, String type) {
251 return findFirst(tag, type, 0);
252 }
253
254
255
256
257
258
259
260
261
262
263 public final <T extends MCRMetaInterface> Optional<T> findFirst(String tag, Integer inherited) {
264 return findFirst(tag, null, inherited);
265 }
266
267
268
269
270
271
272
273
274
275
276
277
278
279 public final <T extends MCRMetaInterface> Optional<T> findFirst(String tag, String type, Integer inherited) {
280 Stream<T> stream = stream(tag);
281 return stream.filter(filterByType(type))
282 .filter(filterByInherited(inherited))
283 .findFirst();
284 }
285
286
287
288
289
290
291 public final Stream<MCRMetaElement> stream() {
292 return metadataElements.stream();
293 }
294
295
296
297
298
299
300
301
302
303
304
305
306 public final <T extends MCRMetaInterface> Stream<T> stream(String tag) {
307 Optional<MCRMetaElement> metadata = Optional.ofNullable(getMetadataElement(tag));
308
309 return metadata.map(
310 mcrMetaInterfaces -> StreamSupport.stream(mcrMetaInterfaces.spliterator(), false).map(metaInterface -> {
311 @SuppressWarnings("unchecked")
312 T t = (T) metaInterface;
313 return t;
314 })).orElseGet(Stream::empty);
315 }
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332 public final <T extends MCRMetaInterface> List<T> list(String tag) {
333 Stream<T> stream = stream(tag);
334 return stream.collect(Collectors.toList());
335 }
336
337
338
339
340
341
342
343
344 private Predicate<MCRMetaInterface> filterByType(String type) {
345 return (metaInterface) -> type == null || type.equals(metaInterface.getType());
346 }
347
348
349
350
351
352
353
354
355 private Predicate<MCRMetaInterface> filterByInherited(Integer inherited) {
356 return (metaInterface) -> metaInterface.getInherited() == inherited;
357 }
358
359
360
361
362
363
364
365
366
367
368 public final void setFromDOM(Element element) throws MCRException {
369 List<Element> elements = element.getChildren();
370 metadataElements.clear();
371 for (Element sub : elements) {
372 MCRMetaElement obj = new MCRMetaElement();
373 obj.setFromDOM(sub);
374 metadataElements.add(obj);
375 }
376 }
377
378
379
380
381
382
383
384
385 public final Element createXML() throws MCRException {
386 try {
387 validate();
388 } catch (MCRException exc) {
389 throw new MCRException("MCRObjectMetadata : The content is not valid.", exc);
390 }
391 Element elm = new Element("metadata");
392 for (MCRMetaElement e : this) {
393 elm.addContent(e.createXML(heritedXML));
394 }
395 return elm;
396 }
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415 public JsonObject createJSON() {
416 JsonObject metadata = new JsonObject();
417 StreamSupport.stream(spliterator(), true)
418 .forEach(metaElement -> metadata.add(metaElement.getTag(), metaElement.createJSON(heritedXML)));
419 return metadata;
420 }
421
422
423
424
425
426
427
428
429
430
431
432
433 public final boolean isValid() {
434 try {
435 validate();
436 return true;
437 } catch (MCRException exc) {
438 LOGGER.warn("The <metadata> element is invalid.", exc);
439 }
440 return false;
441 }
442
443
444
445
446
447
448
449
450
451 public void validate() throws MCRException {
452 for (MCRMetaElement e : this) {
453 try {
454 e.validate();
455 } catch (Exception exc) {
456 throw new MCRException("The <metadata> element is invalid because '" + e.getTag() + "' is invalid.",
457 exc);
458 }
459 }
460 }
461
462
463
464
465 public final void debug() {
466 if (LOGGER.isDebugEnabled()) {
467 for (MCRMetaElement sub : this) {
468 sub.debug();
469 }
470 }
471 }
472
473 @Override
474 public Iterator<MCRMetaElement> iterator() {
475 return metadataElements.iterator();
476 }
477
478 }