    1   /**
    2    * Licensed to Neo Technology under one or more contributor
    3    * license agreements. See the NOTICE file distributed with
    4    * this work for additional information regarding copyright
    5    * ownership. Neo Technology licenses this file to you under
    6    * the Apache License, Version 2.0 (the "License"); you may
    7    * not use this file except in compliance with the License.
    8    * You may obtain a copy of the License at
    9    *
    10   * http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing,
    13   * software distributed under the License is distributed on an
    14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    15   * KIND, either express or implied. See the License for the
    16   * specific language governing permissions and limitations
    17   * under the License.
    18   */
    19  package org.neo4j.examples;
    20
    21  import java.io.File;
    22
    23  import org.neo4j.graphalgo.GraphAlgoFactory;
    24  import org.neo4j.graphalgo.PathFinder;
    25  import org.neo4j.graphdb.Direction;
    26  import org.neo4j.graphdb.DynamicRelationshipType;
    27  import org.neo4j.graphdb.GraphDatabaseService;
    28  import org.neo4j.graphdb.Node;
    29  import org.neo4j.graphdb.Path;
    30  import org.neo4j.graphdb.RelationshipType;
    31  import org.neo4j.graphdb.Transaction;
    32  import org.neo4j.graphdb.index.Index;
    33  import org.neo4j.kernel.EmbeddedGraphDatabase;
    34  import org.neo4j.kernel.Traversal;
    35
    36  public class CalculateShortestPath
    37  {
    38      private static final String DB_PATH = "neo4j-shortest-path";
    39      private static final String NAME_KEY = "name";
    40      private static RelationshipType KNOWS = DynamicRelationshipType.withName( "KNOWS" );
    41
    42      private static GraphDatabaseService graphDb;
    43      private static Index<Node> indexService;
    44
    45      public static void main( final String[] args )
    46      {
    47          deleteFileOrDirectory( new File( DB_PATH ) );
    48          graphDb = new EmbeddedGraphDatabase( DB_PATH );
    49          indexService = graphDb.index().forNodes( "nodes" );
    50          registerShutdownHook();
    51          Transaction tx = graphDb.beginTx();
    52          try
    53          {
    54              /*
    55               *  (Neo) --> (Trinity)
    56               *     \       ^
    57               *      v     /
    58               *    (Morpheus) --> (Cypher)
    59               *            \         |
    60               *             v        v
    61               *            (Agent Smith)
    62               */
    63              createChain( "Neo", "Trinity" );
    64              createChain( "Neo", "Morpheus", "Trinity" );
    65              createChain( "Morpheus", "Cypher", "Agent Smith" );
    66              createChain( "Morpheus", "Agent Smith" );
    67              tx.success();
    68          }
    69          finally
    70          {
    71              tx.finish();
    72          }
    73
    74          // So let's find the shortest path between Neo and Agent Smith
    75          Node neo = getOrCreateNode( "Neo" );
    76          Node agentSmith = getOrCreateNode( "Agent Smith" );
    77          // START SNIPPET: shortestPathUsage
    78          PathFinder<Path> finder = GraphAlgoFactory.shortestPath(
    79                  Traversal.expanderForTypes( KNOWS, Direction.BOTH ), 4 );
    80          Path foundPath = finder.findSinglePath( neo, agentSmith );
    81          System.out.println( "Path from Neo to Agent Smith: "
    82                              + Traversal.simplePathToString( foundPath, NAME_KEY ) );
    83          // END SNIPPET: shortestPathUsage
    84
    85          System.out.println( "Shutting down database ..." );
    86          graphDb.shutdown();
    87      }
    88
    89      private static void createChain( String... names )
    90      {
    91          for ( int i = 0; i < names.length - 1; i++ )
    92          {
    93              Node firstNode = getOrCreateNode( names[i] );
    94              Node secondNode = getOrCreateNode( names[i + 1] );
    95              firstNode.createRelationshipTo( secondNode, KNOWS );
    96          }
    97      }
    98
    99      private static Node getOrCreateNode( String name )
    100     {
    101         Node node = indexService.get( NAME_KEY, name ).getSingle();
    102         if ( node == null )
    103         {
    104             node = graphDb.createNode();
    105             node.setProperty( NAME_KEY, name );
    106             indexService.add( node, NAME_KEY, name );
    107         }
    108         return node;
    109     }
    110
    111     private static void registerShutdownHook()
    112     {
    113         // Registers a shutdown hook for the Neo4j instance so that it
    114         // shuts down nicely when the VM exits (even if you "Ctrl-C" the
    115         // running example before it's completed)
    116         Runtime.getRuntime().addShutdownHook( new Thread()
    117         {
    118             @Override
    119             public void run()
    120             {
    121                 graphDb.shutdown();
    122             }
    123         } );
    124     }
    125
    126     private static void deleteFileOrDirectory( File file )
    127     {
    128         if ( file.exists() )
    129         {
    130             if ( file.isDirectory() )
    131             {
    132                 for ( File child : file.listFiles() )
    133                 {
    134                     deleteFileOrDirectory( child );
    135                 }
    136             }
    137             file.delete();
    138         }
    139     }
    140 }