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.stream.Stream;
25
26 import org.apache.logging.log4j.LogManager;
27 import org.apache.logging.log4j.Logger;
28 import org.jdom2.Element;
29 import org.mycore.common.MCRClassTools;
30 import org.mycore.common.MCRConstants;
31 import org.mycore.common.MCRException;
32 import org.mycore.common.MCRUtils;
33 import org.mycore.common.config.MCRConfiguration2;
34
35 import com.google.gson.JsonArray;
36 import com.google.gson.JsonObject;
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 public class MCRMetaElement implements Iterable<MCRMetaInterface>, Cloneable {
52
53 public static final String DEFAULT_LANGUAGE = MCRConfiguration2.getString("MCR.Metadata.DefaultLang")
54 .orElse(MCRConstants.DEFAULT_LANG);
55
56 public static final boolean DEFAULT_HERITABLE = MCRConfiguration2.getBoolean("MCR.MetaElement.defaults.heritable")
57 .orElse(false);
58
59 public static final boolean DEFAULT_NOT_INHERIT = MCRConfiguration2
60 .getBoolean("MCR.MetaElement.defaults.notinherit").orElse(true);
61
62 private static final String META_PACKAGE_NAME = "org.mycore.datamodel.metadata.";
63
64
65 static Logger LOGGER = LogManager.getLogger();
66
67 private Class<? extends MCRMetaInterface> clazz = null;
68
69 private String tag = null;
70
71 private boolean heritable;
72
73 private boolean notinherit;
74
75 private ArrayList<MCRMetaInterface> list = null;
76
77
78
79
80
81 public MCRMetaElement() {
82 list = new ArrayList<>();
83 heritable = DEFAULT_HERITABLE;
84 notinherit = DEFAULT_NOT_INHERIT;
85 }
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100 public MCRMetaElement(Class<? extends MCRMetaInterface> clazz, String tag, boolean heritable, boolean notinherit,
101 List<? extends MCRMetaInterface> list) {
102 this();
103 this.clazz = clazz;
104 setTag(tag);
105 this.heritable = heritable;
106 this.notinherit = notinherit;
107
108 if (list != null) {
109 this.list.addAll(list);
110 }
111 }
112
113
114
115
116
117
118 public final String getClassName() {
119 return getClazz().getSimpleName();
120 }
121
122
123
124
125
126
127
128 public final MCRMetaInterface getElement(int index) {
129 if ((index < 0) || (index > list.size())) {
130 return null;
131 }
132 return list.get(index);
133 }
134
135
136
137
138
139
140
141 public final MCRMetaInterface getElementByName(String name) {
142 for (MCRMetaInterface sub : this) {
143 if (sub.getSubTag().equals(name)) {
144 return sub;
145 }
146 }
147 return null;
148 }
149
150
151
152
153
154
155 public final boolean isHeritable() {
156 return heritable;
157 }
158
159
160
161
162
163
164 public final boolean inheritsNot() {
165 return notinherit;
166 }
167
168
169
170
171
172
173 public final String getTag() {
174 return tag;
175 }
176
177
178
179
180
181
182
183 public void setHeritable(boolean heritable) {
184 this.heritable = heritable;
185 }
186
187
188
189
190
191
192
193 public void setNotInherit(boolean notinherit) {
194 this.notinherit = notinherit;
195 }
196
197
198
199
200
201
202
203 public void setTag(String tag) {
204 MCRUtils.filterTrimmedNotEmpty(tag)
205 .ifPresent(s -> this.tag = s);
206 }
207
208
209
210
211
212
213
214 public final void setClass(Class<? extends MCRMetaInterface> clazz) {
215 this.clazz = clazz;
216 }
217
218 public Class<? extends MCRMetaInterface> getClazz() {
219 return clazz;
220 }
221
222
223
224
225
226
227 public final int size() {
228 return list.size();
229 }
230
231
232
233
234
235
236
237
238
239
240
241 public final void addMetaObject(MCRMetaInterface obj) {
242 list.add(obj);
243 }
244
245
246
247
248
249
250
251 public final boolean removeElement(int index) {
252 if ((index < 0) || (index > list.size())) {
253 return false;
254 }
255 list.remove(index);
256 return true;
257 }
258
259
260
261
262
263
264
265
266
267
268
269
270
271 public final boolean removeMetaObject(MCRMetaInterface obj) {
272 return list.remove(obj);
273 }
274
275
276
277
278 public final void removeInheritedMetadata() {
279 list.removeIf(mi -> mi.getInherited() > 0);
280 }
281
282
283
284
285
286
287
288
289
290
291 @SuppressWarnings("unchecked")
292 public final void setFromDOM(Element element) throws MCRException {
293
294 String fullname;
295 Class<? extends MCRMetaInterface> forName;
296 try {
297 String classname = element.getAttributeValue("class");
298 if (classname == null) {
299 throw new MCRException("Missing required class attribute in element " + element.getName());
300 }
301 fullname = META_PACKAGE_NAME + classname;
302 forName = MCRClassTools.forName(fullname);
303 setClass(forName);
304 } catch (ClassNotFoundException e) {
305 throw new MCRException(e);
306 }
307 tag = element.getName();
308 String heritable = element.getAttributeValue("heritable");
309 if (heritable != null) {
310 setHeritable(Boolean.valueOf(heritable));
311 }
312
313 String notInherit = element.getAttributeValue("notinherit");
314 if (notInherit != null) {
315 setNotInherit(Boolean.valueOf(notInherit));
316 }
317
318 List<Element> elementList = element.getChildren();
319 for (Element subtag : elementList) {
320 MCRMetaInterface obj;
321 try {
322 obj = forName.getDeclaredConstructor().newInstance();
323 obj.setFromDOM(subtag);
324 } catch (ReflectiveOperationException e) {
325 throw new MCRException(fullname + " ReflectiveOperationException", e);
326 }
327
328 list.add(obj);
329 }
330 }
331
332
333
334
335
336
337
338
339
340
341
342 public final Element createXML(boolean flag) throws MCRException {
343 try {
344 validate();
345 } catch (MCRException exc) {
346 debug();
347 throw new MCRException("MCRMetaElement : The content is not valid: Tag=" + this.tag, exc);
348 }
349 Element elm = new Element(tag);
350 elm.setAttribute("class", getClassName());
351 elm.setAttribute("heritable", String.valueOf(heritable));
352 elm.setAttribute("notinherit", String.valueOf(notinherit));
353 list
354 .stream()
355 .filter(metaInterface -> (flag || metaInterface.getInherited() == 0))
356 .map(MCRMetaInterface::createXML)
357 .forEachOrdered(elm::addContent);
358 return elm;
359 }
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378 public JsonObject createJSON(boolean flag) {
379 JsonObject meta = new JsonObject();
380 meta.addProperty("class", getClassName());
381 meta.addProperty("heritable", isHeritable());
382 meta.addProperty("notinherit", notinherit);
383 JsonArray data = new JsonArray();
384 list
385 .stream()
386 .filter(metaInterface -> (flag || metaInterface.getInherited() == 0))
387 .map(MCRMetaInterface::createJSON)
388 .forEachOrdered(data::add);
389 meta.add("data", data);
390 return meta;
391 }
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406 public final boolean isValid() {
407 try {
408 validate();
409 return true;
410 } catch (MCRException exc) {
411 LOGGER.warn("The '{}' is invalid.", getTag(), exc);
412 }
413 return false;
414 }
415
416
417
418
419
420
421
422
423
424
425
426
427 public void validate() throws MCRException {
428 tag = MCRUtils.filterTrimmedNotEmpty(tag).orElse(null);
429 if (tag == null) {
430 throw new MCRException("No tag name defined!");
431 }
432 if (clazz == null) {
433 throw new MCRException(getTag() + ": @class is not defined");
434 }
435 if (!clazz.getPackage().getName().equals(META_PACKAGE_NAME.substring(0, META_PACKAGE_NAME.length() - 1))) {
436 throw new MCRException(
437 getTag() + ": package " + clazz.getPackage().getName() + " does not equal " + META_PACKAGE_NAME);
438 }
439 if (list.size() == 0) {
440 throw new MCRException(getTag() + ": does not contain any sub elements");
441 }
442 }
443
444
445
446
447 @Override
448 public final MCRMetaElement clone() {
449 MCRMetaElement out = new MCRMetaElement();
450 out.setClass(getClazz());
451 out.setTag(tag);
452 out.setHeritable(heritable);
453 out.setNotInherit(notinherit);
454
455 for (int i = 0; i < size(); i++) {
456 MCRMetaInterface mif = (list.get(i)).clone();
457 out.addMetaObject(mif);
458 }
459
460 return out;
461 }
462
463
464
465
466 public final void debug() {
467 if (LOGGER.isDebugEnabled()) {
468 LOGGER.debug("ClassName = {}", getClassName());
469 LOGGER.debug("Tag = {}", tag);
470 LOGGER.debug("Heritable = {}", String.valueOf(heritable));
471 LOGGER.debug("NotInherit = {}", String.valueOf(notinherit));
472 LOGGER.debug("Elements = {}", String.valueOf(list.size()));
473 LOGGER.debug(" ");
474 for (MCRMetaInterface aList : list) {
475 aList.debug();
476 }
477 }
478 }
479
480
481
482
483
484
485 public Stream<MCRMetaInterface> stream() {
486 return list.stream();
487 }
488
489 @Override
490 public Iterator<MCRMetaInterface> iterator() {
491 return list.iterator();
492 }
493
494 }