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 @@ -154,17 +154,29 @@ private NetworkModificationNode duplicateNode(@NonNull StudyEntity study, @NonNu

NetworkModificationNodeInfoEntity newNodeInfoEntity = networkModificationNodeInfoRepository.getReferenceById(newNode.getId());
NetworkModificationNodeInfoEntity originNodeInfoEntity = networkModificationNodeInfoRepository.getReferenceById(originNodeUuid);
if (!isDuplicatingStudy && study.getId() != sourceStudy.getId()) {
rootNetworkNodeInfoService.createNodeLinks(study, newNodeInfoEntity);
} 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));

Map<String, RootNetworkEntity> targetRootNetworksByTag = study.getRootNetworks().stream()
.collect(Collectors.toMap(RootNetworkEntity::getTag, rn -> rn));

Map<RootNetworkEntity, RootNetworkEntity> originToDuplicateRootNetworkMap = new HashMap<>();
for (RootNetworkEntity sourceRN : sourceStudy.getRootNetworks()) {
RootNetworkEntity targetRN = targetRootNetworksByTag.get(sourceRN.getTag());
if (targetRN != null) {
originToDuplicateRootNetworkMap.put(sourceRN, targetRN);
}
}

// Link node to root networks
if (!isDuplicatingStudy && !Objects.equals(study.getId(), sourceStudy.getId())) {
// Node duplication between studies
rootNetworkNodeInfoService.createNodeLinksWithCommonTag(
newNodeInfoEntity,
originNodeInfoEntity,
originToDuplicateModificationUuidMap,
targetRootNetworksByTag
);
} else {
// Node duplication within the same study (or full study duplication)
rootNetworkNodeInfoService.duplicateNodeLinks(originNodeInfoEntity.getRootNetworkNodeInfos(), newNodeInfoEntity, originToDuplicateModificationUuidMap, originToDuplicateRootNetworkMap);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,52 @@ 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();
}

// create links for root networks with common tags
public void createNodeLinksWithCommonTag(
@NonNull NetworkModificationNodeInfoEntity targetNodeInfoEntity,
@NonNull NetworkModificationNodeInfoEntity sourceNodeInfoEntity,
@NonNull Map<UUID, UUID> originToDuplicateModificationUuidMap,
@NonNull Map<String, RootNetworkEntity> targetRootNetworksByTag) {

// Map source node links by root network tag
Map<String, RootNetworkNodeInfoEntity> sourceNodeLinksByTag = sourceNodeInfoEntity.getRootNetworkNodeInfos().stream()
.filter(rn -> rn.getRootNetwork().getTag() != null)
.collect(Collectors.toMap(rn -> rn.getRootNetwork().getTag(), rn -> rn));

targetRootNetworksByTag.forEach((tag, targetRN) -> {
RootNetworkNodeInfoEntity sourceNodeLink = sourceNodeLinksByTag.get(tag);
Set<UUID> modificationsToExclude = Collections.emptySet();

if (sourceNodeLink != null) {
// Map modifications to the duplicated UUIDs
modificationsToExclude = sourceNodeLink.getModificationsUuidsToExclude().stream()
.map(originToDuplicateModificationUuidMap::get)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
}

// Create a new RootNetworkNodeInfoEntity for the target
RootNetworkNodeInfoEntity newRNNodeInfo = createDefaultEntity(targetNodeInfoEntity.getId(), modificationsToExclude);

addLink(targetNodeInfoEntity, targetRN, newRNNodeInfo);
});
}

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 Down Expand Up @@ -519,6 +565,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 @@ -2491,13 +2491,14 @@ public void duplicateOrInsertNetworkModifications(UUID targetStudyUuid, UUID tar
.toList();

NetworkModificationsResult networkModificationResults = networkModificationService.duplicateOrInsertModifications(groupUuid, action, Pair.of(modificationsUuis, modificationApplicationContexts));

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

if (networkModificationResults != null) {
Expand Down
Loading