{
if ( nodeToAdd == null )
{
throw new IllegalArgumentException( "Null node" );
}
Transaction tx = graphDb.beginTx();
try
{
for ( Relationship rel : nodeToAdd.getRelationships( RelTypes.TIMELINE_INSTANCE ) )
{
if ( rel.getProperty( TIMELINE_NAME, "" ).equals( name ) )
{
throw new IllegalArgumentException(
"Node[" + nodeToAdd.getId()
+ "] already connected to Timeline[" + name
+ "]" );
}
}
Relationship rel = underlyingNode.getSingleRelationship(
RelTypes.TIMELINE_NEXT_ENTRY, Direction.INCOMING );
if ( rel == null )
{
// timeline was empty
Node node = createNewTimeNode( timestamp, nodeToAdd );
underlyingNode.createRelationshipTo( node,
RelTypes.TIMELINE_NEXT_ENTRY );
node.createRelationshipTo( underlyingNode,
RelTypes.TIMELINE_NEXT_ENTRY );
firstNode = nodeToAdd;
lastNode = nodeToAdd;
updateNodeAdded( timestamp );
}
else
{
Node previousLast = rel.getStartNode();
long previousTime = (Long) previousLast.getProperty( TIMESTAMP );
if ( timestamp > previousTime )
{
// add it last in chain
Node node = createNewTimeNode( timestamp, nodeToAdd );
rel.delete();
previousLast.createRelationshipTo( node,
RelTypes.TIMELINE_NEXT_ENTRY );
node.createRelationshipTo( underlyingNode,
RelTypes.TIMELINE_NEXT_ENTRY );
lastNode = nodeToAdd;
updateNodeAdded( timestamp );
}
else if ( timestamp == previousTime )
{
Relationship instanceRel = previousLast.createRelationshipTo( nodeToAdd,
RelTypes.TIMELINE_INSTANCE );
instanceRel.setProperty( TIMELINE_NAME, name );
}
else
{
// find where to insert
Iterator<Node> itr = getAllTimeNodesAfter( timestamp ).iterator();
assert itr.hasNext();
Node next = itr.next();
rel = next.getSingleRelationship(
RelTypes.TIMELINE_NEXT_ENTRY, Direction.INCOMING );
assert rel != null;
Node previous = rel.getStartNode();
long previousTimestamp = Long.MIN_VALUE;
if ( !previous.equals( underlyingNode ) )
{
previousTimestamp = (Long) previous.getProperty( TIMESTAMP );
}
if ( previousTimestamp == timestamp )
{
// just connect previous with node to add
Relationship instanceRel = previous.createRelationshipTo( nodeToAdd,
RelTypes.TIMELINE_INSTANCE );
instanceRel.setProperty( TIMELINE_NAME, name );
return;
}
long nextTimestamp = (Long) next.getProperty( TIMESTAMP );
if ( nextTimestamp == timestamp )
{
// just connect next with node to add
Relationship instanceRel = next.createRelationshipTo( nodeToAdd,
RelTypes.TIMELINE_INSTANCE );
instanceRel.setProperty( TIMELINE_NAME, name );
return;
}
assert previousTimestamp < timestamp;
assert nextTimestamp > timestamp;
Node node = createNewTimeNode( timestamp, nodeToAdd );
rel.delete();
previous.createRelationshipTo( node,
RelTypes.TIMELINE_NEXT_ENTRY );
node.createRelationshipTo( next,
RelTypes.TIMELINE_NEXT_ENTRY );
if ( previous.equals( underlyingNode ) )
{
firstNode = nodeToAdd;
}
updateNodeAdded( timestamp );
}
}
tx.success();
}
finally
{
tx.finish();
}
}