Hi Patrik,
there is a lot of commits in your lab, maybe it would be cool to have
a small intro on what you are doing and what the status of the algos
are?

/peter

On Thu, May 22, 2008 at 7:17 PM,  <[EMAIL PROTECTED]> wrote:
> Author: patrik
> Date: 2008-05-22 19:17:29 +0200 (Thu, 22 May 2008)
> New Revision: 1597
>
> Log:
> Various experimental subgraph implementations
>
> Added:
>   
> laboratory/users/patrik/neoalgo/trunk/src/main/java/org/neo4j/algo/graphGeneration/SubNetwork.java
>   
> laboratory/users/patrik/neoalgo/trunk/src/main/java/org/neo4j/algo/graphGeneration/SubNetworkCopy.java
>
> Added: 
> laboratory/users/patrik/neoalgo/trunk/src/main/java/org/neo4j/algo/graphGeneration/SubNetwork.java
> ===================================================================
> --- 
> laboratory/users/patrik/neoalgo/trunk/src/main/java/org/neo4j/algo/graphGeneration/SubNetwork.java
>                           (rev 0)
> +++ 
> laboratory/users/patrik/neoalgo/trunk/src/main/java/org/neo4j/algo/graphGeneration/SubNetwork.java
>   2008-05-22 17:17:29 UTC (rev 1597)
> @@ -0,0 +1,603 @@
> +package org.neo4j.algo.graphGeneration;
> +
> +import java.util.HashMap;
> +import java.util.HashSet;
> +import java.util.LinkedList;
> +import java.util.List;
> +import java.util.Map;
> +import java.util.Set;
> +import org.neo4j.api.core.Direction;
> +import org.neo4j.api.core.Node;
> +import org.neo4j.api.core.Relationship;
> +import org.neo4j.api.core.RelationshipType;
> +import org.neo4j.api.core.ReturnableEvaluator;
> +import org.neo4j.api.core.StopEvaluator;
> +import org.neo4j.api.core.TraversalPosition;
> +import org.neo4j.api.core.Traverser;
> +import org.neo4j.api.core.Traverser.Order;
> +import org.neo4j.impl.traversal.TraverserFactory;
> +
> +/**
> + * This class can be used to represent part of a network (like a subgraph),
> + * represented as a set of nodes and a set of edges. All this really does is
> + * filter the results of Node.getRelationships to only return relationships
> + * within this subnetwork, thus limiting traversals and searches to the nodes
> + * within the subnetwork. Therefore, any changes made to the subnetwork will 
> be
> + * reflected in the underlying network as well. The subgraph always starts 
> out
> + * empty, and can be emptied again with the clear() method. It can then be
> + * filled with nodes and edges through the various methods supplied. This 
> class
> + * can of course also be used to retrieve the set of all nodes and the set of
> + * all edges from a network.
> + * @author Patrik Larsson
> + */
> +public class SubNetwork
> +{
> +    Set<Relationship> subNetworkRelationships = new HashSet<Relationship>();
> +    Set<Node> subNetworkNodes = new HashSet<Node>();
> +    TraverserFactory traverserFactory = new TraverserFactory();
> +
> +    /**
> +     * Adds a tree to this subnetwork by doing a breadth first search of a 
> given
> +     * depth, adding all nodes found and the first edge leading to each node.
> +     * @param node
> +     *            The starting node
> +     * @param searchDepth
> +     *            The search depth.
> +     * @param relationshipType
> +     *            Relation type to traverse.
> +     * @param direction
> +     *            Direction in which to traverse relationships.
> +     */
> +    public void addTreeFromCentralNode( Node node, final int searchDepth,
> +        RelationshipType relationshipType, Direction direction )
> +    {
> +        Traverser traverser = node.traverse( Order.BREADTH_FIRST,
> +            new StopEvaluator()
> +            {
> +                public boolean isStopNode( TraversalPosition currentPos )
> +                {
> +                    return currentPos.depth() >= searchDepth;
> +                }
> +            }, ReturnableEvaluator.ALL, relationshipType, direction );
> +        for ( Node node2 : traverser )
> +        {
> +            subNetworkNodes.add( node2 );
> +            subNetworkRelationships.add( traverser.currentPosition()
> +                .lastRelationshipTraversed() );
> +        }
> +    }
> +
> +    /**
> +     * Makes a search of a given depth from a given node and adds all found
> +     * nodes and relationships to this subnetwork.
> +     * @param node
> +     *            The starting node
> +     * @param searchDepth
> +     *            The search depth.
> +     * @param relationshipType
> +     *            Relation type to traverse.
> +     * @param direction
> +     *            Direction in which to traverse relationships.
> +     * @param includeBoundaryRelationships
> +     *            If false, relationships between nodes where the maximum 
> depth
> +     *            has been reached will not be included since the search 
> depth
> +     *            is considered to have been exhausted at them.
> +     */
> +    public void addSubNetworkFromCentralNode( Node node, final int 
> searchDepth,
> +        RelationshipType relationshipType, Direction direction,
> +        boolean includeBoundaryRelationships )
> +    {
> +        internalAddSubNetworkFromCentralNode( node, searchDepth,
> +            relationshipType, direction, includeBoundaryRelationships,
> +            new HashMap<Node,Integer>() );
> +    }
> +
> +    /**
> +     * Same as addSubNetworkFromCentralNode, but the internal version with 
> some
> +     * extra data sent along.
> +     * @param nodeScanDepths
> +     *            This stores at what depth a certain node was added so we 
> can
> +     *            ignore it when we reach it with a lower depth.
> +     */
> +    protected void internalAddSubNetworkFromCentralNode( Node node,
> +        final int searchDepth, RelationshipType relationshipType,
> +        Direction direction, boolean includeBoundaryRelationships,
> +        Map<Node,Integer> nodeScanDepths )
> +    {
> +        // We stop here if this node has already been scanned and we this 
> time
> +        // have a "shorter" way to go beyond it.
> +        Integer previousDepth = nodeScanDepths.get( node );
> +        if ( previousDepth != null && previousDepth >= searchDepth )
> +        {
> +            return;
> +        }
> +        subNetworkNodes.add( node );
> +        nodeScanDepths.put( node, searchDepth );
> +        if ( searchDepth == 0 && includeBoundaryRelationships )
> +        {
> +            for ( Relationship relationship : node.getRelationships(
> +                relationshipType, direction ) )
> +            {
> +                if ( subNetworkNodes
> +                    .contains( relationship.getOtherNode( node ) ) )
> +                {
> +                    subNetworkRelationships.add( relationship );
> +                }
> +            }
> +        }
> +        if ( searchDepth <= 0 )
> +        {
> +            return;
> +        }
> +        for ( Relationship relationship : node.getRelationships(
> +            relationshipType, direction ) )
> +        {
> +            subNetworkRelationships.add( relationship );
> +            internalAddSubNetworkFromCentralNode( relationship
> +                .getOtherNode( node ), searchDepth - 1, relationshipType,
> +                direction, includeBoundaryRelationships, nodeScanDepths );
> +        }
> +    }
> +
> +    public void clear()
> +    {
> +        subNetworkRelationships = new HashSet<Relationship>();
> +        subNetworkNodes = new HashSet<Node>();
> +    }
> +
> +    protected Relationship filterRelationship( Relationship relationship )
> +    {
> +        if ( subNetworkRelationships.contains( relationship ) )
> +        {
> +            return relationship;
> +        }
> +        return null;
> +    }
> +
> +    protected Iterable<Relationship> filterRelationships(
> +        Iterable<Relationship> rels )
> +    {
> +        List<Relationship> result = new LinkedList<Relationship>();
> +        for ( Relationship relationship : rels )
> +        {
> +            if ( filterRelationship( relationship ) != null )
> +            {
> +                result.add( relationship );
> +            }
> +        }
> +        return result;
> +    }
> +
> +    class SubNetWorkNode implements Node
> +    {
> +        Node underlyingNode;
> +
> +        public SubNetWorkNode( Node underlyingNode )
> +        {
> +            super();
> +            this.underlyingNode = underlyingNode;
> +        }
> +
> +        /**
> +         * @param otherNode
> +         * @param type
> +         * @return
> +         * @see 
> org.neo4j.api.core.Node#createRelationshipTo(org.neo4j.api.core.Node,
> +         *      org.neo4j.api.core.RelationshipType)
> +         */
> +        public Relationship createRelationshipTo( Node otherNode,
> +            RelationshipType type )
> +        {
> +            return new SubNetworkRelationship( underlyingNode
> +                .createRelationshipTo( otherNode, type ) );
> +        }
> +
> +        /**
> +         * @see org.neo4j.api.core.Node#delete()
> +         */
> +        public void delete()
> +        {
> +            underlyingNode.delete();
> +        }
> +
> +        /**
> +         * @return
> +         * @see org.neo4j.api.core.Node#getId()
> +         */
> +        public long getId()
> +        {
> +            return underlyingNode.getId();
> +        }
> +
> +        /**
> +         * @param arg0
> +         * @param arg1
> +         * @return
> +         * @see 
> org.neo4j.api.core.PropertyContainer#getProperty(java.lang.String,
> +         *      java.lang.Object)
> +         */
> +        public Object getProperty( String arg0, Object arg1 )
> +        {
> +            return underlyingNode.getProperty( arg0, arg1 );
> +        }
> +
> +        /**
> +         * @param arg0
> +         * @return
> +         * @see 
> org.neo4j.api.core.PropertyContainer#getProperty(java.lang.String)
> +         */
> +        public Object getProperty( String arg0 )
> +        {
> +            return underlyingNode.getProperty( arg0 );
> +        }
> +
> +        /**
> +         * @return
> +         * @see org.neo4j.api.core.PropertyContainer#getPropertyKeys()
> +         */
> +        public Iterable<String> getPropertyKeys()
> +        {
> +            return underlyingNode.getPropertyKeys();
> +        }
> +
> +        /**
> +         * @return
> +         * @see org.neo4j.api.core.PropertyContainer#getPropertyValues()
> +         */
> +        public Iterable<Object> getPropertyValues()
> +        {
> +            return underlyingNode.getPropertyValues();
> +        }
> +
> +        /**
> +         * @return
> +         * @see org.neo4j.api.core.Node#getRelationships()
> +         */
> +        public Iterable<Relationship> getRelationships()
> +        {
> +            return filterRelationships( underlyingNode.getRelationships() );
> +        }
> +
> +        /**
> +         * @param dir
> +         * @return
> +         * @see 
> org.neo4j.api.core.Node#getRelationships(org.neo4j.api.core.Direction)
> +         */
> +        public Iterable<Relationship> getRelationships( Direction dir )
> +        {
> +            return filterRelationships( underlyingNode.getRelationships( dir 
> ) );
> +        }
> +
> +        /**
> +         * @param type
> +         * @param dir
> +         * @return
> +         * @see 
> org.neo4j.api.core.Node#getRelationships(org.neo4j.api.core.RelationshipType,
> +         *      org.neo4j.api.core.Direction)
> +         */
> +        public Iterable<Relationship> getRelationships( RelationshipType 
> type,
> +            Direction dir )
> +        {
> +            return filterRelationships( underlyingNode.getRelationships( 
> type,
> +                dir ) );
> +        }
> +
> +        /**
> +         * @param types
> +         * @return
> +         * @see 
> org.neo4j.api.core.Node#getRelationships(org.neo4j.api.core.RelationshipType[])
> +         */
> +        public Iterable<Relationship> getRelationships(
> +            RelationshipType... types )
> +        {
> +            return filterRelationships( underlyingNode.getRelationships( 
> types ) );
> +        }
> +
> +        /**
> +         * @param type
> +         * @param dir
> +         * @return
> +         * @see 
> org.neo4j.api.core.Node#getSingleRelationship(org.neo4j.api.core.RelationshipType,
> +         *      org.neo4j.api.core.Direction)
> +         */
> +        public Relationship getSingleRelationship( RelationshipType type,
> +            Direction dir )
> +        {
> +            return filterRelationship( underlyingNode.getSingleRelationship(
> +                type, dir ) );
> +        }
> +
> +        /**
> +         * @param arg0
> +         * @return
> +         * @see 
> org.neo4j.api.core.PropertyContainer#hasProperty(java.lang.String)
> +         */
> +        public boolean hasProperty( String arg0 )
> +        {
> +            return underlyingNode.hasProperty( arg0 );
> +        }
> +
> +        public boolean hasRelationship()
> +        {
> +            return getRelationships().iterator().hasNext();
> +        }
> +
> +        public boolean hasRelationship( RelationshipType... types )
> +        {
> +            return getRelationships( types ).iterator().hasNext();
> +        }
> +
> +        public boolean hasRelationship( Direction dir )
> +        {
> +            return getRelationships( dir ).iterator().hasNext();
> +        }
> +
> +        public boolean hasRelationship( RelationshipType type, Direction dir 
> )
> +        {
> +            return getRelationships( type, dir ).iterator().hasNext();
> +        }
> +
> +        /**
> +         * @param arg0
> +         * @return
> +         * @see 
> org.neo4j.api.core.PropertyContainer#removeProperty(java.lang.String)
> +         */
> +        public Object removeProperty( String arg0 )
> +        {
> +            return underlyingNode.removeProperty( arg0 );
> +        }
> +
> +        /**
> +         * @param arg0
> +         * @param arg1
> +         * @see 
> org.neo4j.api.core.PropertyContainer#setProperty(java.lang.String,
> +         *      java.lang.Object)
> +         */
> +        public void setProperty( String arg0, Object arg1 )
> +        {
> +            underlyingNode.setProperty( arg0, arg1 );
> +        }
> +
> +        public Traverser traverse( Order traversalOrder,
> +            StopEvaluator stopEvaluator,
> +            ReturnableEvaluator returnableEvaluator,
> +            RelationshipType relationshipType, Direction direction )
> +        {
> +            if ( direction == null )
> +            {
> +                throw new IllegalArgumentException( "Null direction" );
> +            }
> +            if ( relationshipType == null )
> +            {
> +                throw new IllegalArgumentException( "Null relationship type" 
> );
> +            }
> +            // rest of parameters will be validated in traverser package
> +            return traverserFactory
> +                .createTraverser( traversalOrder, this, relationshipType,
> +                    direction, stopEvaluator, returnableEvaluator );
> +        }
> +
> +        public Traverser traverse( Order traversalOrder,
> +            StopEvaluator stopEvaluator,
> +            ReturnableEvaluator returnableEvaluator,
> +            RelationshipType firstRelationshipType, Direction firstDirection,
> +            RelationshipType secondRelationshipType, Direction 
> secondDirection )
> +        {
> +            if ( firstDirection == null || secondDirection == null )
> +            {
> +                throw new IllegalArgumentException( "Null direction, "
> +                    + "firstDirection=" + firstDirection + "secondDirection="
> +                    + secondDirection );
> +            }
> +            if ( firstRelationshipType == null
> +                || secondRelationshipType == null )
> +            {
> +                throw new IllegalArgumentException( "Null rel type, "
> +                    + "first=" + firstRelationshipType + "second="
> +                    + secondRelationshipType );
> +            }
> +            // rest of parameters will be validated in traverser package
> +            RelationshipType[] types = new RelationshipType[2];
> +            Direction[] dirs = new Direction[2];
> +            types[0] = firstRelationshipType;
> +            types[1] = secondRelationshipType;
> +            dirs[0] = firstDirection;
> +            dirs[1] = secondDirection;
> +            return traverserFactory.createTraverser( traversalOrder, this,
> +                types, dirs, stopEvaluator, returnableEvaluator );
> +        }
> +
> +        public Traverser traverse( Order traversalOrder,
> +            StopEvaluator stopEvaluator,
> +            ReturnableEvaluator returnableEvaluator,
> +            Object... relationshipTypesAndDirections )
> +        {
> +            int length = relationshipTypesAndDirections.length;
> +            if ( (length % 2) != 0 || length == 0 )
> +            {
> +                throw new IllegalArgumentException( "Variable argument 
> should "
> +                    + " consist of [RelationshipType,Direction] pairs" );
> +            }
> +            int elements = relationshipTypesAndDirections.length / 2;
> +            RelationshipType[] types = new RelationshipType[elements];
> +            Direction[] dirs = new Direction[elements];
> +            int j = 0;
> +            for ( int i = 0; i < elements; i++ )
> +            {
> +                Object relType = relationshipTypesAndDirections[j++];
> +                if ( !(relType instanceof RelationshipType) )
> +                {
> +                    throw new IllegalArgumentException(
> +                        "Expected RelationshipType at var args pos " + (j - 
> 1)
> +                            + ", found " + relType );
> +                }
> +                types[i] = (RelationshipType) relType;
> +                Object direction = relationshipTypesAndDirections[j++];
> +                if ( !(direction instanceof Direction) )
> +                {
> +                    throw new IllegalArgumentException(
> +                        "Expected Direction at var args pos " + (j - 1)
> +                            + ", found " + direction );
> +                }
> +                dirs[i] = (Direction) direction;
> +            }
> +            return traverserFactory.createTraverser( traversalOrder, this,
> +                types, dirs, stopEvaluator, returnableEvaluator );
> +        }
> +    }
> +    public class SubNetworkRelationship implements Relationship
> +    {
> +        Relationship underlyingRelationship;
> +
> +        public SubNetworkRelationship( Relationship underlyingRelationship )
> +        {
> +            super();
> +            this.underlyingRelationship = underlyingRelationship;
> +        }
> +
> +        /**
> +         * @see org.neo4j.api.core.Relationship#delete()
> +         */
> +        public void delete()
> +        {
> +            underlyingRelationship.delete();
> +        }
> +
> +        /**
> +         * @return
> +         * @see org.neo4j.api.core.Relationship#getEndNode()
> +         */
> +        public Node getEndNode()
> +        {
> +            return new SubNetWorkNode( underlyingRelationship.getEndNode() );
> +        }
> +
> +        /**
> +         * @return
> +         * @see org.neo4j.api.core.Relationship#getId()
> +         */
> +        public long getId()
> +        {
> +            return underlyingRelationship.getId();
> +        }
> +
> +        /**
> +         * @return
> +         * @see org.neo4j.api.core.Relationship#getNodes()
> +         */
> +        public Node[] getNodes()
> +        {
> +            return new Node[] { getStartNode(), getEndNode() };
> +        }
> +
> +        /**
> +         * @param node
> +         * @return
> +         * @see 
> org.neo4j.api.core.Relationship#getOtherNode(org.neo4j.api.core.Node)
> +         */
> +        public Node getOtherNode( Node node )
> +        {
> +            return new SubNetWorkNode( underlyingRelationship
> +                .getOtherNode( node ) );
> +        }
> +
> +        /**
> +         * @param arg0
> +         * @param arg1
> +         * @return
> +         * @see 
> org.neo4j.api.core.PropertyContainer#getProperty(java.lang.String,
> +         *      java.lang.Object)
> +         */
> +        public Object getProperty( String arg0, Object arg1 )
> +        {
> +            return underlyingRelationship.getProperty( arg0, arg1 );
> +        }
> +
> +        /**
> +         * @param arg0
> +         * @return
> +         * @see 
> org.neo4j.api.core.PropertyContainer#getProperty(java.lang.String)
> +         */
> +        public Object getProperty( String arg0 )
> +        {
> +            return underlyingRelationship.getProperty( arg0 );
> +        }
> +
> +        /**
> +         * @return
> +         * @see org.neo4j.api.core.PropertyContainer#getPropertyKeys()
> +         */
> +        public Iterable<String> getPropertyKeys()
> +        {
> +            return underlyingRelationship.getPropertyKeys();
> +        }
> +
> +        /**
> +         * @return
> +         * @see org.neo4j.api.core.PropertyContainer#getPropertyValues()
> +         */
> +        public Iterable<Object> getPropertyValues()
> +        {
> +            return underlyingRelationship.getPropertyValues();
> +        }
> +
> +        /**
> +         * @return
> +         * @see org.neo4j.api.core.Relationship#getStartNode()
> +         */
> +        public Node getStartNode()
> +        {
> +            return new SubNetWorkNode( underlyingRelationship.getStartNode() 
> );
> +        }
> +
> +        /**
> +         * @return
> +         * @see org.neo4j.api.core.Relationship#getType()
> +         */
> +        public RelationshipType getType()
> +        {
> +            return underlyingRelationship.getType();
> +        }
> +
> +        /**
> +         * @param arg0
> +         * @return
> +         * @see 
> org.neo4j.api.core.PropertyContainer#hasProperty(java.lang.String)
> +         */
> +        public boolean hasProperty( String arg0 )
> +        {
> +            return underlyingRelationship.hasProperty( arg0 );
> +        }
> +
> +        /**
> +         * @param type
> +         * @return
> +         * @see 
> org.neo4j.api.core.Relationship#isType(org.neo4j.api.core.RelationshipType)
> +         */
> +        public boolean isType( RelationshipType type )
> +        {
> +            return underlyingRelationship.isType( type );
> +        }
> +
> +        /**
> +         * @param arg0
> +         * @return
> +         * @see 
> org.neo4j.api.core.PropertyContainer#removeProperty(java.lang.String)
> +         */
> +        public Object removeProperty( String arg0 )
> +        {
> +            return underlyingRelationship.removeProperty( arg0 );
> +        }
> +
> +        /**
> +         * @param arg0
> +         * @param arg1
> +         * @see 
> org.neo4j.api.core.PropertyContainer#setProperty(java.lang.String,
> +         *      java.lang.Object)
> +         */
> +        public void setProperty( String arg0, Object arg1 )
> +        {
> +            underlyingRelationship.setProperty( arg0, arg1 );
> +        }
> +    }
> +}
>
> Added: 
> laboratory/users/patrik/neoalgo/trunk/src/main/java/org/neo4j/algo/graphGeneration/SubNetworkCopy.java
> ===================================================================
> --- 
> laboratory/users/patrik/neoalgo/trunk/src/main/java/org/neo4j/algo/graphGeneration/SubNetworkCopy.java
>                               (rev 0)
> +++ 
> laboratory/users/patrik/neoalgo/trunk/src/main/java/org/neo4j/algo/graphGeneration/SubNetworkCopy.java
>       2008-05-22 17:17:29 UTC (rev 1597)
> @@ -0,0 +1,633 @@
> +package org.neo4j.algo.graphGeneration;
> +
> +import java.util.HashMap;
> +import java.util.HashSet;
> +import java.util.LinkedList;
> +import java.util.List;
> +import java.util.Map;
> +import java.util.Set;
> +import org.neo4j.api.core.Direction;
> +import org.neo4j.api.core.Node;
> +import org.neo4j.api.core.Relationship;
> +import org.neo4j.api.core.RelationshipType;
> +import org.neo4j.api.core.ReturnableEvaluator;
> +import org.neo4j.api.core.StopEvaluator;
> +import org.neo4j.api.core.TraversalPosition;
> +import org.neo4j.api.core.Traverser;
> +import org.neo4j.api.core.Traverser.Order;
> +import org.neo4j.impl.traversal.TraverserFactory;
> +
> +/**
> + * This class can be used to generate an in-memory copy of a part of a 
> network
> + * (like a subgraph), represented as a set of copys of nodes and a set of 
> copys
> + * of edges. Currently, any changes made to the subnetwork will be reflected 
> in
> + * the underlying network as well. The subgraph always starts out empty, and 
> can
> + * be emptied again with the clear() method. It can then be filled with nodes
> + * and edges through the various methods supplied. This class can of course 
> be
> + * used to retrieve the set of all nodes and the set of all edges from a
> + * network.
> + * @author Patrik Larsson
> + */
> +public class SubNetworkCopy
> +{
> +    Set<Relationship> subNetworkRelationships = new HashSet<Relationship>();
> +    Map<Node,SubNetworkNode> nodeMap = new HashMap<Node,SubNetworkNode>();
> +
> +    public SubNetworkRelationship addRelationship(
> +        Relationship underlyingRelationship )
> +    {
> +        SubNetworkRelationship subNetworkRelationship = new 
> SubNetworkRelationship(
> +            underlyingRelationship, nodeMap.get( underlyingRelationship
> +                .getStartNode() ), nodeMap.get( underlyingRelationship
> +                .getEndNode() ) );
> +        subNetworkRelationships.add( subNetworkRelationship );
> +        return subNetworkRelationship;
> +    }
> +
> +    /**
> +     * Empties this subnetwork.
> +     */
> +    public void clear()
> +    {
> +        subNetworkRelationships = new HashSet<Relationship>();
> +        nodeMap = new HashMap<Node,SubNetworkNode>();
> +    }
> +
> +    /**
> +     * Adds a tree to this subnetwork by doing a breadth first search of a 
> given
> +     * depth, adding all nodes found and the first edge leading to each node.
> +     * @param node
> +     *            The starting node
> +     * @param searchDepth
> +     *            The search depth.
> +     * @param relationshipType
> +     *            Relation type to traverse.
> +     * @param direction
> +     *            Direction in which to traverse edges.
> +     */
> +    public void addTreeFromCentralNode( Node node, final int searchDepth,
> +        RelationshipType relationshipType, Direction direction )
> +    {
> +        Traverser traverser = node.traverse( Order.BREADTH_FIRST,
> +            new StopEvaluator()
> +            {
> +                public boolean isStopNode( TraversalPosition currentPos )
> +                {
> +                    return currentPos.depth() >= searchDepth;
> +                }
> +            }, ReturnableEvaluator.ALL, relationshipType, direction );
> +        for ( Node node2 : traverser )
> +        {
> +            nodeMap.put( node2, new SubNetworkNode( node2 ) );
> +            Relationship relationship = traverser.currentPosition()
> +                .lastRelationshipTraversed();
> +            if ( relationship != null )
> +            {
> +                addRelationship( relationship );
> +            }
> +        }
> +    }
> +
> +    /**
> +     * Makes a search of a given depth from a given node and adds all found
> +     * nodes and relationships to this subnetwork.
> +     * @param node
> +     *            The starting node
> +     * @param searchDepth
> +     *            The search depth.
> +     * @param relationshipType
> +     *            Relation type to traverse.
> +     * @param direction
> +     *            Direction in which to traverse edges.
> +     */
> +    public void addSubNetworkFromCentralNode( Node node, final int 
> searchDepth,
> +        RelationshipType relationshipType, Direction direction )
> +    {
> +        internalAddSubNetworkFromCentralNode( node, searchDepth,
> +            relationshipType, direction, new HashMap<Node,Integer>() );
> +    }
> +
> +    /**
> +     * Same as addSubNetworkFromCentralNode, but the internal version with 
> some
> +     * extra data sent along.
> +     * @param nodeScanDepths
> +     *            This stores at what depth a certain node was added so we 
> can
> +     *            ignore it when we reach it with a lower depth.
> +     */
> +    protected void internalAddSubNetworkFromCentralNode( Node node,
> +        final int searchDepth, RelationshipType relationshipType,
> +        Direction direction, Map<Node,Integer> nodeScanDepths )
> +    {
> +        // We stop here if this node has already been scanned and we this 
> time
> +        // have a "shorter" way to go beyond it.
> +        Integer previousDepth = nodeScanDepths.get( node );
> +        if ( previousDepth != null && previousDepth >= searchDepth )
> +        {
> +            return;
> +        }
> +        nodeMap.put( node, new SubNetworkNode( node ) );
> +        nodeScanDepths.put( node, searchDepth );
> +        for ( Relationship relationship : node.getRelationships(
> +            relationshipType, direction ) )
> +        {
> +            Node otherNode = relationship.getOtherNode( node );
> +            if ( nodeMap.containsKey( otherNode ) )
> +            {
> +                addRelationship( relationship );
> +            }
> +        }
> +        if ( searchDepth <= 0 )
> +        {
> +            return;
> +        }
> +        for ( Relationship relationship : node.getRelationships(
> +            relationshipType, direction ) )
> +        {
> +            internalAddSubNetworkFromCentralNode( relationship
> +                .getOtherNode( node ), searchDepth - 1, relationshipType,
> +                direction, nodeScanDepths );
> +        }
> +    }
> +
> +    /**
> +     * @return the relationships
> +     */
> +    public Set<Relationship> getEdges()
> +    {
> +        return subNetworkRelationships;
> +    }
> +
> +    /**
> +     * @return the nodes
> +     */
> +    public Set<Node> getNodes()
> +    {
> +        return new HashSet<Node>( nodeMap.values() );
> +    }
> +
> +    TraverserFactory traverserFactory = new TraverserFactory();
> +
> +    public class SubNetworkNode implements Node
> +    {
> +        Node underlyingNode;
> +        Map<RelationshipType,List<SubNetworkRelationship>> relationships = 
> new HashMap<RelationshipType,List<SubNetworkRelationship>>();
> +
> +        /**
> +         * @return
> +         * @see org.neo4j.api.core.Node#getId()
> +         */
> +        public long getId()
> +        {
> +            return underlyingNode.getId();
> +        }
> +
> +        /**
> +         * @param arg0
> +         * @return
> +         * @see 
> org.neo4j.api.core.PropertyContainer#getProperty(java.lang.String)
> +         */
> +        public Object getProperty( String arg0 )
> +        {
> +            return underlyingNode.getProperty( arg0 );
> +        }
> +
> +        /**
> +         * @param arg0
> +         * @param arg1
> +         * @return
> +         * @see 
> org.neo4j.api.core.PropertyContainer#getProperty(java.lang.String,
> +         *      java.lang.Object)
> +         */
> +        public Object getProperty( String arg0, Object arg1 )
> +        {
> +            return underlyingNode.getProperty( arg0, arg1 );
> +        }
> +
> +        /**
> +         * @return
> +         * @see org.neo4j.api.core.PropertyContainer#getPropertyKeys()
> +         */
> +        public Iterable<String> getPropertyKeys()
> +        {
> +            return underlyingNode.getPropertyKeys();
> +        }
> +
> +        /**
> +         * @return
> +         * @see org.neo4j.api.core.PropertyContainer#getPropertyValues()
> +         */
> +        public Iterable<Object> getPropertyValues()
> +        {
> +            return underlyingNode.getPropertyValues();
> +        }
> +
> +        /**
> +         * @param arg0
> +         * @return
> +         * @see 
> org.neo4j.api.core.PropertyContainer#hasProperty(java.lang.String)
> +         */
> +        public boolean hasProperty( String arg0 )
> +        {
> +            return underlyingNode.hasProperty( arg0 );
> +        }
> +
> +        /**
> +         * @param arg0
> +         * @return
> +         * @see 
> org.neo4j.api.core.PropertyContainer#removeProperty(java.lang.String)
> +         */
> +        public Object removeProperty( String arg0 )
> +        {
> +            return underlyingNode.removeProperty( arg0 );
> +        }
> +
> +        /**
> +         * @param arg0
> +         * @param arg1
> +         * @see 
> org.neo4j.api.core.PropertyContainer#setProperty(java.lang.String,
> +         *      java.lang.Object)
> +         */
> +        public void setProperty( String arg0, Object arg1 )
> +        {
> +            underlyingNode.setProperty( arg0, arg1 );
> +        }
> +
> +        public SubNetworkNode( Node underlyingNode )
> +        {
> +            super();
> +            this.underlyingNode = underlyingNode;
> +        }
> +
> +        public Relationship createRelationshipTo( Node otherNode,
> +            RelationshipType type )
> +        {
> +            SubNetworkNode otherSubNetworkNode = (SubNetworkNode) otherNode;
> +            Node otherUnderlyingNode = otherNode;
> +            // If otherNode is a subNetworkNode (of this network)
> +            if ( nodeMap.containsValue( otherNode ) )
> +            {
> +                otherUnderlyingNode = otherSubNetworkNode.underlyingNode;
> +            }
> +            // Otherwise add it
> +            // TODO: or throw some error?
> +            else
> +            {
> +                otherSubNetworkNode = new SubNetworkNode( 
> otherUnderlyingNode );
> +                nodeMap.put( otherUnderlyingNode, otherSubNetworkNode );
> +            }
> +            Relationship underlyingRelationship = underlyingNode
> +                .createRelationshipTo( otherUnderlyingNode, type );
> +            return addRelationship( underlyingRelationship );
> +        }
> +
> +        public void delete()
> +        {
> +            // TODO Auto-generated method stub
> +        }
> +
> +        public Iterable<Relationship> getRelationships()
> +        {
> +            List<Relationship> result = new LinkedList<Relationship>();
> +            for ( RelationshipType relationshipType : relationships.keySet() 
> )
> +            {
> +                result.addAll( relationships.get( relationshipType ) );
> +            }
> +            return result;
> +        }
> +
> +        public Iterable<Relationship> getRelationships(
> +            RelationshipType... types )
> +        {
> +            List<Relationship> result = new LinkedList<Relationship>();
> +            for ( RelationshipType relationshipType : types )
> +            {
> +                result.addAll( relationships.get( relationshipType ) );
> +            }
> +            return result;
> +        }
> +
> +        protected List<Relationship> getRelationshipsOfDirection(
> +            Iterable<Relationship> rels, Direction dir )
> +        {
> +            List<Relationship> result = new LinkedList<Relationship>();
> +            for ( Relationship relationship : rels )
> +            {
> +                if ( dir.equals( Direction.BOTH )
> +                    || (dir.equals( Direction.OUTGOING ) && relationship
> +                        .getStartNode().equals( this ))
> +                    || (dir.equals( Direction.INCOMING ) && relationship
> +                        .getEndNode().equals( this )) )
> +                {
> +                    result.add( relationship );
> +                }
> +            }
> +            return result;
> +        }
> +
> +        protected boolean containsRelationshipOfDirection(
> +            Iterable<Relationship> rels, Direction dir )
> +        {
> +            for ( Relationship relationship : rels )
> +            {
> +                if ( dir.equals( Direction.BOTH )
> +                    || (dir.equals( Direction.OUTGOING ) && relationship
> +                        .getStartNode().equals( this ))
> +                    || (dir.equals( Direction.INCOMING ) && relationship
> +                        .getEndNode().equals( this )) )
> +                {
> +                    return true;
> +                }
> +            }
> +            return false;
> +        }
> +
> +        public Iterable<Relationship> getRelationships( Direction dir )
> +        {
> +            return getRelationshipsOfDirection( getRelationships(), dir );
> +        }
> +
> +        public Iterable<Relationship> getRelationships( RelationshipType 
> type,
> +            Direction dir )
> +        {
> +            List<Relationship> result = new LinkedList<Relationship>();
> +            result.addAll( relationships.get( type ) );
> +            return result;
> +        }
> +
> +        public Relationship getSingleRelationship( RelationshipType type,
> +            Direction dir )
> +        {
> +            List<SubNetworkRelationship> rels = relationships.get( type );
> +            if ( rels == null || rels.isEmpty() )
> +            {
> +                return null;
> +            }
> +            return rels.get( 0 );
> +        }
> +
> +        public boolean hasRelationship()
> +        {
> +            return !relationships.isEmpty();
> +        }
> +
> +        public boolean hasRelationship( RelationshipType... types )
> +        {
> +            for ( RelationshipType relationshipType : types )
> +            {
> +                List<SubNetworkRelationship> rels = relationships
> +                    .get( relationshipType );
> +                if ( rels != null && !rels.isEmpty() )
> +                {
> +                    return true;
> +                }
> +            }
> +            return false;
> +        }
> +
> +        public boolean hasRelationship( Direction dir )
> +        {
> +            return containsRelationshipOfDirection( getRelationships(), dir 
> );
> +        }
> +
> +        public boolean hasRelationship( RelationshipType type, Direction dir 
> )
> +        {
> +            return containsRelationshipOfDirection( getRelationships( type ),
> +                dir );
> +        }
> +
> +        public Traverser traverse( Order traversalOrder,
> +            StopEvaluator stopEvaluator,
> +            ReturnableEvaluator returnableEvaluator,
> +            RelationshipType relationshipType, Direction direction )
> +        {
> +            if ( direction == null )
> +            {
> +                throw new IllegalArgumentException( "Null direction" );
> +            }
> +            if ( relationshipType == null )
> +            {
> +                throw new IllegalArgumentException( "Null relationship type" 
> );
> +            }
> +            // rest of parameters will be validated in traverser package
> +            return traverserFactory
> +                .createTraverser( traversalOrder, this, relationshipType,
> +                    direction, stopEvaluator, returnableEvaluator );
> +        }
> +
> +        public Traverser traverse( Order traversalOrder,
> +            StopEvaluator stopEvaluator,
> +            ReturnableEvaluator returnableEvaluator,
> +            RelationshipType firstRelationshipType, Direction firstDirection,
> +            RelationshipType secondRelationshipType, Direction 
> secondDirection )
> +        {
> +            if ( firstDirection == null || secondDirection == null )
> +            {
> +                throw new IllegalArgumentException( "Null direction, "
> +                    + "firstDirection=" + firstDirection + "secondDirection="
> +                    + secondDirection );
> +            }
> +            if ( firstRelationshipType == null
> +                || secondRelationshipType == null )
> +            {
> +                throw new IllegalArgumentException( "Null rel type, "
> +                    + "first=" + firstRelationshipType + "second="
> +                    + secondRelationshipType );
> +            }
> +            // rest of parameters will be validated in traverser package
> +            RelationshipType[] types = new RelationshipType[2];
> +            Direction[] dirs = new Direction[2];
> +            types[0] = firstRelationshipType;
> +            types[1] = secondRelationshipType;
> +            dirs[0] = firstDirection;
> +            dirs[1] = secondDirection;
> +            return traverserFactory.createTraverser( traversalOrder, this,
> +                types, dirs, stopEvaluator, returnableEvaluator );
> +        }
> +
> +        public Traverser traverse( Order traversalOrder,
> +            StopEvaluator stopEvaluator,
> +            ReturnableEvaluator returnableEvaluator,
> +            Object... relationshipTypesAndDirections )
> +        {
> +            int length = relationshipTypesAndDirections.length;
> +            if ( (length % 2) != 0 || length == 0 )
> +            {
> +                throw new IllegalArgumentException( "Variable argument 
> should "
> +                    + " consist of [RelationshipType,Direction] pairs" );
> +            }
> +            int elements = relationshipTypesAndDirections.length / 2;
> +            RelationshipType[] types = new RelationshipType[elements];
> +            Direction[] dirs = new Direction[elements];
> +            int j = 0;
> +            for ( int i = 0; i < elements; i++ )
> +            {
> +                Object relType = relationshipTypesAndDirections[j++];
> +                if ( !(relType instanceof RelationshipType) )
> +                {
> +                    throw new IllegalArgumentException(
> +                        "Expected RelationshipType at var args pos " + (j - 
> 1)
> +                            + ", found " + relType );
> +                }
> +                types[i] = (RelationshipType) relType;
> +                Object direction = relationshipTypesAndDirections[j++];
> +                if ( !(direction instanceof Direction) )
> +                {
> +                    throw new IllegalArgumentException(
> +                        "Expected Direction at var args pos " + (j - 1)
> +                            + ", found " + direction );
> +                }
> +                dirs[i] = (Direction) direction;
> +            }
> +            return traverserFactory.createTraverser( traversalOrder, this,
> +                types, dirs, stopEvaluator, returnableEvaluator );
> +        }
> +    }
> +    public class SubNetworkRelationship implements Relationship
> +    {
> +        Relationship underlyingRelationship;
> +        Node startNode;
> +        Node endNode;
> +
> +        public SubNetworkRelationship( Relationship underlyingRelationship,
> +            Node startNode, Node endNode )
> +        {
> +            super();
> +            this.underlyingRelationship = underlyingRelationship;
> +            this.startNode = startNode;
> +            this.endNode = endNode;
> +        }
> +
> +        /**
> +         * @return
> +         * @see org.neo4j.api.core.Relationship#getId()
> +         */
> +        public long getId()
> +        {
> +            return underlyingRelationship.getId();
> +        }
> +
> +        /**
> +         * @param arg0
> +         * @param arg1
> +         * @return
> +         * @see 
> org.neo4j.api.core.PropertyContainer#getProperty(java.lang.String,
> +         *      java.lang.Object)
> +         */
> +        public Object getProperty( String arg0, Object arg1 )
> +        {
> +            return underlyingRelationship.getProperty( arg0, arg1 );
> +        }
> +
> +        /**
> +         * @param arg0
> +         * @return
> +         * @see 
> org.neo4j.api.core.PropertyContainer#getProperty(java.lang.String)
> +         */
> +        public Object getProperty( String arg0 )
> +        {
> +            return underlyingRelationship.getProperty( arg0 );
> +        }
> +
> +        /**
> +         * @return
> +         * @see org.neo4j.api.core.PropertyContainer#getPropertyKeys()
> +         */
> +        public Iterable<String> getPropertyKeys()
> +        {
> +            return underlyingRelationship.getPropertyKeys();
> +        }
> +
> +        /**
> +         * @return
> +         * @see org.neo4j.api.core.PropertyContainer#getPropertyValues()
> +         */
> +        public Iterable<Object> getPropertyValues()
> +        {
> +            return underlyingRelationship.getPropertyValues();
> +        }
> +
> +        /**
> +         * @return
> +         * @see org.neo4j.api.core.Relationship#getType()
> +         */
> +        public RelationshipType getType()
> +        {
> +            return underlyingRelationship.getType();
> +        }
> +
> +        /**
> +         * @param arg0
> +         * @return
> +         * @see 
> org.neo4j.api.core.PropertyContainer#hasProperty(java.lang.String)
> +         */
> +        public boolean hasProperty( String arg0 )
> +        {
> +            return underlyingRelationship.hasProperty( arg0 );
> +        }
> +
> +        /**
> +         * @param type
> +         * @return
> +         * @see 
> org.neo4j.api.core.Relationship#isType(org.neo4j.api.core.RelationshipType)
> +         */
> +        public boolean isType( RelationshipType type )
> +        {
> +            return underlyingRelationship.isType( type );
> +        }
> +
> +        /**
> +         * @param arg0
> +         * @return
> +         * @see 
> org.neo4j.api.core.PropertyContainer#removeProperty(java.lang.String)
> +         */
> +        public Object removeProperty( String arg0 )
> +        {
> +            return underlyingRelationship.removeProperty( arg0 );
> +        }
> +
> +        /**
> +         * @param arg0
> +         * @param arg1
> +         * @see 
> org.neo4j.api.core.PropertyContainer#setProperty(java.lang.String,
> +         *      java.lang.Object)
> +         */
> +        public void setProperty( String arg0, Object arg1 )
> +        {
> +            underlyingRelationship.setProperty( arg0, arg1 );
> +        }
> +
> +        public void delete()
> +        {
> +            // TODO Auto-generated method stub
> +        }
> +
> +        public Node getEndNode()
> +        {
> +            return endNode;
> +        }
> +
> +        public Node[] getNodes()
> +        {
> +            return new Node[] { startNode, endNode };
> +        }
> +
> +        public Node getOtherNode( Node node )
> +        {
> +            if ( node.equals( startNode ) )
> +            {
> +                return endNode;
> +            }
> +            if ( node.equals( endNode ) )
> +            {
> +                return startNode;
> +            }
> +            throw new RuntimeException( "Node[" + node.getId()
> +                + "] not connected to this relationship[" + getId() + "]" );
> +        }
> +
> +        public Node getStartNode()
> +        {
> +            return startNode;
> +        }
> +    }
> +}
>
> _______________________________________________
> Commits mailing list
> [EMAIL PROTECTED]
> https://lists.neo4j.org/mailman/listinfo/commits
>
>



-- 
GTalk:        neubauer.peter
Skype        peter.neubauer
ICQ            18762544
GTalk        neubauer.peter
Phone       +46704 106975
LinkedIn   http://www.linkedin.com/in/neubauer

http://www.neo4j.org     - New Energy for Data - the Graph Database.
http://www.ops4j.org     - New Energy for OSS Communities - Open
Participation Software.
http://www.qi4j.org        - New Energy for Java - Domain Driven Development.
_______________________________________________
Neo mailing list
User@lists.neo4j.org
https://lists.neo4j.org/mailman/listinfo/user

Reply via email to