package edu.asu.spring.quadriga.service.network.impl; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import edu.asu.spring.quadriga.domain.network.INetwork; import edu.asu.spring.quadriga.domain.network.INetworkNodeInfo; import edu.asu.spring.quadriga.exceptions.QuadrigaStorageException; import edu.asu.spring.quadriga.service.network.INetworkManager; import edu.asu.spring.quadriga.service.network.INetworkTransformationManager; import edu.asu.spring.quadriga.service.network.domain.ITransformedNetwork; import edu.asu.spring.quadriga.service.network.domain.impl.TransformedNetwork; import edu.asu.spring.quadriga.transform.Link; import edu.asu.spring.quadriga.transform.Node; import edu.asu.spring.quadriga.transform.PredicateNode; @Service public class NetworkTransformationManager implements INetworkTransformationManager { @Autowired private INetworkManager networkManager; @Autowired private NetworkTransformer transformer; @Override public ITransformedNetwork getTransformedNetwork(String networkId, String versionID) throws QuadrigaStorageException { List<INetworkNodeInfo> oldNetworkTopNodesList = networkManager.getNetworkTopNodesByVersion(networkId, Integer.parseInt(versionID)); return transformer.transformNetwork(oldNetworkTopNodesList); } @Override public ITransformedNetwork getTransformedNetwork(String networkId) throws QuadrigaStorageException { List<INetworkNodeInfo> networkTopNodesList = networkManager.getNetworkTopNodes(networkId); return transformer.transformNetwork(networkTopNodesList); } @Override public ITransformedNetwork getTransformedApprovedNetworks(List<INetwork> networkList) throws QuadrigaStorageException { List<INetworkNodeInfo> networkTopNodesList = new ArrayList<INetworkNodeInfo>(); for (INetwork curnetwork : networkList) { List<INetworkNodeInfo> curTopNodesList = networkManager.getNetworkTopNodes(curnetwork.getNetworkId()); networkTopNodesList.addAll(curTopNodesList); } return transformer.transformNetwork(networkTopNodesList); } @Override public ITransformedNetwork getTransformedNetworkOfProject(String projectId, String status) throws QuadrigaStorageException { List<INetwork> networkList = getNetworkList(projectId, status); if (networkList == null) { return null; } return getTransformedNetworkusingNetworkList(networkList); } /** * This method returns a network that consists of all the statements in the * given projects that contain the provided concept id. * * @param projectIds * @param conceptId * @return ITransformedNetwork * @throws QuadrigaStorageException * @author suraj nilapwar */ @Override public ITransformedNetwork getSearchTransformedNetwork(String projectId, String conceptId, String status) throws QuadrigaStorageException { // get the transformed network and search for the concept id List<INetwork> networkList = getNetworkList(projectId, status); if (networkList == null) { return null; } // get the transformed network of all the networks in a project ITransformedNetwork transformedNetwork = getTransformedNetworkusingNetworkList(networkList); // create finalnetwork using conceptId return getFinalTransformedNetwork(transformedNetwork, conceptId); } private List<INetwork> getNetworkList(String projectId, String status) throws QuadrigaStorageException { return networkManager.getNetworksInProject(projectId, status); } /** * This method searches for concept specified by conceptId in the networks * of projects specified by project Ids and returns transformed networks of * all projects specified by projectIds containing given conceptId. * * @param projectIds * : List of projectIds for projects to search under * @param conceptId * : Id of concept to search * @return ITransformedNetwork * @throws QuadrigaStorageException * @author suraj nilapwar */ @Override public ITransformedNetwork getSearchTransformedNetworkMultipleProjects(List<String> projectIds, String conceptId, String status) throws QuadrigaStorageException { // get the transformed network and search for the concept id List<INetwork> networkList = new ArrayList<>(); for (String projectId : projectIds) { List<INetwork> networks = getNetworkList(projectId, status); if (networks != null) { networkList.addAll(networks); } } if (networkList.size() == 0) { return null; } // get the transformed network of all the networks in projects ITransformedNetwork transformedNetwork = getTransformedNetworkusingNetworkList(networkList); // create finalnetwork using conceptId return getFinalTransformedNetwork(transformedNetwork, conceptId); } @Override public ITransformedNetwork getTransformedNetworkusingNetworkList(List<INetwork> networkList) throws QuadrigaStorageException { List<INetworkNodeInfo> networkNodeInfoList = new ArrayList<INetworkNodeInfo>(); for (INetwork network : networkList) { List<INetworkNodeInfo> localNetworkNodeInfoList = networkManager.getNetworkTopNodes(network.getNetworkId()); if (localNetworkNodeInfoList != null) { networkNodeInfoList.addAll(localNetworkNodeInfoList); } } ITransformedNetwork transformedNetwork = transformer.transformNetwork(networkNodeInfoList); // combine all the nodes except predicate nodes Map<String, Node> nodes = transformedNetwork.getNodes(); List<Link> links = transformedNetwork.getLinks(); Map<String, Node> updatedNodes = new HashMap<String, Node>(); for (Map.Entry<String, Node> entry : nodes.entrySet()) { Node node = entry.getValue(); // if the node is predicate node // add to the updated nodes map if (node instanceof PredicateNode) { // used the original key to store the // predicate node updatedNodes.put(entry.getKey(), node); continue; } // node is subject or object // If the concept id is already present in the // updated nodes map - dont add it if (!updatedNodes.containsKey(node.getConceptId())) { updatedNodes.put(node.getConceptId(), node); } } // update the links to point to the new updatedNodes for (Link link : links) { Node subjectNode = link.getSubject(); if (!(subjectNode instanceof PredicateNode)) { link.setSubject(updatedNodes.get(subjectNode.getConceptId())); } Node objectNode = link.getObject(); if (!(objectNode instanceof PredicateNode)) { link.setObject(updatedNodes.get(objectNode.getConceptId())); } } // return new network with updated nodes and links return new TransformedNetwork(updatedNodes, links); } private ITransformedNetwork getFinalTransformedNetwork(ITransformedNetwork transformedNetwork, String conceptId) { // Filter the nodes with the concept id // add all the statement ids to a set Set<String> statementIdSearchSet = new HashSet<String>(); List<Node> searchedNodes = new ArrayList<Node>(); for (Node node : transformedNetwork.getNodes().values()) { if (conceptId.equals(node.getConceptId())) { searchedNodes.add(node); statementIdSearchSet.addAll(node.getStatementIds()); } } // include only those links which have statement ids in the search set List<Link> finalLinks = new ArrayList<Link>(); // final nodes Map<String, Node> finalNodes = new HashMap<String, Node>(); // To store already added nodes to the final nodes map // this would avoid duplicate nodes Set<Node> addedNodes = new HashSet<Node>(); for (Link link : transformedNetwork.getLinks()) { if (statementIdSearchSet.contains(link.getStatementId())) { // statement id match // add to the final link list finalLinks.add(link); Node subjectNode = link.getSubject(); Node objectNode = link.getObject(); // if node already added then do not add it // if nodes are added twice - it would produce many // nodes and less links => disconnected graph if (!addedNodes.contains(subjectNode)) { finalNodes.put(subjectNode.getId(), subjectNode); addedNodes.add(subjectNode); } if (!addedNodes.contains(objectNode)) { finalNodes.put(objectNode.getId(), objectNode); addedNodes.add(objectNode); } } } // finally add the searched concept nodes if they are not present for (Node node : searchedNodes) { if (!searchedNodes.contains(node)) { finalNodes.put(node.getId(), node); } } return new TransformedNetwork(finalNodes, finalLinks); } }