org.neo4j.graphdb.PathExpanders Maven / Gradle / Ivy
Show all versions of neo4j-graphdb-api Show documentation
/*
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [http://neo4j.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package org.neo4j.graphdb;
import java.io.PrintStream;
import java.util.function.BiFunction;
import org.neo4j.annotations.api.PublicApi;
import org.neo4j.graphdb.impl.StandardExpander;
import org.neo4j.graphdb.traversal.BranchState;
import org.neo4j.graphdb.traversal.Paths;
/**
* A catalog of convenient {@link PathExpander} factory methods.
*
* Use {@link PathExpanderBuilder} to build specialized {@link PathExpander}s.
*/
@PublicApi
public abstract class PathExpanders
{
/**
* A very permissive {@link PathExpander} that follows any type in any direction.
*
* @param the type of the object that holds the state
* @return a very permissive {@link PathExpander} that follows any type in any direction
*/
@SuppressWarnings( "unchecked" )
public static PathExpander allTypesAndDirections()
{
return StandardExpander.DEFAULT;
}
/**
* A very permissive {@link PathExpander} that follows {@code type} relationships in any direction.
*
* @param type the type of relationships to expand in any direction
* @param the type of the object that holds the state
* @return a very permissive {@link PathExpander} that follows {@code type} relationships in any direction
*/
@SuppressWarnings( "unchecked" )
public static PathExpander forType( RelationshipType type )
{
return StandardExpander.create( type, Direction.BOTH );
}
/**
* A very permissive {@link PathExpander} that follows any type in {@code direction}.
*
* @param direction the direction to follow relationships in
* @param the type of the object that holds the state
* @return a very permissive {@link PathExpander} that follows any type in {@code direction}
*/
@SuppressWarnings( "unchecked" )
public static PathExpander forDirection( Direction direction )
{
return StandardExpander.create( direction );
}
/**
* A very restricted {@link PathExpander} that follows {@code type} in {@code direction}.
*
* @param type the type of relationships to follow
* @param direction the direction to follow relationships in
* @param the type of the object that holds the state
* @return a very restricted {@link PathExpander} that follows {@code type} in {@code direction}
*/
@SuppressWarnings( "unchecked" )
public static PathExpander forTypeAndDirection( RelationshipType type, Direction direction )
{
return StandardExpander.create( type, direction );
}
/**
* A very restricted {@link PathExpander} that follows only the {@code type}/{@code direction} pairs that you list.
*
* @param type1 the type of relationships to follow in {@code direction1}
* @param direction1 the direction to follow {@code type1} relationships in
* @param type2 the type of relationships to follow in {@code direction2}
* @param direction2 the direction to follow {@code type2} relationships in
* @param more add more {@code type}/{@code direction} pairs
* @param the type of the object that holds the state
* @return a very restricted {@link PathExpander} that follows only the {@code type}/{@code direction} pairs that you list
*/
@SuppressWarnings( "unchecked" )
public static PathExpander forTypesAndDirections( RelationshipType type1, Direction direction1,
RelationshipType type2, Direction direction2,
Object... more )
{
return StandardExpander.create( type1, direction1, type2, direction2, more );
}
/**
* An expander forcing constant relationship direction
*
* @param types types of relationships to follow
* @param the type of the object that holds the state
* @return a {@link PathExpander} which enforces constant relationship direction
*/
public static PathExpander forConstantDirectionWithTypes( final RelationshipType... types )
{
return new PathExpander<>()
{
@Override
public Iterable expand( Path path, BranchState state )
{
if ( path.length() == 0 )
{
return path.endNode().getRelationships( types );
}
else
{
Direction direction = getDirectionOfLastRelationship( path );
return path.endNode().getRelationships( direction, types );
}
}
@Override
public PathExpander reverse()
{
return this;
}
private Direction getDirectionOfLastRelationship( Path path )
{
assert path.length() > 0;
Direction direction = Direction.INCOMING;
if ( path.endNode().equals( path.lastRelationship().getEndNode() ) )
{
direction = Direction.OUTGOING;
}
return direction;
}
};
}
private PathExpanders()
{
// you should never instantiate this
}
/**
* A wrapper that uses {@link org.neo4j.graphdb.traversal.Paths.DefaultPathDescriptor} to print expanded paths.
* All expanded paths will be printed using System.out.
* @param source {@link PathExpander} to wrap.
* @param the type of the object that holds the state
* @return A new {@link PathExpander}.
*/
public static PathExpander printingWrapper( final PathExpander source )
{
return printingWrapper( source, new Paths.DefaultPathDescriptor() );
}
/**
* A wrapper that uses {@link org.neo4j.graphdb.traversal.Paths.DefaultPathDescriptor}
* to print expanded paths that fulfill {@link BiFunction} predicate.
* Will use System.out as {@link PrintStream}.
* @param source {@link PathExpander} to wrap.
* @param pred {@link BiFunction} used as predicate for printing expansion.
* @param the type of the object that holds the state
* @return A new {@link PathExpander}.
*/
public static PathExpander printingWrapper(
final PathExpander source,
final BiFunction pred )
{
return printingWrapper( source, pred, new Paths.DefaultPathDescriptor() );
}
/**
* A wrapper that uses {@link org.neo4j.graphdb.traversal.Paths.DefaultPathDescriptor} to print expanded paths
* using given {@link org.neo4j.graphdb.traversal.Paths.PathDescriptor}.
* All expanded paths will be printed.
* Will use System.out as {@link PrintStream}.
* @param source {@link PathExpander} to wrap.
* @param descriptor {@link org.neo4j.graphdb.traversal.Paths.PathDescriptor} to use when printing paths.
* @param the type of the object that holds the state
* @return A new {@link PathExpander}.
*/
public static PathExpander printingWrapper(
final PathExpander source,
final Paths.PathDescriptor descriptor )
{
return printingWrapper( source, ( entities, stateBranchState ) -> Boolean.TRUE, descriptor );
}
/**
* A wrapper that uses {@link org.neo4j.graphdb.traversal.Paths.DefaultPathDescriptor} to print expanded paths
* that fulfill {@link BiFunction} predicate using given {@link org.neo4j.graphdb.traversal.Paths.PathDescriptor}.
* Will use System.out as {@link PrintStream}.
* @param source {@link PathExpander} to wrap.
* @param pred {@link BiFunction} used as predicate for printing expansion.
* @param descriptor {@link org.neo4j.graphdb.traversal.Paths.PathDescriptor} to use when printing paths.
* @param the type of the object that holds the state
* @return A new {@link PathExpander}.
*/
public static PathExpander printingWrapper(
final PathExpander source,
final BiFunction pred,
final Paths.PathDescriptor descriptor )
{
return printingWrapper( source, pred, descriptor, System.out );
}
/**
* A wrapper that uses {@link org.neo4j.graphdb.traversal.Paths.DefaultPathDescriptor} to print expanded paths
* that fulfill {@link BiFunction} predicate using given {@link org.neo4j.graphdb.traversal.Paths.PathDescriptor}.
* @param source {@link PathExpander} to wrap.
* @param pred {@link BiFunction} used as predicate for printing expansion.
* @param descriptor {@link org.neo4j.graphdb.traversal.Paths.PathDescriptor} to use when printing paths.
* @param out {@link PrintStream} to use for printing expanded paths
* @param the type of the object that holds the state
* @return A new {@link PathExpander}.
*/
public static PathExpander printingWrapper(
final PathExpander source,
final BiFunction pred,
final Paths.PathDescriptor descriptor,
final PrintStream out )
{
return new PathExpander<>()
{
@Override
public Iterable expand( Path path, BranchState state )
{
if ( pred.apply( path, state ) )
{
out.println( Paths.pathToString( path, descriptor ) );
}
return source.expand( path, state );
}
@Override
public PathExpander reverse()
{
return printingWrapper( source.reverse(), pred, descriptor, out );
}
};
}
}