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  
20  package org.neo4j.examples;
21  
22  import java.io.File;
23  
24  import org.junit.AfterClass;
25  import org.junit.BeforeClass;
26  import org.junit.Test;
27  import org.neo4j.graphdb.Direction;
28  import org.neo4j.graphdb.GraphDatabaseService;
29  import org.neo4j.graphdb.Node;
30  import org.neo4j.graphdb.Path;
31  import org.neo4j.graphdb.RelationshipType;
32  import org.neo4j.graphdb.Transaction;
33  import org.neo4j.graphdb.index.Index;
34  import org.neo4j.graphdb.traversal.TraversalDescription;
35  import org.neo4j.helpers.Predicate;
36  import org.neo4j.kernel.EmbeddedGraphDatabase;
37  import org.neo4j.kernel.Traversal;
38  
39  public class RolesTest
40  {
41      private static final String GROUP = "group";
42      private static final String USER = "user";
43      private static final String NAME = "name";
44  
45      public enum RoleRels implements RelationshipType
46      {
47          ROOT,
48          PART_OF,
49          MEMBER_OF;
50      }
51  
52      private static final String ROLES_DB = "target/roles-db";
53      private static GraphDatabaseService graphDb;
54      private static Index<Node> index;
55  
56      @BeforeClass
57      public static void setUp()
58      {
59          deleteFileOrDirectory( new File( ROLES_DB ) );
60          graphDb = new EmbeddedGraphDatabase( ROLES_DB );
61          index = graphDb.index().forNodes( "nodes" );
62          registerShutdownHook();
63          createNodespace();
64      }
65  
66      @AfterClass
67      public static void tearDown()
68      {
69          graphDb.shutdown();
70      }
71  
72      private static void createNodespace()
73      {
74          Transaction tx = graphDb.beginTx();
75          try
76          {
77              // add the top level groups
78              Node admins = createTopLevelGroup( "Admins" );
79              Node users = createTopLevelGroup( "Users" );
80  
81              // add other groups
82              Node helpDesk = createGroup( "HelpDesk", admins );
83              Node managers = createGroup( "Managers", users );
84              Node technicians = createGroup( "Technicians", users );
85              Node abcTechnicians = createGroup( "ABCTechnicians", technicians );
86  
87              // add the users
88              createUser( "Ali", admins, users );
89              createUser( "Burcu", users );
90              createUser( "Can", users );
91              createUser( "Demet", helpDesk );
92              createUser( "Engin", helpDesk, users );
93              createUser( "Fuat", managers );
94              createUser( "Gul", managers );
95              createUser( "Hakan", technicians );
96              createUser( "Irmak", technicians );
97              createUser( "Jale", abcTechnicians );
98  
99              tx.success();
100         }
101         finally
102         {
103             tx.finish();
104         }
105     }
106 
107     public static void createRoles()
108     {
109         Transaction tx = graphDb.beginTx();
110         try
111         {
112             tx.success();
113         }
114         finally
115         {
116             tx.finish();
117         }
118     }
119 
120     private static Node createTopLevelGroup( final String name )
121     {
122         return createNode( name, RoleRels.ROOT, GROUP,
123                 graphDb.getReferenceNode() );
124     }
125 
126     private static Node createGroup( final String name,
127             final Node... containedIn )
128     {
129         return createNode( name, RoleRels.PART_OF, GROUP, containedIn );
130     }
131 
132     private static Node createUser( final String name,
133             final Node... containedIn )
134     {
135         return createNode( name, RoleRels.MEMBER_OF, USER, containedIn );
136     }
137 
138     private static Node createNode( final String name,
139             final RelationshipType relType, final String category,
140             final Node... containedIn )
141     {
142         Node node = graphDb.createNode();
143         node.setProperty( NAME, name );
144         index.add( node, category, name );
145         for ( Node parent : containedIn )
146         {
147             node.createRelationshipTo( parent, relType );
148         }
149         return node;
150     }
151 
152     private static Node getUserByName( final String name )
153     {
154         return getNodeByName( USER, name );
155     }
156 
157     private static Node getGroupByName( String name )
158     {
159         return getNodeByName( GROUP, name );
160     }
161 
162     private static Node getNodeByName( final String category, final String name )
163     {
164         return index.get( category, name ).getSingle();
165     }
166 
167     @Test
168     public void getAllAdmins()
169     {
170         Transaction tx = graphDb.beginTx();
171         try
172         {
173             System.out.println( "All admins:" );
174             // START SNIPPET: get-admins
175             Node admins = getGroupByName( "Admins" );
176             TraversalDescription td = Traversal.description().breadthFirst().relationships(
177                     RoleRels.PART_OF, Direction.INCOMING ).relationships(
178                     RoleRels.MEMBER_OF, Direction.INCOMING ).filter(
179                     Traversal.returnAllButStartNode() );
180             for ( Path path : td.traverse( admins ) )
181             {
182                 Node part = path.endNode();
183                 System.out.println( part.getProperty( NAME )
184                                     + " "
185                                     + ( path.length() - 1 ) );
186             }
187             // END SNIPPET: get-admins
188             tx.success();
189         }
190         finally
191         {
192             tx.finish();
193         }
194     }
195 
196     @Test
197     public void getJalesMemberships() throws Exception
198     {
199         Transaction tx = graphDb.beginTx();
200         try
201         {
202             System.out.println( "Jale's memberships:" );
203             // START SNIPPET: get-user-memberships
204             Node jale = getUserByName( "Jale" );
205             TraversalDescription td = Traversal.description().depthFirst().relationships(
206                     RoleRels.MEMBER_OF, Direction.OUTGOING ).relationships(
207                     RoleRels.PART_OF, Direction.OUTGOING ).filter(
208                     Traversal.returnAllButStartNode() );
209             for ( Path path : td.traverse( jale ) )
210             {
211                 Node membership = path.endNode();
212                 System.out.println( membership.getProperty( NAME )
213                                     + " "
214                                     + ( path.length() - 1 ) );
215             }
216             // END SNIPPET: get-user-memberships
217             tx.success();
218         }
219         finally
220         {
221             tx.finish();
222         }
223     }
224 
225     @Test
226     public void getAllGroups() throws Exception
227     {
228         Transaction tx = graphDb.beginTx();
229         try
230         {
231             System.out.println( "All groups:" );
232             // START SNIPPET: get-groups
233             Node referenceNode = graphDb.getReferenceNode();
234             TraversalDescription td = Traversal.description().breadthFirst().relationships(
235                     RoleRels.ROOT, Direction.INCOMING ).relationships(
236                     RoleRels.PART_OF, Direction.INCOMING ).filter(
237                     Traversal.returnAllButStartNode() );
238             for ( Node group : td.traverse( referenceNode ).nodes() )
239             {
240                 System.out.println( group.getProperty( NAME ) );
241             }
242             // END SNIPPET: get-groups
243             tx.success();
244         }
245         finally
246         {
247             tx.finish();
248         }
249     }
250 
251     @Test
252     public void getAllMembers() throws Exception
253     {
254         Transaction tx = graphDb.beginTx();
255         try
256         {
257             System.out.println( "All members:" );
258             // START SNIPPET: get-members
259             Node referenceNode = graphDb.getReferenceNode();
260             TraversalDescription td = Traversal.description().breadthFirst().relationships(
261                     RoleRels.ROOT, Direction.INCOMING ).relationships(
262                     RoleRels.MEMBER_OF, Direction.INCOMING ).relationships(
263                     RoleRels.PART_OF, Direction.INCOMING ).filter(
264                     new Predicate<Path>()
265                     {
266                         public boolean accept( Path item )
267                         {
268                             if ( item.length() == 0 )
269                             {
270                                 return false;
271                             }
272                             return item.lastRelationship().isType(
273                                     RoleRels.MEMBER_OF );
274                         }
275                     } );
276             for ( Node group : td.traverse( referenceNode ).nodes() )
277             {
278                 System.out.println( group.getProperty( NAME ) );
279             }
280             // END SNIPPET: get-members
281             tx.success();
282         }
283         finally
284         {
285             tx.finish();
286         }
287     }
288 
289     private static void registerShutdownHook()
290     {
291         // Registers a shutdown hook for the Neo4j instance so that it
292         // shuts down nicely when the VM exits (even if you "Ctrl-C" the
293         // running example before it's completed)
294         Runtime.getRuntime().addShutdownHook( new Thread()
295         {
296             @Override
297             public void run()
298             {
299                 graphDb.shutdown();
300             }
301         } );
302     }
303 
304     private static void deleteFileOrDirectory( final File file )
305     {
306         if ( !file.exists() )
307         {
308             return;
309         }
310 
311         if ( file.isDirectory() )
312         {
313             for ( File child : file.listFiles() )
314             {
315                 deleteFileOrDirectory( child );
316             }
317         }
318         else
319         {
320             file.delete();
321         }
322     }
323 }