    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.socnet;
    20
    21  import static org.neo4j.examples.socnet.RelTypes.A_PERSON;
    22  import static org.neo4j.examples.socnet.RelTypes.REF_PERSONS;
    23
    24  import org.neo4j.graphdb.Direction;
    25  import org.neo4j.graphdb.GraphDatabaseService;
    26  import org.neo4j.graphdb.Node;
    27  import org.neo4j.graphdb.Relationship;
    28  import org.neo4j.graphdb.Transaction;
    29  import org.neo4j.graphdb.index.Index;
    30  import org.neo4j.helpers.collection.IterableWrapper;
    31
    32  public class PersonRepository
    33  {
    34      private final GraphDatabaseService graphDb;
    35      private final Index<Node> index;
    36      private final Node personRefNode;
    37
    38      public PersonRepository( GraphDatabaseService graphDb, Index<Node> index )
    39      {
    40          this.graphDb = graphDb;
    41          this.index = index;
    42
    43          personRefNode = getPersonsRootNode( graphDb );
    44      }
    45
    46      private Node getPersonsRootNode( GraphDatabaseService graphDb )
    47      {
    48          Relationship rel = graphDb.getReferenceNode().getSingleRelationship(
    49                  REF_PERSONS, Direction.OUTGOING );
    50          if ( rel != null )
    51          {
    52              return rel.getEndNode();
    53          } else
    54          {
    55              Transaction tx = this.graphDb.beginTx();
    56              try
    57              {
    58                  Node refNode = this.graphDb.createNode();
    59                  this.graphDb.getReferenceNode().createRelationshipTo( refNode,
    60                          REF_PERSONS );
    61                  tx.success();
    62                  return refNode;
    63              }
    64              finally
    65              {
    66                  tx.finish();
    67              }
    68          }
    69      }
    70
    71      public Person createPerson( String name ) throws Exception
    72      {
    73          // to guard against duplications we use the lock grabbed on ref node
    74          // when
    75          // creating a relationship and are optimistic about person not existing
    76          Transaction tx = graphDb.beginTx();
    77          try
    78          {
    79              Node newPersonNode = graphDb.createNode();
    80              personRefNode.createRelationshipTo( newPersonNode, A_PERSON );
    81              // lock now taken, we can check if  already exist in index
    82              Node alreadyExist = index.get( Person.NAME, name ).getSingle();
    83              if ( alreadyExist != null )
    84              {
    85                  tx.failure();
    86                  throw new Exception( "Person with this name already exists " );
    87              }
    88              newPersonNode.setProperty( Person.NAME, name );
    89              index.add( newPersonNode, Person.NAME, name );
    90              tx.success();
    91              return new Person( newPersonNode );
    92          }
    93          finally
    94          {
    95              tx.finish();
    96          }
    97      }
    98
    99      public Person getPersonByName( String name )
    100     {
    101         Node personNode = index.get( Person.NAME, name ).getSingle();
    102         if ( personNode == null )
    103         {
    104             throw new IllegalArgumentException( "Person[" + name
    105                     + "] not found" );
    106         }
    107         return new Person( personNode );
    108     }
    109
    110     public void deletePerson( Person person )
    111     {
    112         Transaction tx = graphDb.beginTx();
    113         try
    114         {
    115             Node personNode = person.getUnderlyingNode();
    116             index.remove( personNode, Person.NAME, person.getName() );
    117             for ( Person friend : person.getFriends() )
    118             {
    119                 person.removeFriend( friend );
    120             }
    121             personNode.getSingleRelationship( A_PERSON, Direction.INCOMING ).delete();
    122
    123             for ( StatusUpdate status : person.getStatus() )
    124             {
    125                 Node statusNode = status.getUnderlyingNode();
    126                 for ( Relationship r : statusNode.getRelationships() )
    127                 {
    128                     r.delete();
    129                 }
    130                 statusNode.delete();
    131             }
    132
    133             personNode.delete();
    134             tx.success();
    135         }
    136         finally
    137         {
    138             tx.finish();
    139         }
    140     }
    141
    142     public Iterable<Person> getAllPersons()
    143     {
    144         return new IterableWrapper<Person, Relationship>(
    145                 personRefNode.getRelationships( A_PERSON ) )
    146         {
    147             @Override
    148             protected Person underlyingObjectToObject( Relationship personRel )
    149             {
    150                 return new Person( personRel.getEndNode() );
    151             }
    152         };
    153     }
    154 }