package org.qi4j.api.unitofwork;
import org.qi4j.api.structure.Module;
import org.qi4j.api.usecase.Usecase;
/**
* UnitOfWork Template.
*/
public abstract class UnitOfWorkTemplate<RESULT, ThrowableType extends Throwable>
{
private Usecase usecase = Usecase.DEFAULT;
private int retries = 10;
private boolean complete = true;
protected UnitOfWorkTemplate()
{
}
protected UnitOfWorkTemplate( int retries, boolean complete )
{
this.retries = retries;
this.complete = complete;
}
protected UnitOfWorkTemplate( Usecase usecase, int retries, boolean complete )
{
this.usecase = usecase;
this.retries = retries;
this.complete = complete;
}
protected abstract RESULT withUnitOfWork( UnitOfWork uow )
throws ThrowableType;
public RESULT withModule( Module module )
throws ThrowableType, UnitOfWorkCompletionException
{
int loop = 0;
ThrowableType ex = null;
do
{
UnitOfWork uow = module.newUnitOfWork( usecase );
try
{
RESULT result = withUnitOfWork( uow );
if( complete )
{
try
{
uow.complete();
return result;
}
catch( ConcurrentEntityModificationException e )
{
// Retry?
ex = (ThrowableType) e;
}
}
}
catch( Throwable e )
{
ex = (ThrowableType) e;
}
finally
{
uow.discard();
}
}
while( loop++ < retries );
throw ex;
}
}