1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.mycore.frontend.cli;
20
21 import java.io.File;
22 import java.io.FileNotFoundException;
23 import java.io.FileOutputStream;
24 import java.io.IOException;
25 import java.nio.file.FileVisitResult;
26 import java.nio.file.Files;
27 import java.nio.file.Path;
28 import java.nio.file.PathMatcher;
29 import java.nio.file.SimpleFileVisitor;
30 import java.nio.file.StandardCopyOption;
31 import java.nio.file.attribute.BasicFileAttributes;
32 import java.util.ArrayList;
33 import java.util.Collection;
34 import java.util.HashMap;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.function.Predicate;
38 import java.util.stream.Collectors;
39 import java.util.stream.Stream;
40
41 import javax.xml.transform.Transformer;
42 import javax.xml.transform.TransformerException;
43 import javax.xml.transform.stream.StreamResult;
44
45 import org.apache.logging.log4j.LogManager;
46 import org.apache.logging.log4j.Logger;
47 import org.jdom2.Document;
48 import org.jdom2.Element;
49 import org.jdom2.JDOMException;
50 import org.jdom2.output.XMLOutputter;
51 import org.jdom2.transform.JDOMSource;
52 import org.mycore.access.MCRAccessInterface;
53 import org.mycore.access.MCRAccessException;
54 import org.mycore.access.MCRRuleAccessInterface;
55 import org.mycore.access.MCRAccessManager;
56 import org.mycore.common.MCRException;
57 import org.mycore.common.MCRPersistenceException;
58 import org.mycore.common.content.MCRContent;
59 import org.mycore.common.content.MCRPathContent;
60 import org.mycore.common.content.transformer.MCRXSLTransformer;
61 import org.mycore.common.events.MCREvent;
62 import org.mycore.common.events.MCREventManager;
63 import org.mycore.common.xml.MCRXMLHelper;
64 import org.mycore.datamodel.classifications2.MCRCategoryDAO;
65 import org.mycore.datamodel.classifications2.MCRCategoryDAOFactory;
66 import org.mycore.datamodel.classifications2.MCRCategoryID;
67 import org.mycore.datamodel.common.MCRActiveLinkException;
68 import org.mycore.datamodel.common.MCRXMLMetadataManager;
69 import org.mycore.datamodel.metadata.MCRDerivate;
70 import org.mycore.datamodel.metadata.MCRMetaClassification;
71 import org.mycore.datamodel.metadata.MCRMetaEnrichedLinkID;
72 import org.mycore.datamodel.metadata.MCRMetaEnrichedLinkIDFactory;
73 import org.mycore.datamodel.metadata.MCRMetaLinkID;
74 import org.mycore.datamodel.metadata.MCRMetadataManager;
75 import org.mycore.datamodel.metadata.MCRObject;
76 import org.mycore.datamodel.metadata.MCRObjectID;
77 import org.mycore.datamodel.niofs.MCRAbstractFileSystem;
78 import org.mycore.datamodel.niofs.MCRPath;
79 import org.mycore.datamodel.niofs.utils.MCRDerivateUtil;
80 import org.mycore.datamodel.niofs.utils.MCRTreeCopier;
81 import org.mycore.frontend.cli.annotation.MCRCommand;
82 import org.mycore.frontend.cli.annotation.MCRCommandGroup;
83 import org.xml.sax.SAXException;
84 import org.xml.sax.SAXParseException;
85
86
87
88
89
90
91
92
93
94
95 @MCRCommandGroup(name = "Derivate Commands")
96 public class MCRDerivateCommands extends MCRAbstractCommands {
97
98
99 private static Logger LOGGER = LogManager.getLogger(MCRDerivateCommands.class);
100
101
102 private static final MCRAccessInterface ACCESS_IMPL = MCRAccessManager.getAccessImpl();
103
104
105 public static final String DEFAULT_STYLE = "save-derivate.xsl";
106
107
108 private static final Map<String, Transformer> TRANSFORMER_CACHE = new HashMap<>();
109
110
111
112
113 @MCRCommand(syntax = "delete all derivates", help = "Removes all derivates from the repository", order = 10)
114 public static List<String> deleteAllDerivates() {
115 return MCRCommandUtils.getIdsForType("derivate")
116 .map(id -> "delete derivate " + id)
117 .collect(Collectors.toList());
118 }
119
120
121
122
123
124
125
126
127
128 @MCRCommand(syntax = "delete derivate {0}",
129 help = "The command remove a derivate with the MCRObjectID {0}",
130 order = 30)
131 public static void delete(String id) throws MCRPersistenceException, MCRActiveLinkException, MCRAccessException {
132 MCRObjectID objectID = MCRObjectID.getInstance(id);
133 MCRMetadataManager.deleteMCRDerivate(objectID);
134 LOGGER.info("{} deleted.", objectID);
135 }
136
137
138
139
140
141
142
143
144
145
146 @MCRCommand(syntax = "delete derivate from {0} to {1}",
147 help = "The command remove derivates in the number range between the MCRObjectID {0} and {1}.",
148 order = 20)
149 public static List<String> delete(String idFrom, String idTo)
150 throws MCRPersistenceException, MCRActiveLinkException, MCRAccessException {
151 return MCRCommandUtils.getIdsFromIdToId(idFrom, idTo)
152 .map(id -> "delete derivate " + id)
153 .collect(Collectors.toList());
154 }
155
156
157
158
159
160
161
162 @MCRCommand(syntax = "load all derivates from directory {0}",
163 help = "Loads all MCRDerivates from the directory {0} to the system. " +
164 "If the numerical part of a provided ID is zero, a new ID with the same project ID and type is assigned.",
165 order = 60)
166 public static List<String> loadFromDirectory(String directory) {
167 return processFromDirectory(directory, false);
168 }
169
170
171
172
173
174
175
176 @MCRCommand(syntax = "update all derivates from directory {0}",
177 help = "The command update all derivates form the directory {0} in the system.",
178 order = 70)
179 public static List<String> updateFromDirectory(String directory) {
180 return processFromDirectory(directory, true);
181 }
182
183
184
185
186
187
188
189
190
191 private static List<String> processFromDirectory(String directory, boolean update) {
192 File dir = new File(directory);
193
194 if (!dir.isDirectory()) {
195 LOGGER.warn("{} ignored, is not a directory.", directory);
196 return null;
197 }
198
199 File[] list = dir.listFiles();
200
201 if (list.length == 0) {
202 LOGGER.warn("No files found in directory {}", directory);
203 return null;
204 }
205
206 List<String> cmds = new ArrayList<>();
207 for (File file : list) {
208 String name = file.getName();
209 if (!(name.endsWith(".xml") && name.contains("derivate"))) {
210 continue;
211 }
212 name = name.substring(0, name.length() - 4);
213 File contentDir = new File(dir, name);
214 if (!(contentDir.exists() && contentDir.isDirectory())) {
215 continue;
216 }
217 cmds.add((update ? "update" : "load") + " derivate from file " + file.getAbsolutePath());
218 }
219
220 return cmds;
221 }
222
223
224
225
226
227
228
229
230 @MCRCommand(syntax = "load derivate from file {0}",
231 help = "Loads an MCRDerivate from the file {0} to the system. " +
232 "If the numerical part of the provided ID is zero, a new ID with the same project ID and type is assigned.",
233 order = 40)
234 public static boolean loadFromFile(String file)
235 throws SAXParseException, IOException, MCRPersistenceException, MCRAccessException {
236 return loadFromFile(file, true);
237 }
238
239
240
241
242
243
244
245
246
247
248
249 public static boolean loadFromFile(String file, boolean importMode)
250 throws SAXParseException, IOException, MCRPersistenceException, MCRAccessException {
251 return processFromFile(new File(file), false, importMode);
252 }
253
254
255
256
257
258
259
260
261
262
263 @MCRCommand(syntax = "update derivate from file {0}",
264 help = "The command update a derivate form the file {0} in the system.",
265 order = 50)
266 public static boolean updateFromFile(String file)
267 throws SAXParseException, IOException, MCRPersistenceException, MCRAccessException {
268 return updateFromFile(file, true);
269 }
270
271
272
273
274
275
276
277
278
279
280 public static boolean updateFromFile(String file, boolean importMode)
281 throws SAXParseException, IOException, MCRPersistenceException, MCRAccessException {
282 return processFromFile(new File(file), true, importMode);
283 }
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299 private static boolean processFromFile(File file, boolean update, boolean importMode) throws SAXParseException,
300 IOException, MCRPersistenceException, MCRAccessException {
301 if (!file.getName().endsWith(".xml")) {
302 LOGGER.warn("{} ignored, does not end with *.xml", file);
303 return false;
304 }
305
306 if (!file.isFile()) {
307 LOGGER.warn("{} ignored, is not a file.", file);
308 return false;
309 }
310
311 LOGGER.info("Reading file {} ...", file);
312
313 MCRDerivate derivate = new MCRDerivate(file.toURI());
314 derivate.setImportMode(importMode);
315
316
317 if (derivate.getDerivate().getInternals() != null) {
318 String path = derivate.getDerivate().getInternals().getSourcePath();
319 if (path == null) {
320 path = "";
321 } else {
322 path = path.replace('/', File.separatorChar).replace('\\', File.separatorChar);
323 }
324 if (path.trim().length() <= 1) {
325
326 path = derivate.getId().toString();
327 }
328 File sPath = new File(path);
329
330 if (!sPath.isAbsolute()) {
331
332 String prefix = file.getParent();
333
334 if (prefix != null) {
335 path = prefix + File.separator + path;
336 }
337 }
338
339 derivate.getDerivate().getInternals().setSourcePath(path);
340 LOGGER.info("Source path --> {}", path);
341 }
342
343 if (update) {
344 MCRMetadataManager.update(derivate);
345 LOGGER.info("{} updated.", derivate.getId());
346 } else {
347 MCRMetadataManager.create(derivate);
348 LOGGER.info("{} loaded.", derivate.getId());
349 }
350
351 return true;
352 }
353
354
355
356
357
358
359
360
361
362
363
364
365
366 @MCRCommand(syntax = "show loadable derivate of {0} to directory {1}",
367 help = "The command store the derivate with the MCRObjectID {0} to the directory {1}, without ifs-metadata",
368 order = 130)
369 public static void show(String id, String dirname) {
370 exportWithStylesheet(id, id, dirname, "save");
371 }
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386 @MCRCommand(syntax = "export derivate {0} to directory {1} with stylesheet {2}",
387 help = "Stores the derivate with the MCRObjectID {0} to the directory {1}"
388 + " with the stylesheet {2}-derivate.xsl. For {2}, the default is xsl/save.",
389 order = 90)
390 public static void exportWithStylesheet(String id, String dirname, String style) {
391 exportWithStylesheet(id, id, dirname, style);
392 }
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411 @MCRCommand(syntax = "export derivates from {0} to {1} to directory {2} with stylesheet {3}",
412 help = "Stores all derivates with MCRObjectID's between {0} and {1} to the directory {2}"
413 + " with the stylesheet {3}-derivate.xsl. For {3}, the default is xsl/save.",
414 order = 80)
415 public static void exportWithStylesheet(String fromID, String toID, String dirname, String style) {
416
417 MCRObjectID fid = null;
418 MCRObjectID tid = null;
419
420 try {
421 fid = MCRObjectID.getInstance(fromID);
422 } catch (Exception ex) {
423 LOGGER.error("FromID : {}", ex.getMessage());
424
425 return;
426 }
427
428 try {
429 tid = MCRObjectID.getInstance(toID);
430 } catch (Exception ex) {
431 LOGGER.error("ToID : {}", ex.getMessage());
432
433 return;
434 }
435
436
437 File dir = new File(dirname);
438
439 if (dir.isFile()) {
440 LOGGER.error("{} is not a dirctory.", dirname);
441
442 return;
443 }
444
445 Transformer trans = getTransformer(style != null ? style + "-derivate" : null);
446
447 int k = 0;
448
449 try {
450 for (int i = fid.getNumberAsInteger(); i < tid.getNumberAsInteger() + 1; i++) {
451
452 exportDerivate(dir, trans, MCRObjectID.formatID(fid.getProjectId(), fid.getTypeId(), i));
453
454 k++;
455 }
456 } catch (Exception ex) {
457 LOGGER.error(ex.getMessage());
458 LOGGER.error("Exception while store file or objects to {}", dir.getAbsolutePath(), ex);
459
460 return;
461 }
462
463 LOGGER.info("{} Object's stored under {}.", k, dir.getAbsolutePath());
464 }
465
466
467
468
469
470
471
472
473
474
475
476 @MCRCommand(syntax = "export all derivates to directory {0} with stylesheet {1}",
477 help = "Stores all derivates to the directory {0} with the stylesheet {1}-derivate.xsl."
478 + " For {1}, the default is xsl/save.",
479 order = 100)
480 public static List<String> exportAllDerivatesWithStylesheet(String dirname, String style) {
481 return MCRCommandUtils.getIdsForType("derivate")
482 .map(id -> "export derivate " + id + " to directory " + dirname + " with stylesheet " + style)
483 .collect(Collectors.toList());
484 }
485
486
487
488
489
490
491
492
493
494
495
496 @MCRCommand(syntax = "export all derivates of project {0} to directory {1} with stylesheet {2}",
497 help = "Stores all derivates of project {0} to the directory {1} with the stylesheet {2}-derivate.xsl."
498 + " For {2}, the default is xsl/save.",
499 order = 110)
500 public static List<String> exportAllDerivatesOfProjectWithStylesheet(String project, String dirname, String style) {
501 return MCRCommandUtils.getIdsForProjectAndType(project, "derivate")
502 .map(id -> "export derivate " + id + " to directory " + dirname + " with stylesheet " + style)
503 .collect(Collectors.toList());
504 }
505
506
507
508
509
510
511
512
513
514 private static void exportDerivate(File dir, Transformer trans, String nid)
515 throws TransformerException, IOException {
516
517 Document xml = null;
518 MCRDerivate obj;
519
520 MCRObjectID derivateID = MCRObjectID.getInstance(nid);
521 try {
522 obj = MCRMetadataManager.retrieveMCRDerivate(derivateID);
523 String path = obj.getDerivate().getInternals().getSourcePath();
524
525 LOGGER.info("Old Internal Path ====>{}", path);
526 obj.getDerivate().getInternals().setSourcePath(nid);
527 LOGGER.info("New Internal Path ====>{}", nid);
528
529 if (ACCESS_IMPL instanceof MCRRuleAccessInterface) {
530 Collection<String> l = ((MCRRuleAccessInterface) ACCESS_IMPL).getPermissionsForID(nid);
531 for (String permission : l) {
532 Element rule = ((MCRRuleAccessInterface) ACCESS_IMPL).getRule(nid, permission);
533 obj.getService().addRule(permission, rule);
534 }
535 }
536
537
538 xml = obj.createXML();
539
540 } catch (MCRException ex) {
541 LOGGER.warn("Could not read {}, continue with next ID", nid);
542 return;
543 }
544 File xmlOutput = new File(dir, derivateID + ".xml");
545 FileOutputStream out = new FileOutputStream(xmlOutput);
546 dir = new File(dir, derivateID.toString());
547
548 if (trans != null) {
549 trans.setParameter("dirname", dir.getPath());
550 StreamResult sr = new StreamResult(out);
551 trans.transform(new JDOMSource(xml), sr);
552 } else {
553 new XMLOutputter().output(xml, out);
554 out.flush();
555 out.close();
556 }
557
558 LOGGER.info("Object {} stored under {}.", nid, xmlOutput);
559
560
561 if (!dir.isDirectory()) {
562 dir.mkdir();
563 }
564 MCRPath rootPath = MCRPath.getPath(derivateID.toString(), "/");
565 Files.walkFileTree(rootPath, new MCRTreeCopier(rootPath, dir.toPath()));
566
567 LOGGER.info("Derivate {} saved under {} and {}.", nid, dir, xmlOutput);
568 }
569
570
571
572
573
574
575
576
577
578 private static Transformer getTransformer(String style) {
579 return MCRCommandUtils.getTransformer(style, DEFAULT_STYLE, TRANSFORMER_CACHE);
580 }
581
582
583
584
585 @MCRCommand(syntax = "repair derivate search of type derivate",
586 help = "The command read the Content store and reindex the derivate search stores.",
587 order = 140)
588 public static List<String> repairDerivateSearch() {
589 LOGGER.info("Start the repair for type derivate.");
590 return MCRCommandUtils.getIdsForType("derivate")
591 .map(id -> "repair derivate search of ID " + id)
592 .collect(Collectors.toList());
593 }
594
595
596
597
598
599
600
601 @MCRCommand(syntax = "repair derivate search of project {0}",
602 help = "Reads the Content store for project {0} and reindexes the derivate search stores.",
603 order = 141)
604 public static List<String> repairDerivateSearchForBase(String project) {
605 LOGGER.info("Start the repair for project {}.", project);
606 return MCRCommandUtils.getIdsForProjectAndType(project, "derivate")
607 .map(id -> "repair derivate search of ID " + id)
608 .collect(Collectors.toList());
609 }
610
611
612
613
614
615
616
617 @MCRCommand(syntax = "repair derivate search of ID {0}",
618 help = "The command read the Content store for MCRObjectID {0} and reindex the derivate search store.",
619 order = 150)
620 public static void repairDerivateSearchForID(String id) throws IOException {
621 LOGGER.info("Start the repair for the ID {}", id);
622 doForChildren(MCRPath.getPath(id, "/"));
623 LOGGER.info("Repaired {}", id);
624 }
625
626
627
628
629
630
631
632 private static void doForChildren(Path rootPath) throws IOException {
633 Files.walkFileTree(rootPath, new SimpleFileVisitor<Path>() {
634 @Override
635 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
636
637 MCREvent evt = new MCREvent(MCREvent.ObjectType.PATH, MCREvent.EventType.REPAIR);
638 evt.put(MCREvent.PATH_KEY, file);
639 evt.put(MCREvent.FILEATTR_KEY, attrs);
640 MCREventManager.instance().handleEvent(evt);
641 LOGGER.debug("repaired file {}", file);
642 return super.visitFile(file, attrs);
643 }
644
645 });
646 }
647
648
649
650
651 @MCRCommand(syntax = "synchronize all derivates",
652 help = "The command read each derivate and synchronize the xlink:label with "
653 + "the derivate entry of the mycoreobject.",
654 order = 160)
655 public static List<String> synchronizeAllDerivates() {
656 LOGGER.info("Start the synchronization for derivates.");
657 return MCRCommandUtils.getIdsForType("derivate")
658 .map(id -> "synchronize derivate with ID " + id)
659 .collect(Collectors.toList());
660 }
661
662
663
664
665 @MCRCommand(syntax = "link derivate {0} to {1}",
666 help = "links the given derivate {0} to the given mycore object {1}",
667 order = 180)
668 public static void linkDerivateToObject(String derivateId, String objectId) throws Exception {
669 if (derivateId == null || objectId == null) {
670 LOGGER.error("Either derivate id or object id is null. Derivate={}, object={}", derivateId, objectId);
671 return;
672 }
673 MCRObjectID derID = MCRObjectID.getInstance(derivateId);
674 MCRObjectID objID = MCRObjectID.getInstance(objectId);
675
676 if (!MCRMetadataManager.exists(objID)) {
677 throw new Exception("The object with id " + objID + " does not exist");
678 }
679
680 if (!MCRMetadataManager.exists(derID)) {
681 throw new Exception("The derivate with id " + derID + " does not exist");
682 }
683
684 MCRDerivate derObj = MCRMetadataManager.retrieveMCRDerivate(derID);
685 MCRMetaLinkID oldDerivateToObjectLink = derObj.getDerivate().getMetaLink();
686 MCRObjectID oldOwnerId = oldDerivateToObjectLink.getXLinkHrefID();
687
688
689 LOGGER.info("Setting {} as parent for derivate {}", objID, derID);
690 derObj.getDerivate().getMetaLink()
691 .setReference(objID, oldDerivateToObjectLink.getXLinkLabel(), oldDerivateToObjectLink.getXLinkTitle());
692 MCRMetadataManager.update(derObj);
693
694
695 MCRObject oldOwner = MCRMetadataManager.retrieveMCRObject(oldOwnerId);
696 List<MCRMetaEnrichedLinkID> derivates = oldOwner.getStructure().getDerivates();
697 MCRMetaLinkID oldObjectToDerivateLink = null;
698 for (MCRMetaLinkID derivate : derivates) {
699 if (derivate.getXLinkHrefID().equals(derID)) {
700 oldObjectToDerivateLink = derivate;
701 }
702 }
703 if (oldObjectToDerivateLink == null) {
704 oldObjectToDerivateLink = new MCRMetaLinkID();
705 }
706 LOGGER.info("Linking derivate {} to {}", derID, objID);
707 MCRMetaEnrichedLinkID derivateLink = MCRMetaEnrichedLinkIDFactory.getInstance().getDerivateLink(derObj);
708 MCRMetadataManager.addOrUpdateDerivateToObject(objID, derivateLink);
709
710
711 boolean flag = oldOwner.getStructure().removeDerivate(derID);
712 LOGGER.info("Unlinking derivate {} from object {}. Success={}", derID, oldOwnerId, flag);
713 MCRMetadataManager.fireUpdateEvent(oldOwner);
714 }
715
716
717
718
719
720
721
722
723 @MCRCommand(syntax = "check object entries in derivates for base {0}",
724 help = "check in all derivates of MCR base ID {0} for existing linked objects",
725 order = 400)
726 public static void checkObjectsInDerivates(String baseId) throws IOException {
727 if (baseId == null || baseId.length() == 0) {
728 LOGGER.error("Base ID missed for check object entries in derivates for base {0}");
729 return;
730 }
731 int projectPartPosition = baseId.indexOf('_');
732 if (projectPartPosition == -1) {
733 LOGGER.error("The given base ID {} has not the syntax of project_type", baseId);
734 return;
735 }
736 MCRXMLMetadataManager mgr = MCRXMLMetadataManager.instance();
737 List<String> idList = mgr.listIDsForBase(baseId.substring(0, projectPartPosition + 1) + "derivate");
738 int counter = 0;
739 int maxresults = idList.size();
740 for (String derid : idList) {
741 counter++;
742 LOGGER.info("Processing dataset {} from {} with ID: {}", counter, maxresults, derid);
743
744 MCRObjectID mcrderid = MCRObjectID.getInstance(derid);
745 MCRDerivate der = MCRMetadataManager.retrieveMCRDerivate(mcrderid);
746 MCRObjectID objid = der.getOwnerID();
747 if (!mgr.exists(objid)) {
748 LOGGER.error(" !!! Missing object {} in database for derivate ID {}", objid, mcrderid);
749 }
750 }
751 LOGGER.info("Check done for {} entries", Integer.toString(counter));
752 }
753
754 @MCRCommand(syntax = "transform xml matching file name pattern {0} in derivate {1} with stylesheet {2}",
755 help = "Finds all files in Derivate {1} which match the pattern {0} "
756 + "(the complete path with regex: or glob:*.xml syntax) and transforms them with stylesheet {2}")
757 public static void transformXMLMatchingPatternWithStylesheet(String pattern, String derivate, String stylesheet)
758 throws IOException {
759 MCRXSLTransformer transformer = new MCRXSLTransformer(stylesheet);
760 MCRPath derivateRoot = MCRPath.getPath(derivate, "/");
761 PathMatcher matcher = derivateRoot.getFileSystem().getPathMatcher(pattern);
762
763 Files.walkFileTree(derivateRoot, new SimpleFileVisitor<Path>() {
764 @Override
765 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
766 throws IOException {
767 if (matcher.matches(file)) {
768 LOGGER.info("The file {} matches the pattern {}", file, pattern);
769 MCRContent sourceContent = new MCRPathContent(file);
770
771 MCRContent resultContent = transformer.transform(sourceContent);
772 try {
773 Document source = sourceContent.asXML();
774 Document result = resultContent.asXML();
775 LOGGER.info("Transforming complete!");
776
777 if (!MCRXMLHelper.deepEqual(source, result)) {
778 LOGGER.info("Writing result..");
779 resultContent.sendTo(file, StandardCopyOption.REPLACE_EXISTING);
780 } else {
781 LOGGER.info("Result and Source is the same..");
782 }
783
784 } catch (JDOMException | SAXException e) {
785 throw new IOException("Error while processing file : " + file, e);
786 }
787
788 }
789
790 return FileVisitResult.CONTINUE;
791 }
792 });
793
794 }
795
796 @MCRCommand(syntax = "set main file of {0} to {1}",
797 help = "Sets the main file of the derivate with the id {0} to "
798 + "the file with the path {1}")
799 public static void setMainFile(final String derivateIDString, final String filePath) throws MCRAccessException {
800 if (!MCRObjectID.isValid(derivateIDString)) {
801 LOGGER.error("{} is not valid. ", derivateIDString);
802 return;
803 }
804
805
806 final MCRObjectID derivateID = MCRObjectID.getInstance(derivateIDString);
807 if (!MCRMetadataManager.exists(derivateID)) {
808 LOGGER.error("{} does not exist!", derivateIDString);
809 return;
810 }
811
812
813 String cleanPath = filePath;
814 if (filePath.startsWith(String.valueOf(MCRAbstractFileSystem.SEPARATOR))) {
815 cleanPath = filePath.substring(1);
816 }
817
818
819 final MCRPath path = MCRPath.getPath(derivateID.toString(), cleanPath);
820 if (!Files.exists(path)) {
821 LOGGER.error("File {} does not exist!", cleanPath);
822 return;
823 }
824
825 final MCRDerivate derivate = MCRMetadataManager.retrieveMCRDerivate(derivateID);
826 derivate.getDerivate().getInternals().setMainDoc(cleanPath);
827 MCRMetadataManager.update(derivate);
828 LOGGER.info("The main file of {} is now '{}'!", derivateIDString, cleanPath);
829 }
830
831 @MCRCommand(syntax = "rename files from derivate {0} with {1} to {2}",
832 help = "Renames multiple files in one Derivate with the ID {0} the given RegEx pattern {1} and the replacement"
833 + " {2}. You can try out your pattern with the command: 'test rename file {0} with {1} to {2}'.")
834 public static void renameFiles(String derivate, String pattern, String newName)
835 throws IOException {
836 MCRDerivateUtil.renameFiles(derivate, pattern, newName);
837 }
838
839 @MCRCommand(syntax = "test rename file {0} with {1} to {2}",
840 help = "Tests the rename pattern {1} on one file {0} and replaces it with {2}, so you can try the rename"
841 + " before renaming all files. This command does not change any files.")
842 public static void testRenameFile(String filename, String pattern, String newName) {
843 MCRDerivateUtil.testRenameFile(filename, pattern, newName);
844 }
845
846 @MCRCommand(syntax = "set order of derivate {0} to {1}",
847 help = "Sets the order of derivate {0} to the number {1} see also MCR-2003")
848 public static void setOrderOfDerivate(String derivateIDStr, String orderStr) throws MCRAccessException {
849 final int order = Integer.parseInt(orderStr);
850
851 final MCRObjectID derivateID = MCRObjectID.getInstance(derivateIDStr);
852
853 if (!MCRMetadataManager.exists(derivateID)) {
854 throw new MCRException("The derivate " + derivateIDStr + " does not exist!");
855 }
856
857 final MCRDerivate derivate = MCRMetadataManager.retrieveMCRDerivate(derivateID);
858 derivate.setOrder(order);
859 MCRMetadataManager.update(derivate);
860
861 }
862
863 @MCRCommand(syntax = "set classification of derivate {0} to {1}",
864 help = "Sets the classification of derivate {0} to the categories {1} (comma separated) "
865 + "of classification 'derivate_types' or any fully qualified category, removing any previous definition.")
866 public static void setClassificationOfDerivate(String derivateIDStr, String categoriesCommaList)
867 throws MCRAccessException {
868 final MCRCategoryDAO categoryDAO = MCRCategoryDAOFactory.getInstance();
869 final List<MCRCategoryID> derivateTypes = Stream.of(categoriesCommaList.split(","))
870 .map(String::trim)
871 .map(category -> category.contains(":") ? MCRCategoryID.fromString(category)
872 : new MCRCategoryID("derivate_types", category))
873 .collect(Collectors.toList());
874
875 final String nonExistingCategoriesCommaList = derivateTypes.stream()
876 .filter(Predicate.not(categoryDAO::exist))
877 .map(MCRCategoryID::getID)
878 .collect(Collectors.joining(", "));
879 if (!nonExistingCategoriesCommaList.isEmpty()) {
880 throw new MCRPersistenceException("Categories do not exist: " + nonExistingCategoriesCommaList);
881 }
882
883 final MCRObjectID derivateID = MCRObjectID.getInstance(derivateIDStr);
884 final MCRDerivate derivate = MCRMetadataManager.retrieveMCRDerivate(derivateID);
885 derivate.getDerivate().getClassifications().clear();
886 derivate.getDerivate().getClassifications()
887 .addAll(
888 derivateTypes.stream()
889 .map(categoryID -> new MCRMetaClassification("classification", 0, null, categoryID.getRootID(),
890 categoryID.getID()))
891 .collect(Collectors.toList()));
892 MCRMetadataManager.update(derivate);
893 }
894
895 }