Newer
Older
Nicola Fulvio Calabria
committed
/*
* This file is part of vospace-rest
* Copyright (C) 2021 Istituto Nazionale di Astrofisica
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package it.inaf.oats.vospace;
import it.inaf.oats.vospace.datamodel.NodeUtils;
import it.inaf.oats.vospace.exception.InternalFaultException;
import it.inaf.oats.vospace.parent.exchange.ArchiveEntryDescriptor;
Nicola Fulvio Calabria
committed
import it.inaf.oats.vospace.persistence.NodeDAO;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import net.ivoa.xml.vospace.v2.LinkNode;
import net.ivoa.xml.vospace.v2.Node;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@Service
public class LinkService {
@Value("${vospace-authority}")
private String authority;
@Value("${link-max-depth}")
private int linkMaxDepth;
@Autowired
private NodeDAO nodeDao;
// Returns a new list = the list in argument with paths of links to links are substituted with
// their actual destination vos path. Only links to external resources
// (http:// ... ) should remain
public List<ArchiveEntryDescriptor> followLinksForArchiveService(List<String> vosPaths) {
Nicola Fulvio Calabria
committed
List<LinkNode> linkNodesInPaths = nodeDao.returnLinkNodesInList(vosPaths);
// No links no change
if(linkNodesInPaths.isEmpty())
return vosPaths.stream().map(p -> new ArchiveEntryDescriptor(p))
.collect(Collectors.toList());
Nicola Fulvio Calabria
committed
List<String> linkVosPaths = linkNodesInPaths.stream()
.map(ln -> NodeUtils.getVosPath(ln)).collect(Collectors.toList());
// Safe copy of argument
List<String> resultVosPaths = new ArrayList<>(vosPaths);
resultVosPaths.removeAll(linkVosPaths);
// Generate descriptors from non link vospaths
List<ArchiveEntryDescriptor> resultDescriptors =
resultVosPaths.stream().map(p -> new ArchiveEntryDescriptor(p))
.collect(Collectors.toList());
Nicola Fulvio Calabria
committed
// Add descriptors from links
resultDescriptors.addAll(
linkNodesInPaths.stream().map(p -> getLinkNodeArchiveEntryDescriptor(p))
.collect(Collectors.toList())
);
Nicola Fulvio Calabria
committed
return resultDescriptors;
}
private ArchiveEntryDescriptor getLinkNodeArchiveEntryDescriptor(LinkNode node){
String vosPath = NodeUtils.getVosPath(node);
String targetNodeVosPath = NodeUtils.getVosPath(this.followLink(node));
return new ArchiveEntryDescriptor(vosPath, targetNodeVosPath);
Nicola Fulvio Calabria
committed
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
}
public Node followLink(LinkNode linkNode) {
return this.followLinkRecursive(linkNode, 0);
}
private Node followLinkRecursive(LinkNode linkNode, int depth) {
if (depth >= linkMaxDepth) {
throw new InternalFaultException("Max link depth reached at link node: "
+ NodeUtils.getVosPath(linkNode));
}
String linkTarget = linkNode.getTarget();
if (URIUtils.isURIInternal(linkTarget)) {
String targetPath = URIUtils.returnVosPathFromNodeURI(linkTarget, authority);
Optional<Node> targetNodeOpt = nodeDao.listNode(targetPath);
Node targetNode = targetNodeOpt.orElseThrow(() -> new InternalFaultException("Broken Link to target: " + targetPath));
if (targetNode instanceof LinkNode) {
return this.followLinkRecursive(linkNode, ++depth);
} else {
return targetNode;
}
} else {
return linkNode;
}
}
}