001package org.biopax.paxtools.query.algorithm;
002
003import org.biopax.paxtools.query.model.GraphObject;
004import org.biopax.paxtools.query.model.Node;
005
006import java.util.HashSet;
007import java.util.Map;
008import java.util.Set;
009
010/**
011 * Searches the neighborhood of given source set of nodes
012 * 
013 * @author Shatlyk Ashyralyev
014 */
015public class NeighborhoodQuery
016{
017        /**
018         * Set of source nodes.
019         */
020        private Set<Node> sourceNodes;
021        
022        /**
023         * Booleans to determine the directin of search.
024         */
025        private Direction direction;
026
027        /**
028         * Stop distance.
029         */
030        private int limit;
031
032        /**
033         * Constructor with parameters.
034         * @param sourceNodes Seed to the query
035         * @param direction Direction of the search
036         * @param limit Distance limit
037         */
038        public NeighborhoodQuery(Set<Node> sourceNodes, Direction direction, int limit)
039        {
040                if (direction == Direction.UNDIRECTED)
041                        throw new IllegalArgumentException("Direction cannot be undirected, " +
042                                "use BOTHSTREAM instead");
043
044                this.sourceNodes = sourceNodes;
045                this.direction = direction;
046                this.limit = limit;
047        }
048
049        /**
050         * Executes the query.
051         * @return Neighborhood
052         */
053        public Set<GraphObject> run()
054        {
055                // result set of neighborhood query
056                Set<GraphObject> queryResult = new HashSet<GraphObject>();
057
058                // if upstream is selected
059                if (direction == Direction.UPSTREAM || direction == Direction.BOTHSTREAM)
060                {
061                        // run BFS in upstream direction
062                        BFS bfsBackward = new BFS(sourceNodes, null, Direction.UPSTREAM, this.limit);
063
064                        /*
065          Maps to hold forward and backward BFS results
066         */
067                        Map<GraphObject, Integer> mapBackward = bfsBackward.run();
068
069                        // add result of BFS to result Set
070                        queryResult.addAll(mapBackward.keySet());
071                }
072
073                // if downstream is selected
074                if (direction == Direction.DOWNSTREAM || direction == Direction.BOTHSTREAM)
075                {
076                        // run BFS in downstream direction
077                        BFS bfsForward = new BFS(sourceNodes, null, Direction.DOWNSTREAM, this.limit);
078
079                        Map<GraphObject, Integer> mapForward = bfsForward.run();
080
081                        // add result of BFS to result Set
082                        queryResult.addAll(mapForward.keySet());
083                }
084                
085                // return the result of query
086                return queryResult;
087        }
088}