Package org.neo4j.collections.indexedrelationship

Source Code of org.neo4j.collections.indexedrelationship.IndexedRelationshipExpander$RelationshipIterator

/**
* Copyright (c) 2002-2013 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.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 <http://www.gnu.org/licenses/>.
*/
package org.neo4j.collections.indexedrelationship;

import java.util.Iterator;
import java.util.NoSuchElementException;

import org.neo4j.collections.NodeCollection;
import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Path;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.RelationshipExpander;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.traversal.Evaluation;
import org.neo4j.graphdb.traversal.Evaluator;
import org.neo4j.kernel.Traversal;

public class IndexedRelationshipExpander implements RelationshipExpander
{
    private final Direction direction;
    private final RelationshipType relType;
    private final GraphDatabaseService graphDb;

    public IndexedRelationshipExpander( GraphDatabaseService graphDb, Direction direction, RelationshipType relType )
    {
        this.direction = direction;
        this.relType = relType;
        this.graphDb = graphDb;
    }

    class RelationshipIterable implements Iterable<Relationship>
    {
        final Node node;

        RelationshipIterable( Node node )
        {
            this.node = node;
        }

        @Override
        public Iterator<Relationship> iterator()
        {
            return new RelationshipIterator( node, relType, direction );
        }
    }

    class RelationshipIterator implements Iterator<Relationship>
    {
        final Iterator<Relationship> directRelationshipIterator;
        final Iterator<Relationship> indexedRelationshipIterator;
        final Iterator<Path> indexedRelationshipDestinationIterator;

        boolean inIndexedRelationshipIterator = false;

        RelationshipIterator( Node node, final RelationshipType relType, final Direction direction )
        {
            if ( node.hasRelationship( relType, direction ) )
            {
                directRelationshipIterator = node.getRelationships( relType, direction ).iterator();
            }
            else
            {
                directRelationshipIterator = null;
            }

            IndexedRelationship indexedRelationship = new IndexedRelationship( node, relType, direction );
            if ( !indexedRelationship.exists() )
            {
                indexedRelationshipIterator = null;
            }
            else
            {
                indexedRelationshipIterator = indexedRelationship.iterator();
            }

            indexedRelationshipDestinationIterator = Traversal.description().depthFirst()
                .evaluator( new Evaluator()
                {
                    @Override
                    public Evaluation evaluate( Path path )
                    {
                        if ( path.length() == 0 )
                        {
                            return Evaluation.EXCLUDE_AND_CONTINUE;
                        }

                        Relationship relationship = path.lastRelationship();
                        if ( path.length() == 1 )
                        {
                            if ( relationship.getType().name().equals( NodeCollection.RelationshipTypes.VALUE.name() ) ) {
                                String relationshipType = (String) relationship.getProperty(
                                    IndexedRelationship.RELATIONSHIP_TYPE, null );
                                String relationshipDirection = (String) relationship.getProperty(
                                    IndexedRelationship.RELATIONSHIP_DIRECTION, null );

                                if ( relType.name().equals( relationshipType ) &&
                                    direction.reverse().name().equals( relationshipDirection ) )
                                {
                                    return Evaluation.EXCLUDE_AND_CONTINUE;
                                }
                            }

                            return Evaluation.EXCLUDE_AND_PRUNE;
                        }

                        if ( relationship.getType().name().equals( IndexedRelationship.RelationshipTypes.NODE_COLLECTION.name() ) )
                        {
                            return Evaluation.INCLUDE_AND_PRUNE;
                        }
                       
                        return Evaluation.EXCLUDE_AND_CONTINUE;
                    }
                } ).traverse( node ).iterator();
        }

        @Override
        public boolean hasNext()
        {
            if ( directRelationshipIterator != null && directRelationshipIterator.hasNext() )
            {
                return true;
            }
            if ( indexedRelationshipIterator != null && indexedRelationshipIterator.hasNext() )
            {
                return true;
            }
            if ( indexedRelationshipDestinationIterator != null && indexedRelationshipDestinationIterator.hasNext() )
            {
                return true;
            }
            return false;
        }

        @Override
        public Relationship next()
        {
            if ( directRelationshipIterator != null && directRelationshipIterator.hasNext() )
            {
                return directRelationshipIterator.next();
            }
            if ( indexedRelationshipIterator != null && indexedRelationshipIterator.hasNext() )
            {
                return indexedRelationshipIterator.next();
            }
            if ( indexedRelationshipDestinationIterator != null && indexedRelationshipDestinationIterator.hasNext() )
            {
                Path path = indexedRelationshipDestinationIterator.next();
                String direction = (String) path.lastRelationship().getProperty(
                    IndexedRelationship.RELATIONSHIP_DIRECTION );
                try
                {
                    IndexedRelationship indexedRelationship = new IndexedRelationship( path.endNode(), relType,
                        Direction.valueOf( direction ) );
                    return indexedRelationship.getRelationship( path.relationships().iterator().next() );
                }
                catch ( Exception e )
                {
                    throw new RuntimeException( "Comparator class cannot be instantiated" );
                }
            }
            throw new NoSuchElementException();
        }

        @Override
        public void remove()
        {
            if ( directRelationshipIterator != null && !inIndexedRelationshipIterator )
            {
                directRelationshipIterator.remove();
            }
            else
            {
                if ( indexedRelationshipIterator != null )
                {
                    indexedRelationshipIterator.remove();
                }
            }
        }
    }

    @Override
    public Iterable<Relationship> expand( Node node )
    {
        return new RelationshipIterable( node );
    }

    @Override
    public RelationshipExpander reversed()
    {
        return new IndexedRelationshipExpander( graphDb, direction.reverse(), relType );
    }
}
TOP

Related Classes of org.neo4j.collections.indexedrelationship.IndexedRelationshipExpander$RelationshipIterator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.