package org.neo4j.kernel.impl.core;
import javax.transaction.TransactionManager;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.TransactionFailureException;
import org.neo4j.kernel.impl.nioneo.store.RelationshipTypeData;
import org.neo4j.kernel.impl.persistence.EntityIdGenerator;
import org.neo4j.kernel.impl.persistence.PersistenceManager;
public class DefaultRelationshipTypeCreator implements RelationshipTypeCreator
{
public int getOrCreate( TransactionManager txManager, EntityIdGenerator idGenerator,
PersistenceManager persistence, RelationshipTypeHolder relTypeHolder, String name )
{
RelTypeCreater createrThread = new RelTypeCreater( name, txManager, idGenerator,
persistence );
synchronized ( createrThread )
{
createrThread.start();
while ( createrThread.isAlive() )
{
try
{
createrThread.wait( 50 );
}
catch ( InterruptedException e )
{
Thread.interrupted();
}
}
}
if ( createrThread.succeded() )
{
int id = createrThread.getRelTypeId();
relTypeHolder.addRawRelationshipType( new RelationshipTypeData( id, name ) );
return id;
}
throw new TransactionFailureException(
"Unable to create relationship type " + name );
}
// TODO: this should be fixed to run in same thread
private static class RelTypeCreater extends Thread
{
private boolean success = false;
private String name;
private int id = -1;
private final TransactionManager txManager;
private final PersistenceManager persistence;
private final EntityIdGenerator idGenerator;
RelTypeCreater( String name, TransactionManager txManager, EntityIdGenerator idGenerator,
PersistenceManager persistence )
{
super();
this.name = name;
this.txManager = txManager;
this.idGenerator = idGenerator;
this.persistence = persistence;
}
synchronized boolean succeded()
{
return success;
}
synchronized int getRelTypeId()
{
return id;
}
public synchronized void run()
{
try
{
txManager.begin();
id = idGenerator.nextId( RelationshipType.class );
persistence.createRelationshipType( id, name );
txManager.commit();
success = true;
}
catch ( Throwable t )
{
t.printStackTrace();
try
{
txManager.rollback();
}
catch ( Throwable tt )
{
tt.printStackTrace();
}
}
finally
{
this.notify();
}
}
}
}