package org.neo4j.util;
import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.kernel.impl.transaction.IllegalResourceException;
public abstract class AbstractLink<T> implements Link<T>
{
private final Node node;
private final RelationshipType type;
private final Direction direction;
public AbstractLink( Node node, RelationshipType type,
Direction direction )
{
this.node = node;
this.type = type;
this.direction = direction;
}
public AbstractLink( Node node, RelationshipType type )
{
this( node, type, Direction.OUTGOING );
}
protected Node node()
{
return this.node;
}
protected Direction direction()
{
return this.direction;
}
protected RelationshipType type()
{
return this.type;
}
protected abstract T newObject( Node node );
private T newObject( Relationship relationship )
{
return newObject( relationship.getOtherNode( this.node ) );
}
protected abstract Node getNodeFromItem( T item );
protected Relationship getLinkRelationshipOrNull()
{
return this.node.getSingleRelationship( this.type(),
this.direction() );
}
public T get()
{
Relationship relationship = getLinkRelationshipOrNull();
return relationship == null ? null : newObject( relationship );
}
public boolean has()
{
return getLinkRelationshipOrNull() != null;
}
public T remove()
{
Relationship relationship = getLinkRelationshipOrNull();
T result = null;
if ( relationship != null )
{
result = newObject( relationship );
entityRemoved( result, relationship );
relationship.delete();
}
return result;
}
public T set( T object )
{
GraphDatabaseUtil.acquireWriteLock( node );
try
{
Relationship existingRelationship = getLinkRelationshipOrNull();
T existingObject = null;
if ( existingRelationship != null )
{
existingObject = newObject( existingRelationship );
entityRemoved( existingObject, existingRelationship );
existingRelationship.delete();
}
Node entityNode = getNodeFromItem( object );
Node startNode = this.direction() == Direction.OUTGOING ?
this.node() : entityNode;
Node endNode = this.direction() == Direction.OUTGOING ?
entityNode : this.node();
Relationship createdRelationship =
startNode.createRelationshipTo( endNode, this.type() );
entitySet( object, createdRelationship );
return existingObject;
}
catch ( IllegalResourceException e )
{
throw new RuntimeException( e );
}
}
protected void entitySet( T entity, Relationship createdRelationship )
{
}
protected void entityRemoved( T entity, Relationship removedRelationship )
{
}
}