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 }