1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.mycore.datamodel.common;
20
21 import java.util.Arrays;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.HashSet;
25 import java.util.LinkedList;
26 import java.util.Map;
27 import java.util.Optional;
28 import java.util.stream.Collectors;
29 import java.util.stream.Stream;
30
31 import org.apache.logging.log4j.LogManager;
32 import org.apache.logging.log4j.Logger;
33 import org.mycore.common.MCRUtils;
34 import org.mycore.common.config.MCRConfiguration2;
35 import org.mycore.datamodel.classifications2.MCRCategLinkReference;
36 import org.mycore.datamodel.classifications2.MCRCategLinkServiceFactory;
37 import org.mycore.datamodel.classifications2.MCRCategoryID;
38 import org.mycore.datamodel.metadata.MCRDerivate;
39 import org.mycore.datamodel.metadata.MCRMetaClassification;
40 import org.mycore.datamodel.metadata.MCRMetaDerivateLink;
41 import org.mycore.datamodel.metadata.MCRMetaElement;
42 import org.mycore.datamodel.metadata.MCRMetaLink;
43 import org.mycore.datamodel.metadata.MCRMetaLinkID;
44 import org.mycore.datamodel.metadata.MCRMetadataManager;
45 import org.mycore.datamodel.metadata.MCRObject;
46 import org.mycore.datamodel.metadata.MCRObjectID;
47 import org.mycore.datamodel.metadata.MCRObjectMetadata;
48 import org.mycore.datamodel.metadata.MCRObjectStructure;
49
50
51
52
53
54
55
56
57 public class MCRLinkTableManager {
58
59 public static final String ENTRY_TYPE_CHILD = "child";
60
61 public static final String ENTRY_TYPE_DERIVATE = "derivate";
62
63 public static final String ENTRY_TYPE_DERIVATE_LINK = "derivate_link";
64
65 public static final String ENTRY_TYPE_PARENT = "parent";
66
67 public static final String ENTRY_TYPE_REFERENCE = "reference";
68
69
70 protected static MCRLinkTableManager singleton;
71
72
73 static Logger LOGGER = LogManager.getLogger();
74
75 private MCRLinkTableInterface linkTableInstance = null;
76
77
78
79
80
81
82 public static synchronized MCRLinkTableManager instance() {
83 if (singleton == null) {
84 singleton = new MCRLinkTableManager();
85 }
86
87 return singleton;
88 }
89
90
91
92
93 protected MCRLinkTableManager() {
94
95 linkTableInstance = MCRConfiguration2
96 .getOrThrow("MCR.Persistence.LinkTable.Store.Class", MCRConfiguration2::instantiateClass);
97 }
98
99
100
101
102
103
104
105
106
107
108
109
110
111 public void addReferenceLink(MCRObjectID from, MCRObjectID to, String type, String attr) {
112 addReferenceLink(from.toString(), to.toString(), type, attr);
113 }
114
115
116
117
118
119
120
121
122
123
124
125
126
127 public void addReferenceLink(String from, String to, String type, String attr) {
128 from = MCRUtils.filterTrimmedNotEmpty(from).orElse(null);
129 if (from == null) {
130 LOGGER.warn("The from value of a reference link is false, the link was not added to the link table");
131 return;
132 }
133
134 to = MCRUtils.filterTrimmedNotEmpty(to).orElse(null);
135 if (to == null) {
136 LOGGER.warn("The to value of a reference link is false, the link was not added to the link table");
137 return;
138 }
139
140 type = MCRUtils.filterTrimmedNotEmpty(type).orElse(null);
141 if (type == null) {
142 LOGGER.warn("The type value of a reference link is false, the link was not added to the link table");
143 return;
144 }
145
146 attr = MCRUtils.filterTrimmedNotEmpty(attr).orElse("");
147
148 LOGGER.debug("Link in table {} add for {}<-->{} with {} and {}", type, from, to, type, attr);
149
150 try {
151 linkTableInstance.create(from, to, type, attr);
152 } catch (Exception e) {
153 LOGGER.warn("An error occured while adding a dataset from the reference link table, adding not succesful.",
154 e);
155 }
156 }
157
158
159
160
161
162
163
164 public void deleteReferenceLink(MCRObjectID from) {
165 deleteReferenceLink(from.toString());
166 }
167
168
169
170
171
172
173
174 public void deleteReferenceLink(String from) {
175 from = MCRUtils.filterTrimmedNotEmpty(from).orElse(null);
176 if (from == null) {
177 LOGGER
178 .warn("The from value of a reference link is false, the link was " + "not deleted from the link table");
179 return;
180 }
181
182 try {
183 linkTableInstance.delete(from, null, null);
184 } catch (Exception e) {
185 LOGGER.warn("An error occured while deleting a dataset from the" + from
186 + " reference link table, deleting could be not succesful.", e);
187 }
188 }
189
190
191
192
193
194
195
196
197
198
199
200 public void deleteReferenceLink(String from, String to, String type) {
201 from = MCRUtils.filterTrimmedNotEmpty(from).orElse(null);
202 if (from == null) {
203 LOGGER
204 .warn("The from value of a reference link is false, the link was " + "not deleted from the link table");
205 return;
206 }
207 try {
208 linkTableInstance.delete(from, to, type);
209 } catch (Exception e) {
210 LOGGER.warn("An error occured while deleting a dataset from the"
211 + " reference link table, deleting is not succesful.", e);
212 }
213 }
214
215
216
217
218
219
220
221
222 public int countReferenceLinkTo(MCRObjectID to) {
223 return countReferenceLinkTo(to.toString());
224 }
225
226
227
228
229
230
231
232
233 public int countReferenceLinkTo(String to) {
234 to = MCRUtils.filterTrimmedNotEmpty(to).orElse(null);
235 if (to == null) {
236 LOGGER.warn("The to value of a reference link is false, the link was " + "not added to the link table");
237
238 return 0;
239 }
240
241 try {
242 return linkTableInstance.countTo(null, to, null, null);
243 } catch (Exception e) {
244 LOGGER.warn("An error occured while searching for references of " + to + ".", e);
245 }
246
247 return 0;
248 }
249
250
251
252
253
254
255
256
257
258
259 public int countReferenceLinkTo(String to, String[] types, String restriction) {
260 Optional<String> myTo = MCRUtils.filterTrimmedNotEmpty(to);
261 if (!myTo.isPresent()) {
262 LOGGER.warn("The to value of a reference link is false, the link was " + "not added to the link table");
263 return 0;
264 }
265
266 try {
267 if (types != null && types.length > 0) {
268 return Stream.of(types).mapToInt(type -> linkTableInstance.countTo(null, myTo.get(), type, restriction))
269 .sum();
270 }
271 return linkTableInstance.countTo(null, myTo.get(), null, restriction);
272 } catch (Exception e) {
273 LOGGER.warn("An error occured while searching for references of " + to + ".", e);
274 return 0;
275 }
276 }
277
278
279
280
281
282
283
284
285
286
287 public Map<String, Number> countReferenceCategory(String classid) {
288 return linkTableInstance.getCountedMapOfMCRTO(classid);
289 }
290
291
292
293
294
295
296
297
298
299
300
301 public int countReferenceCategory(String classid, String categid) {
302 return countReferenceLinkTo(classid + "##" + categid, null, null);
303 }
304
305
306
307
308
309
310
311
312 public Collection<String> getSourceOf(MCRObjectID to) {
313 return getSourceOf(to.toString());
314 }
315
316
317
318
319
320
321
322
323 public Collection<String> getSourceOf(String to) {
324 if (to == null || to.length() == 0) {
325 LOGGER.warn("The to value of a reference link is false, the link was not found in the link table");
326 return Collections.emptyList();
327 }
328
329 try {
330 return linkTableInstance.getSourcesOf(to, null);
331 } catch (Exception e) {
332 LOGGER.warn("An error occured while searching for references to " + to + ".", e);
333 return Collections.emptyList();
334 }
335 }
336
337
338
339
340
341
342
343
344
345
346
347 public Collection<String> getSourceOf(MCRObjectID to, String type) {
348 return getSourceOf(to.toString(), type);
349 }
350
351
352
353
354
355
356
357
358
359
360
361 public Collection<String> getSourceOf(String to, String type) {
362 if (to == null || to.length() == 0) {
363 LOGGER.warn("The to value of a reference link is false, the link was not found in the link table");
364 return Collections.emptyList();
365 }
366 if (type == null || type.length() == 0) {
367 LOGGER.warn("The type value of a reference link is false, the link was not found in the link table");
368 return Collections.emptyList();
369 }
370
371 try {
372 return linkTableInstance.getSourcesOf(to, type);
373 } catch (Exception e) {
374 LOGGER.warn("An error occured while searching for references to " + to + " with " + type + ".", e);
375 return Collections.emptyList();
376 }
377 }
378
379
380
381
382
383
384
385
386
387
388
389 public Collection<String> getSourceOf(String[] to, String type) {
390 if (to == null || to.length == 0) {
391 LOGGER.warn("The to value of a reference link is false, the link was not found in the link table");
392 return Collections.emptyList();
393 }
394 LinkedList<String> ll = new LinkedList<>();
395 try {
396 for (String singleTo : to) {
397 ll.addAll(linkTableInstance.getSourcesOf(singleTo, type));
398 }
399 return ll;
400 } catch (Exception e) {
401 LOGGER.warn("An error occured while searching for references to " + Arrays.toString(to) + ".", e);
402 return ll;
403 }
404 }
405
406
407
408
409
410
411
412
413
414
415
416 public Collection<String> getDestinationOf(MCRObjectID from, String type) {
417 return getDestinationOf(from.toString(), type);
418 }
419
420
421
422
423
424
425
426
427
428
429
430
431 public Collection<String> getDestinationOf(String from, String type) {
432 if (from == null || from.length() == 0) {
433 LOGGER.warn("The from value of a reference link is false, the link was not found in the link table");
434 return Collections.emptyList();
435 }
436 if (type == null || type.length() == 0) {
437 LOGGER.warn("The type value of a reference link is false, the link was not found in the link table");
438 return Collections.emptyList();
439 }
440
441 try {
442 return linkTableInstance.getDestinationsOf(from, type);
443 } catch (Exception e) {
444 LOGGER.warn("An error occured while searching for references from " + from + ".", e);
445 return Collections.emptyList();
446 }
447 }
448
449
450
451
452
453
454
455 public void create(MCRObject obj) {
456 MCRObjectID mcrId = obj.getId();
457
458 MCRObjectMetadata meta = obj.getMetadata();
459
460 Collection<MCRCategoryID> categories = new HashSet<>();
461 meta.stream().flatMap(MCRMetaElement::stream).forEach(inf -> {
462 if (inf instanceof MCRMetaClassification) {
463 String classId = ((MCRMetaClassification) inf).getClassId();
464 String categId = ((MCRMetaClassification) inf).getCategId();
465 categories.add(new MCRCategoryID(classId, categId));
466 } else if (inf instanceof MCRMetaLinkID) {
467 addReferenceLink(mcrId.toString(), ((MCRMetaLink) inf).getXLinkHref(),
468 MCRLinkTableManager.ENTRY_TYPE_REFERENCE, "");
469 } else if (inf instanceof MCRMetaDerivateLink) {
470 addReferenceLink(mcrId.toString(), ((MCRMetaLink) inf).getXLinkHref(),
471 MCRLinkTableManager.ENTRY_TYPE_DERIVATE_LINK, "");
472 }
473 });
474 MCRCategoryID state = obj.getService().getState();
475 if (state != null) {
476 categories.add(state);
477 }
478 categories.addAll(obj.getService().getClassifications());
479 if (categories.size() > 0) {
480 MCRCategLinkReference objectReference = new MCRCategLinkReference(mcrId);
481 MCRCategLinkServiceFactory.getInstance().setLinks(objectReference, categories);
482 }
483
484 MCRObjectStructure structure = obj.getStructure();
485 for (int i = 0; i < structure.getDerivates().size(); i++) {
486 MCRMetaLinkID lid = structure.getDerivates().get(i);
487 addReferenceLink(obj.getId(), lid.getXLinkHrefID(), MCRLinkTableManager.ENTRY_TYPE_DERIVATE, "");
488 }
489
490 if (structure.getParentID() != null) {
491 addReferenceLink(mcrId, structure.getParentID(), MCRLinkTableManager.ENTRY_TYPE_PARENT, "");
492 }
493 }
494
495
496
497
498
499
500 public void delete(MCRObjectID id) {
501 deleteReferenceLink(id);
502 MCRCategLinkReference reference = new MCRCategLinkReference(id);
503 MCRCategLinkServiceFactory.getInstance().deleteLink(reference);
504 }
505
506
507
508
509
510
511 public void update(MCRObjectID id) {
512 delete(id);
513 if ("derivate".equals(id.getTypeId())) {
514 create(MCRMetadataManager.retrieveMCRDerivate(id));
515 } else {
516 create(MCRMetadataManager.retrieveMCRObject(id));
517 }
518 }
519
520 public void create(MCRDerivate der) {
521 Collection<MCRCategoryID> categoryList = new HashSet<>();
522 categoryList.addAll(der.getDerivate().getClassifications()
523 .stream()
524 .map(this::metaClassToCategoryID)
525 .collect(Collectors.toList()));
526
527 MCRCategoryID state = der.getService().getState();
528 if (state != null) {
529 categoryList.add(state);
530 }
531
532 MCRCategLinkReference objectReference = new MCRCategLinkReference(der.getId());
533 MCRCategLinkServiceFactory.getInstance().setLinks(objectReference, categoryList);
534 }
535
536 private MCRCategoryID metaClassToCategoryID(MCRMetaClassification metaClazz) {
537 return new MCRCategoryID(metaClazz.getClassId(), metaClazz.getCategId());
538 }
539 }