1
2
3
4
5
6
7 package ch.colabproject.colab.api.controller;
8
9 import ch.colabproject.colab.api.controller.card.CardContentManager;
10 import ch.colabproject.colab.api.controller.document.FileManager;
11 import ch.colabproject.colab.api.controller.document.ResourceReferenceSpreadingHelper;
12 import ch.colabproject.colab.api.controller.document.YjsException;
13 import ch.colabproject.colab.api.controller.document.YjsLexicalCaller;
14 import ch.colabproject.colab.api.exceptions.ColabMergeException;
15 import ch.colabproject.colab.api.model.ColabEntity;
16 import ch.colabproject.colab.api.model.DuplicationParam;
17 import ch.colabproject.colab.api.model.card.*;
18 import ch.colabproject.colab.api.model.document.*;
19 import ch.colabproject.colab.api.model.link.ActivityFlowLink;
20 import ch.colabproject.colab.api.model.link.StickyNoteLink;
21 import ch.colabproject.colab.api.model.project.Project;
22 import ch.colabproject.colab.api.model.team.TeamMember;
23 import ch.colabproject.colab.api.model.team.TeamRole;
24 import ch.colabproject.colab.api.model.team.acl.Assignment;
25 import ch.colabproject.colab.api.model.user.User;
26 import ch.colabproject.colab.generator.model.exceptions.HttpErrorMessage;
27 import ch.colabproject.colab.generator.model.exceptions.MessageI18nKey;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 import javax.jcr.RepositoryException;
32 import java.io.IOException;
33 import java.io.InputStream;
34 import java.util.*;
35 import java.util.Map.Entry;
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 public class DuplicationManager {
52
53
54 private static final Logger logger = LoggerFactory.getLogger(DuplicationManager.class);
55
56
57 private static final Comparator<ColabEntity> ID_COMPARATOR = Comparator
58 .comparingLong(entity -> entity.getId());
59
60
61 private final DuplicationParam params;
62
63
64 private final ResourceReferenceSpreadingHelper resourceSpreader;
65
66
67 private final FileManager fileManager;
68
69
70 private final CardContentManager cardContentManager;
71
72
73 private YjsLexicalCaller yjsLexicalCaller;
74
75
76 private Map<Long, TeamRole> teamRoleMatching = new HashMap<>();
77
78
79 private Map<Long, TeamMember> teamMemberMatching = new HashMap<>();
80
81
82 private Map<Long, AbstractCardType> cardTypeMatching = new HashMap<>();
83
84
85 private Map<Long, Card> cardMatching = new HashMap<>();
86
87
88 private Map<Long, CardContent> cardContentMatching = new HashMap<>();
89
90
91 private Map<Long, AbstractResource> resourceMatching = new HashMap<>();
92
93
94 private Map<Long, Document> documentMatching = new HashMap<>();
95
96
97 private List<StickyNoteLink> stickyNoteLinksToDuplicate = new ArrayList<>();
98
99
100 private List<ActivityFlowLink> activityFlowLinksToDuplicate = new ArrayList<>();
101
102
103 private Map<Long, DocumentFile> documentFilesToProcessOnceIds = new HashMap<>();
104
105
106
107
108
109
110
111 public DuplicationManager(DuplicationParam params,
112 ResourceReferenceSpreadingHelper resourceSpreader,
113 FileManager fileManager, CardContentManager cardContentManager) {
114 this.params = params;
115 this.resourceSpreader = resourceSpreader;
116 this.fileManager = fileManager;
117 this.cardContentManager = cardContentManager;
118 }
119
120
121
122
123
124
125
126
127
128
129
130
131 public Project duplicateProject(Project originalProject) {
132 try {
133 Project newProject = new Project();
134 newProject.mergeToDuplicate(originalProject);
135
136
137
138 if (params.isWithRoles()) {
139 List<TeamRole> teamRoles = originalProject.getRoles();
140 teamRoles.sort(ID_COMPARATOR);
141
142 for (TeamRole original : teamRoles) {
143 TeamRole newTeamRole = duplicateTeamRole(original);
144
145 newTeamRole.setProject(newProject);
146 newProject.getRoles().add(newTeamRole);
147 }
148 } else {
149 logger.info("param do not duplicate project's team roles");
150 }
151
152
153
154 if (params.isWithTeamMembers()) {
155 List<TeamMember> teamMembers = originalProject.getTeamMembers();
156 teamMembers.sort(ID_COMPARATOR);
157
158 for (TeamMember original : teamMembers) {
159 TeamMember newTeamMember = duplicateTeamMember(original);
160
161 newTeamMember.setProject(newProject);
162 newProject.getTeamMembers().add(newTeamMember);
163 }
164 } else {
165 logger.info("param do not duplicate project's team members");
166 }
167
168
169
170
171
172
173
174 if (params.isWithCardTypes()) {
175 List<AbstractCardType> cardTypes = originalProject.getElementsToBeDefined();
176 cardTypes.sort(ID_COMPARATOR);
177
178 for (AbstractCardType original : cardTypes) {
179 AbstractCardType newCardType = duplicateCardType(original);
180
181 newCardType.setProject(newProject);
182 newProject.getElementsToBeDefined().add(newCardType);
183 }
184 }
185
186
187
188 if (params.isWithCardsStructure()) {
189 Card original = originalProject.getRootCard();
190 if (original != null) {
191 Card newRootCard = duplicateCard(original);
192
193 newRootCard.setRootCardProject(newProject);
194 newProject.setRootCard(newRootCard);
195 }
196
197 }
198
199
200
201 if (params.isWithStickyNotes()) {
202 stickyNoteLinksToDuplicate.sort(ID_COMPARATOR);
203
204 for (StickyNoteLink original : stickyNoteLinksToDuplicate) {
205 duplicateStickyNoteLink(original);
206 }
207 }
208
209
210
211 if (params.isWithActivityFlow()) {
212 activityFlowLinksToDuplicate.sort(ID_COMPARATOR);
213
214 for (ActivityFlowLink original : activityFlowLinksToDuplicate) {
215 duplicateActivityFlowLink(original);
216 }
217 }
218
219 return newProject;
220 } catch (ColabMergeException e) {
221 throw HttpErrorMessage.dataError(MessageI18nKey.DATA_INTEGRITY_FAILURE);
222 }
223
224 }
225
226 private TeamRole duplicateTeamRole(TeamRole original) throws ColabMergeException {
227 TeamRole newTeamRole = new TeamRole();
228 newTeamRole.mergeToDuplicate(original);
229
230 teamRoleMatching.put(original.getId(), newTeamRole);
231
232 return newTeamRole;
233 }
234
235 private TeamMember duplicateTeamMember(TeamMember original) throws ColabMergeException {
236 TeamMember newTeamMember = new TeamMember();
237 newTeamMember.mergeToDuplicate(original);
238
239 teamMemberMatching.put(original.getId(), newTeamMember);
240
241
242
243 User user = original.getUser();
244 if (user != null) {
245 newTeamMember.setUser(user);
246 }
247
248
249
250 if (params.isWithRoles()) {
251 List<TeamRole> linkedRoles = original.getRoles();
252 linkedRoles.sort(ID_COMPARATOR);
253
254 for (TeamRole linkedRole : linkedRoles) {
255 TeamRole newRole = teamRoleMatching.get(linkedRole.getId());
256
257 if (newRole == null) {
258 throw HttpErrorMessage.dataError(MessageI18nKey.DATA_INTEGRITY_FAILURE);
259 }
260
261 newRole.getMembers().add(newTeamMember);
262 newTeamMember.getRoles().add(newRole);
263 }
264 }
265
266 return newTeamMember;
267 }
268
269 private AbstractCardType duplicateCardType(AbstractCardType original)
270 throws ColabMergeException {
271
272 if (params.isMakeOnlyCardTypeReferences()) {
273 CardTypeRef newCardTypeRef = new CardTypeRef();
274 newCardTypeRef.setTarget(original);
275 newCardTypeRef.setDeprecated(original.isDeprecated());
276 newCardTypeRef.setPublished(false);
277
278 cardTypeMatching.put(original.getId(), newCardTypeRef);
279
280 if (resourceSpreader == null) {
281 throw new IllegalStateException(
282 "Dear developer, please define the resource spreader");
283 }
284
285 List<ResourceRef> createdRefs = resourceSpreader
286 .extractReferencesFromUp(newCardTypeRef);
287 createdRefs.stream().forEach(ref -> resourceMatching.put(ref.getTarget().getId(), ref));
288
289 return newCardTypeRef;
290 } else {
291 AbstractCardType newAbstractCardType;
292 if (original instanceof CardType) {
293 CardType originalCardType = (CardType) original;
294
295 CardType newCardType = new CardType();
296 newCardType.mergeToDuplicate(originalCardType);
297
298 cardTypeMatching.put(originalCardType.getId(), newCardType);
299
300 TextDataBlock purpose = originalCardType.getPurpose();
301 if (purpose != null) {
302 TextDataBlock newPurpose = (TextDataBlock) duplicateDocument(purpose);
303 newPurpose.setPurposingCardType(newCardType);
304 newCardType.setPurpose(newPurpose);
305 }
306
307 newAbstractCardType = newCardType;
308 } else if (original instanceof CardTypeRef) {
309 CardTypeRef originalCardTypeRef = (CardTypeRef) original;
310
311 CardTypeRef newCardTypeRef = new CardTypeRef();
312 newCardTypeRef.mergeToDuplicate(originalCardTypeRef);
313
314 cardTypeMatching.put(originalCardTypeRef.getId(), newCardTypeRef);
315
316 AbstractCardType originalTarget = originalCardTypeRef.getTarget();
317 if (originalTarget != null) {
318 if (originalTarget.getProjectId() != originalCardTypeRef.getProjectId()) {
319 newCardTypeRef.setTarget(originalTarget);
320 } else {
321 throw new IllegalStateException(
322 "the target of a card type reference must be outside the project");
323
324
325
326
327 }
328 }
329
330 newAbstractCardType = newCardTypeRef;
331 } else {
332 throw new IllegalStateException("abstract card type implementation not handled");
333 }
334
335 if (params.isWithResources()) {
336 List<AbstractResource> originalResources = original.getDirectAbstractResources();
337 originalResources.sort(ID_COMPARATOR);
338
339 for (AbstractResource originalResource : originalResources) {
340 AbstractResource newResource = duplicateResource(originalResource);
341
342 newResource.setAbstractCardType(newAbstractCardType);
343 newAbstractCardType.getDirectAbstractResources().add(newResource);
344 }
345 } else {
346 logger.info("param do not duplicate project's resources");
347 }
348
349 return newAbstractCardType;
350 }
351 }
352
353 private Card duplicateCard(Card original) throws ColabMergeException {
354 Card newCard = new Card();
355 newCard.mergeToDuplicate(original);
356
357 cardMatching.put(original.getId(), newCard);
358
359 AbstractCardType originalCardType = original.getCardType();
360 if (originalCardType != null) {
361 AbstractCardType newCardType = cardTypeMatching.get(originalCardType.getId());
362
363 if (newCardType == null) {
364 throw HttpErrorMessage.dataError(MessageI18nKey.DATA_INTEGRITY_FAILURE);
365 }
366
367 newCard.setCardType(newCardType);
368 }
369
370 if (params.isWithResources()) {
371 List<AbstractResource> originalResources = original.getDirectAbstractResources();
372 originalResources.sort(ID_COMPARATOR);
373
374 for (AbstractResource originalResource : originalResources) {
375 AbstractResource newResource = duplicateResource(originalResource);
376
377 newResource.setCard(newCard);
378 newCard.getDirectAbstractResources().add(newResource);
379 }
380 } else {
381 logger.info("param do not duplicate project's resources");
382 }
383
384 List<CardContent> originalContents = original.getContentVariants();
385 originalContents.sort(ID_COMPARATOR);
386
387 for (CardContent originalCardContent : originalContents) {
388 CardContent newCardContent = duplicateCardContent(originalCardContent);
389
390 newCardContent.setCard(newCard);
391 newCard.getContentVariants().add(newCardContent);
392 }
393
394
395
396
397 List<Assignment> originalAssignments = original.getAssignments();
398 originalAssignments.sort(ID_COMPARATOR);
399
400 for (Assignment originalAssignment : originalAssignments) {
401 if ((params.isWithTeamMembers() || originalAssignment.getMember() == null)
402 && (params.isWithRoles() || originalAssignment.getRole() == null)) {
403
404 Assignment newAssignment = duplicateAssignment(originalAssignment);
405
406 if (newAssignment != null) {
407 newAssignment.setCard(newCard);
408 newCard.getAssignments().add(newAssignment);
409 }
410 }
411
412 }
413
414
415
416 if (params.isWithStickyNotes()) {
417 stickyNoteLinksToDuplicate.addAll(original.getStickyNoteLinksAsDest());
418 }
419
420
421
422 if (params.isWithActivityFlow()) {
423 activityFlowLinksToDuplicate.addAll(original.getActivityFlowLinksAsPrevious());
424 }
425
426 return newCard;
427 }
428
429 private CardContent duplicateCardContent(CardContent original) throws ColabMergeException {
430 CardContent newCardContent = new CardContent();
431 newCardContent.mergeToDuplicate(original);
432
433 if (params.isResetProgressionData()) {
434 cardContentManager.resetProgression(newCardContent);
435 }
436
437 cardContentMatching.put(original.getId(), newCardContent);
438
439 if (params.isWithDeliverables()) {
440 List<Document> originalDeliverables = original.getDeliverables();
441 originalDeliverables.sort(ID_COMPARATOR);
442
443 for (Document originalDoc : originalDeliverables) {
444 Document newDoc = duplicateDocument(originalDoc);
445
446 newDoc.setOwningCardContent(newCardContent);
447 newCardContent.getDeliverables().add(newDoc);
448 }
449 } else {
450 logger.info("param do not duplicate project's deliverables");
451 }
452
453 if (params.isWithResources()) {
454 List<AbstractResource> originalResources = original.getDirectAbstractResources();
455 originalResources.sort(ID_COMPARATOR);
456
457 for (AbstractResource originalResource : originalResources) {
458 AbstractResource newResource = duplicateResource(originalResource);
459
460 newResource.setCardContent(newCardContent);
461 newCardContent.getDirectAbstractResources().add(newResource);
462 }
463 } else {
464 logger.info("param do not duplicate project's resources");
465 }
466
467 List<Card> originalSubCards = original.getSubCards();
468 originalSubCards.sort(ID_COMPARATOR);
469
470 for (Card originalSubCard : originalSubCards) {
471 Card newSubCard = duplicateCard(originalSubCard);
472
473 newSubCard.setParent(newCardContent);
474 newCardContent.getSubCards().add(newSubCard);
475 }
476
477 return newCardContent;
478 }
479
480 private Document duplicateDocument(Document original) throws ColabMergeException {
481 if (original instanceof DocumentFile) {
482 DocumentFile originalDocumentFile = (DocumentFile) original;
483
484 DocumentFile newDocumentFile = duplicateDocumentFile(originalDocumentFile);
485
486 documentMatching.put(originalDocumentFile.getId(), newDocumentFile);
487
488 return newDocumentFile;
489 } else if (original instanceof ExternalLink) {
490 ExternalLink originalExternalLink = (ExternalLink) original;
491
492 ExternalLink newExternalLink = new ExternalLink();
493 newExternalLink.mergeToDuplicate(originalExternalLink);
494
495 documentMatching.put(originalExternalLink.getId(), newExternalLink);
496
497 return newExternalLink;
498 } else if (original instanceof TextDataBlock) {
499 TextDataBlock originalTextDataBlock = (TextDataBlock) original;
500
501 TextDataBlock newTextDataBlock = new TextDataBlock();
502 newTextDataBlock.mergeToDuplicate(originalTextDataBlock);
503
504 documentMatching.put(originalTextDataBlock.getId(), newTextDataBlock);
505
506 return newTextDataBlock;
507 } else {
508 throw new IllegalStateException("abstract card type implementation not handled");
509 }
510 }
511
512 private DocumentFile duplicateDocumentFile(DocumentFile original) throws ColabMergeException {
513 DocumentFile newDocumentFile = new DocumentFile();
514 newDocumentFile.mergeToDuplicate(original);
515
516 documentFilesToProcessOnceIds.put(original.getId(), newDocumentFile);
517
518 return newDocumentFile;
519 }
520
521
522
523
524
525
526
527
528
529
530 public AbstractResource duplicateResource(AbstractResource original)
531 throws ColabMergeException {
532 if (original instanceof Resource) {
533 Resource originalResource = (Resource) original;
534
535 Resource newResource = new Resource();
536 newResource.mergeToDuplicate(originalResource);
537
538 resourceMatching.put(originalResource.getId(), newResource);
539
540 List<Document> originalDocuments = originalResource.getDocuments();
541 originalDocuments.sort(ID_COMPARATOR);
542
543 for (Document originalDocument : originalDocuments) {
544 Document newDocument = duplicateDocument(originalDocument);
545
546 newDocument.setOwningResource(newResource);
547 newResource.getDocuments().add(newDocument);
548 }
549
550 TextDataBlock teaser = originalResource.getTeaser();
551 if (teaser != null) {
552 TextDataBlock newTeaser = (TextDataBlock) duplicateDocument(teaser);
553
554 newTeaser.setTeasingResource(newResource);
555 newResource.setTeaser(newTeaser);
556 }
557
558 return newResource;
559 } else if (original instanceof ResourceRef) {
560 ResourceRef originalResourceRef = (ResourceRef) original;
561
562 ResourceRef newResourceRef = new ResourceRef();
563 newResourceRef.mergeToDuplicate(originalResourceRef);
564
565 resourceMatching.put(originalResourceRef.getId(), newResourceRef);
566
567 AbstractResource originalTarget = originalResourceRef.getTarget();
568 if (originalTarget != null) {
569 AbstractResource newTarget;
570 if (resourceMatching.containsKey(originalTarget.getId())) {
571 newTarget = resourceMatching.get(originalTarget.getId());
572 } else {
573 newTarget = originalTarget;
574 }
575 newResourceRef.setTarget(newTarget);
576 }
577
578 return newResourceRef;
579
580 } else {
581 throw new IllegalStateException("abstract card type implementation not handled");
582 }
583 }
584
585 private Assignment duplicateAssignment(Assignment original)
586 throws ColabMergeException {
587 Assignment newAssignment = new Assignment();
588 newAssignment.mergeToDuplicate(original);
589
590 if (original.getMember() != null) {
591 TeamMember member = teamMemberMatching.get(original.getMember().getId());
592
593 if (member == null) {
594 throw HttpErrorMessage.dataError(MessageI18nKey.DATA_INTEGRITY_FAILURE);
595 }
596
597 member.getAssignments().add(newAssignment);
598 newAssignment.setMember(member);
599 }
600
601 if (original.getRole() != null) {
602 TeamRole role = teamRoleMatching.get(original.getRole().getId());
603
604 if (role == null) {
605 throw HttpErrorMessage.dataError(MessageI18nKey.DATA_INTEGRITY_FAILURE);
606 }
607
608 role.getAssignments().add(newAssignment);
609 newAssignment.setRole(role);
610 }
611
612 return newAssignment;
613 }
614
615 private StickyNoteLink duplicateStickyNoteLink(StickyNoteLink original)
616 throws ColabMergeException {
617 StickyNoteLink newLink = new StickyNoteLink();
618 newLink.mergeToDuplicate(original);
619
620 TextDataBlock explanation = original.getExplanation();
621 if (explanation != null) {
622 TextDataBlock newExplanation = (TextDataBlock) duplicateDocument(explanation);
623 newExplanation.setExplainingStickyNoteLink(newLink);
624 newLink.setExplanation(newExplanation);
625 }
626
627 if (original.getDestinationCard() != null) {
628 Card destinationCard = cardMatching.get(original.getDestinationCard().getId());
629
630 if (destinationCard == null) {
631 throw HttpErrorMessage.dataError(MessageI18nKey.DATA_INTEGRITY_FAILURE);
632 }
633
634 destinationCard.getStickyNoteLinksAsDest().add(newLink);
635 newLink.setDestinationCard(destinationCard);
636 }
637
638 if (original.getSrcCard() != null) {
639 Card srcCard = cardMatching.get(original.getSrcCard().getId());
640
641 if (srcCard == null) {
642 throw HttpErrorMessage.dataError(MessageI18nKey.DATA_INTEGRITY_FAILURE);
643 }
644
645 srcCard.getStickyNoteLinksAsSrc().add(newLink);
646 newLink.setSrcCard(srcCard);
647 }
648
649 if (original.getSrcCardContent() != null) {
650 CardContent srcCardContent = cardContentMatching
651 .get(original.getSrcCardContent().getId());
652
653 if (srcCardContent == null) {
654 throw HttpErrorMessage.dataError(MessageI18nKey.DATA_INTEGRITY_FAILURE);
655 }
656
657 srcCardContent.getStickyNoteLinksAsSrc().add(newLink);
658 newLink.setSrcCardContent(srcCardContent);
659 }
660
661 if (original.getSrcResourceOrRef() != null) {
662 AbstractResource srcResourceOrRef = resourceMatching
663 .get(original.getSrcResourceOrRef().getId());
664
665 if (srcResourceOrRef == null) {
666 throw HttpErrorMessage.dataError(MessageI18nKey.DATA_INTEGRITY_FAILURE);
667 }
668
669 srcResourceOrRef.getStickyNoteLinksAsSrc().add(newLink);
670 newLink.setSrcResourceOrRef(srcResourceOrRef);
671 }
672
673 if (original.getSrcDocument() != null) {
674 Document srcDocument = documentMatching.get(original.getSrcDocument().getId());
675
676 if (srcDocument == null) {
677 throw HttpErrorMessage.dataError(MessageI18nKey.DATA_INTEGRITY_FAILURE);
678 }
679
680 srcDocument.getStickyNoteLinksAsSrc().add(newLink);
681 newLink.setSrcDocument(srcDocument);
682 }
683
684 return newLink;
685 }
686
687 private ActivityFlowLink duplicateActivityFlowLink(ActivityFlowLink original)
688 throws ColabMergeException {
689 ActivityFlowLink newLink = new ActivityFlowLink();
690 newLink.mergeToDuplicate(newLink);
691
692 if (original.getPreviousCard() != null) {
693 Card previousCard = cardMatching.get(original.getPreviousCard().getId());
694
695 if (previousCard == null) {
696 throw HttpErrorMessage.dataError(MessageI18nKey.DATA_INTEGRITY_FAILURE);
697 }
698
699 previousCard.getActivityFlowLinksAsPrevious().add(newLink);
700 newLink.setPreviousCard(previousCard);
701 }
702
703 if (original.getNextCard() != null) {
704 Card nextCard = cardMatching.get(original.getNextCard().getId());
705
706 if (nextCard == null) {
707 throw HttpErrorMessage.dataError(MessageI18nKey.DATA_INTEGRITY_FAILURE);
708 }
709
710 nextCard.getActivityFlowLinksAsNext().add(newLink);
711 newLink.setNextCard(nextCard);
712 }
713
714 return newLink;
715 }
716
717
718
719
720
721
722 public void duplicateDataIntoJCR() {
723 try {
724 for (Entry<Long, DocumentFile> data : documentFilesToProcessOnceIds.entrySet()) {
725 duplicateFileDocumentIntoJCR(data.getKey(), data.getValue());
726 }
727 } catch (RepositoryException e) {
728 throw HttpErrorMessage.duplicationError();
729 }
730 }
731
732
733
734
735
736
737 public void duplicateLexicalData() {
738 if (params.isWithDeliverables()) {
739 for (Entry<Long, CardContent> data : cardContentMatching.entrySet()) {
740
741 callDuplicateYjsService(data.getKey(), LexicalDataOwnershipKind.CARD_CONTENT,
742 data.getValue().getId(), LexicalDataOwnershipKind.CARD_CONTENT);
743 }
744 }
745
746 if (params.isWithResources()) {
747 for (Entry<Long, AbstractResource> data : resourceMatching.entrySet()) {
748 if (data.getValue() instanceof Resource) {
749 callDuplicateYjsService(data.getKey(), LexicalDataOwnershipKind.RESOURCE,
750 data.getValue().getId(), LexicalDataOwnershipKind.RESOURCE);
751 }
752 }
753 }
754 }
755
756
757
758
759
760
761
762
763
764 private void callDuplicateYjsService(Long srcOwnerId, LexicalDataOwnershipKind srcOwnerKind,
765 Long destOwnerId, LexicalDataOwnershipKind destOwnerKind) {
766 try {
767
768
769 yjsLexicalCaller = new YjsLexicalCaller();
770
771 yjsLexicalCaller.sendDuplicationRequest(
772 srcOwnerId, srcOwnerKind, destOwnerId, destOwnerKind);
773 } catch (YjsException e) {
774 throw HttpErrorMessage.duplicationError();
775 }
776 }
777
778
779
780
781
782
783
784 private void duplicateFileDocumentIntoJCR(Long srcDocId, DocumentFile newDocFile)
785 throws RepositoryException {
786 if (fileManager == null) {
787 throw new IllegalStateException("Dear developer, you must have defined a file manager");
788 }
789
790 if (fileManager.hasFile(srcDocId)) {
791 InputStream fileStream = null;
792 try {
793 fileStream = fileManager.getFileStream(srcDocId);
794 fileManager.updateOrCreateFile(newDocFile.getId(), fileStream);
795 } finally {
796 if (fileStream != null) {
797 try {
798 fileStream.close();
799 } catch (IOException e) {
800
801
802 logger.warn("Could not close stream", e);
803 }
804 }
805 }
806 }
807 }
808
809
810
811
812 public void clear() {
813 teamRoleMatching.clear();
814 teamMemberMatching.clear();
815 cardTypeMatching.clear();
816 cardMatching.clear();
817 cardContentMatching.clear();
818 resourceMatching.clear();
819 documentMatching.clear();
820 stickyNoteLinksToDuplicate.clear();
821 activityFlowLinksToDuplicate.clear();
822 documentFilesToProcessOnceIds.clear();
823 }
824
825 }