package org.neo4j.graphdb.traversal;
import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Path;
import org.neo4j.graphdb.RelationshipExpander;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.helpers.Predicate;
/**
* Represents a description of a traversal. Here the rules and behaviour of
* a traversal is described. A traversal description is immutable and each
* method which adds or modifies the behaviour returns a new instances which
* includes the new modification, leaving the instance which returns the new
* instance intact.
*
* When all the rules and behaviours have been described the traversal is
* started using {@link #traverse(Node)} where a starting node is supplied.
* The returned {@link Traverser} is then used to step through the graph,
* returning the positions matching the rules.
*/
public interface TraversalDescription
{
/**
* Sets the {@link Uniqueness} to use.
*
* @param uniqueness the {@link Uniqueness} to use.
* @return a new traversal description with the new modifications.
*/
TraversalDescription uniqueness( Uniqueness uniqueness );
/**
* Sets the {@link Uniqueness} to use. It also accepts an extra parameter
* which is obligatory for certain uniqueness's, f.ex
* {@link Uniqueness#NODE_RECENT}.
*
* @param uniqueness the {@link Uniqueness} to use.
* @param parameter the extra parameter to go with the uniqueness.
* @return a new traversal description with the new modifications.
*/
TraversalDescription uniqueness( Uniqueness uniqueness, Object parameter );
/**
* Adds {@code pruning} to the list of {@link PruneEvaluator}s which
* are used to prune the traversal. The semantics for many prune evaluators
* is that if any one of the added prune evaluators returns {@code true}
* it's considered OK to prune there.
*
* @param pruning the {@link PruneEvaluator} to add to the list of prune
* evaluators to use.
* @return a new traversal description with the new modifications.
*/
TraversalDescription prune( PruneEvaluator pruning );
/**
* Sets the return filter to use, i.e. which positions are OK to return.
* Each position is represented by a {@link Path} from the start node
* of the traversal to the current node. The current node is the
* {@link Path#endNode()} of the path.
*
* @param filter the {@link Predicate} to use as filter.
* @return a new traversal description with the new modifications.
*/
TraversalDescription filter( Predicate<Path> filter );
/**
* Sets the {@link BranchOrderingPolicy} to use. A {@link BranchSelector}
* is the basic decisions in the traversal of "where to go next".
* Examples of default implementations are "breadth first" and
* "depth first", which can be set with convenience methods
* {@link #breadthFirst()} and {@link #depthFirst()}.
*
* @param selector the factory which creates the {@link BranchSelector}
* to use with the traversal.
* @return a new traversal description with the new modifications.
*/
TraversalDescription order( BranchOrderingPolicy selector );
/**
* A convenience method for {@link #order(BranchOrderingPolicy)}
* where a "preorder depth first" selector is used. Positions which are
* deeper than the current position will be returned before positions on
* the same depth. See http://en.wikipedia.org/wiki/Depth-first_search
* @return a new traversal description with the new modifications.
*/
TraversalDescription depthFirst();
/**
* A convenience method for {@link #order(BranchOrderingPolicy)}
* where a "preorder breadth first" selector is used. All positions with
* the same depth will be returned before advancing to the next depth.
* See http://en.wikipedia.org/wiki/Breadth-first_search
* @return a new traversal description with the new modifications.
*/
TraversalDescription breadthFirst();
/**
* Adds {@code type} to the list of relationship types to traverse.
* There's no priority or order in which types to traverse.
*
* @param type the {@link RelationshipType} to add to the list of types
* to traverse.
* @return a new traversal description with the new modifications.
*/
TraversalDescription relationships( RelationshipType type );
/**
* Adds {@code type} to the list of relationship types to traverse in
* the given {@code direction}. There's no priority or order in which
* types to traverse.
*
* @param type the {@link RelationshipType} to add to the list of types
* to traverse.
* @param direction the {@link Direction} to traverse this type of
* relationship in.
* @return a new traversal description with the new modifications.
*/
TraversalDescription relationships( RelationshipType type,
Direction direction );
/**
* Sets the {@link RelationshipExpander} as the expander of relationships,
* discarding all previous calls to
* {@link #relationships(RelationshipType)} and
* {@link #relationships(RelationshipType, Direction)}.
*
* @param expander the {@link RelationshipExpander} to use.
* @return a new traversal description with the new modifications.
*/
TraversalDescription expand( RelationshipExpander expander );
/**
* Starts traversing from {@code startNode} based on all the rules and
* behaviour in this description. A {@link Traverser} is returned which
* is used to step through the graph and getting results back.
*
* @param startNode the {@link Node} to start the traversal from.
* @return a {@link Traverser} used to step through the graph and to
* get results from.
*/
Traverser traverse( Node startNode );
}