Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -148,22 +148,18 @@ public NetworkModificationNode createNode(@NonNull StudyEntity study, @NonNull U
return newNode;
}

private NetworkModificationNode duplicateNode(@NonNull StudyEntity study, @NonNull StudyEntity sourceStudy, @NonNull UUID referenceNodeId, @NonNull NetworkModificationNode newNodeInfo, @NonNull UUID originNodeUuid, @NonNull InsertMode insertMode, Map<UUID, UUID> originToDuplicateModificationUuidMap, boolean isDuplicatingStudy) {
private NetworkModificationNode duplicateNode(@NonNull StudyEntity targetStudy, @NonNull StudyEntity sourceStudy, @NonNull UUID referenceNodeId, @NonNull NetworkModificationNode newNodeInfo, @NonNull UUID originNodeUuid, @NonNull InsertMode insertMode, Map<UUID, UUID> originToDuplicateModificationUuidMap, boolean isDuplicatingStudy) {
// create new node
NetworkModificationNode newNode = createAndInsertNode(study, referenceNodeId, newNodeInfo, insertMode, null);
NetworkModificationNode newNode = createAndInsertNode(targetStudy, referenceNodeId, newNodeInfo, insertMode, null);

NetworkModificationNodeInfoEntity newNodeInfoEntity = networkModificationNodeInfoRepository.getReferenceById(newNode.getId());
NetworkModificationNodeInfoEntity originNodeInfoEntity = networkModificationNodeInfoRepository.getReferenceById(originNodeUuid);
if (!isDuplicatingStudy && study.getId() != sourceStudy.getId()) {
rootNetworkNodeInfoService.createNodeLinks(study, newNodeInfoEntity);
if (!isDuplicatingStudy && targetStudy.getId() != sourceStudy.getId()) {
rootNetworkNodeInfoService.createNodeLinksFromSourceForCommonTags(targetStudy, originNodeInfoEntity.getRootNetworkNodeInfos(), newNodeInfoEntity, originToDuplicateModificationUuidMap);
} else {
// when duplicating node within the same study, we need to retrieve excluded modifications from source node
// when duplicating study, we need to retrieve excluded modifications from source node as well, but we also need to have a correspondence between source root networks and duplicated ones
// since they are fetched in order, we ensure the duplicate is made accurately
Map<RootNetworkEntity, RootNetworkEntity> originToDuplicateRootNetworkMap = new HashMap<>();
for (int i = 0; i < sourceStudy.getRootNetworks().size(); i++) {
// when study.getId() == sourceStudy.getId(), this mapping makes root networks target themselves, but it makes the code more concise with study duplication
originToDuplicateRootNetworkMap.put(sourceStudy.getRootNetworks().get(i), study.getRootNetworks().get(i));
originToDuplicateRootNetworkMap.put(sourceStudy.getRootNetworks().get(i), targetStudy.getRootNetworks().get(i));
}
rootNetworkNodeInfoService.duplicateNodeLinks(originNodeInfoEntity.getRootNetworkNodeInfos(), newNodeInfoEntity, originToDuplicateModificationUuidMap, originToDuplicateRootNetworkMap);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,21 @@ public void createNodeLinks(@NonNull StudyEntity studyEntity, @NonNull NetworkMo
});
}

// get the root networks that are common between source and destination studies
private List<RootNetworkEntity> getCommonRootNetworks(@NonNull UUID sourceStudyUuid, @NonNull UUID destinationStudyUuid) {
Set<String> sourceTags = rootNetworkNodeInfoRepository
.findAllByRootNetworkStudyId(sourceStudyUuid).stream()
.map(RootNetworkNodeInfoEntity::getRootNetwork)
.map(RootNetworkEntity::getTag)
.collect(Collectors.toSet());

return rootNetworkNodeInfoRepository
.findAllByRootNetworkStudyId(destinationStudyUuid).stream()
.map(RootNetworkNodeInfoEntity::getRootNetwork)
.filter(rn -> rn.getTag() != null && sourceTags.contains(rn.getTag()))
.toList();
}

public void duplicateNodeLinks(List<RootNetworkNodeInfoEntity> sourceNodeLinks, @NonNull NetworkModificationNodeInfoEntity destinationNodeInfoEntity, Map<UUID, UUID> originToDuplicateModificationUuidMap, Map<RootNetworkEntity, RootNetworkEntity> originToDuplicateRootNetworkMap) {
// For each root network create a link with the node
sourceNodeLinks.forEach(nodeLink -> {
Expand All @@ -130,6 +145,35 @@ public void duplicateNodeLinks(List<RootNetworkNodeInfoEntity> sourceNodeLinks,
});
}

public void createNodeLinksFromSourceForCommonTags(@NonNull StudyEntity destinationStudy, @NonNull List<RootNetworkNodeInfoEntity> sourceNodeLinks, @NonNull NetworkModificationNodeInfoEntity destinationNodeInfoEntity, @NonNull Map<UUID, UUID> originToDuplicateModificationUuidMap) {
// Map tag → link source
Map<String, RootNetworkNodeInfoEntity> sourceLinkByTag =
sourceNodeLinks.stream()
.filter(l -> l.getRootNetwork().getTag() != null)
.collect(Collectors.toMap(
l -> l.getRootNetwork().getTag(),
Function.identity(),
(a, b) -> a
));

destinationStudy.getRootNetworks().forEach(destRoot -> {
String tag = destRoot.getTag();
// copy exclusions only for common root networks tag
Set<UUID> exclusions;
if (tag != null && sourceLinkByTag.containsKey(tag)) {
exclusions = sourceLinkByTag.get(tag).getModificationsUuidsToExclude()
.stream()
.map(originToDuplicateModificationUuidMap::get)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
} else {
exclusions = Collections.emptySet();
}
RootNetworkNodeInfoEntity entity = createDefaultEntity(destinationNodeInfoEntity.getId(), exclusions);
addLink(destinationNodeInfoEntity, destRoot, entity);
});
}

private static RootNetworkNodeInfoEntity createDefaultEntity(UUID nodeUuid) {
return createDefaultEntity(nodeUuid, new HashSet<>());
}
Expand Down Expand Up @@ -534,6 +578,39 @@ public void copyModificationsToExclude(UUID originNodeUuid, UUID targetNodeUuid,
}));
}

/**
* Copies modification applicability (via exclusions) from origin study to target study
* according to root network tags
*/
public void copyModificationsToExcludeByCommonRootNetworkTag(
UUID originStudyUuid, UUID targetStudyUuid, UUID originNodeUuid, UUID targetNodeUuid, Map<UUID, UUID> originToDuplicateModificationsUuids) {
List<RootNetworkEntity> targetRootNetworksWithCommonTags = getCommonRootNetworks(originStudyUuid, targetStudyUuid);

Map<String, RootNetworkEntity> targetRootByTag = targetRootNetworksWithCommonTags.stream()
.filter(rn -> rn.getTag() != null)
.collect(Collectors.toMap(RootNetworkEntity::getTag, Function.identity(), (a, b) -> a));

rootNetworkNodeInfoRepository.findAllByNodeInfoId(originNodeUuid).forEach(originNodeInfo -> {
RootNetworkEntity targetRoot = targetRootByTag.get(originNodeInfo.getRootNetwork().getTag());
if (targetRoot == null) {
return;
}

getRootNetworkNodeInfo(targetNodeUuid, targetRoot.getId())
.ifPresent(targetNodeInfo -> {
// Collect mapped exclusions into a Set
Set<UUID> duplicatedExcludedModifications = originNodeInfo.getModificationsUuidsToExclude().stream()
.map(originToDuplicateModificationsUuids::get)
.filter(Objects::nonNull)
.collect(Collectors.toSet());

if (!duplicatedExcludedModifications.isEmpty()) {
targetNodeInfo.addModificationsToExclude(duplicatedExcludedModifications);
}
});
});
}

@Transactional
public void updateRootNetworkNode(UUID nodeUuid, UUID rootNetworkUuid, RootNetworkNodeInfo rootNetworkNodeInfo) {
RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity = rootNetworkNodeInfoRepository.findByNodeInfoIdAndRootNetworkId(nodeUuid, rootNetworkUuid).orElseThrow(() -> new StudyException(NOT_FOUND, "Root network not found"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2547,15 +2547,16 @@ public void duplicateOrInsertNetworkModifications(
.toList();

NetworkModificationsResult networkModificationResults = networkModificationService.duplicateOrInsertModifications(groupUuid, action, Pair.of(modifications, modificationApplicationContexts));
Map<UUID, UUID> originToDuplicateModificationsUuids = new HashMap<>();
for (int i = 0; i < modifications.size(); i++) {
originToDuplicateModificationsUuids.put(modifications.get(i).getUuid(), networkModificationResults.modificationUuids().get(i));
}

if (targetStudyUuid.equals(originStudyUuid)) {
Map<UUID, UUID> originToDuplicateModificationsUuids = new HashMap<>();
for (int i = 0; i < modifications.size(); i++) {
originToDuplicateModificationsUuids.put(modifications.get(i).getUuid(), networkModificationResults.modificationUuids().get(i));
}
rootNetworkNodeInfoService.copyModificationsToExclude(originNodeUuid, targetNodeUuid, originToDuplicateModificationsUuids);
} else {
rootNetworkNodeInfoService.copyModificationsToExcludeByCommonRootNetworkTag(originStudyUuid, targetStudyUuid, originNodeUuid, targetNodeUuid, originToDuplicateModificationsUuids);
}

if (networkModificationResults != null) {
int index = 0;
// for each NetworkModificationResult, send an impact notification - studyRootNetworkEntities are ordered in the same way as networkModificationResults
Expand Down
Loading