org.wisdom.api.model.FluentTransaction Maven / Gradle / Ivy
/*
* #%L
* Wisdom-Framework
* %%
* Copyright (C) 2013 - 2014 Wisdom Framework
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package org.wisdom.api.model;
import java.util.concurrent.Callable;
/**
* A FluentTransaction ease the creation of database transaction linked with a {@link Crud} service.
*
* The fluent transaction use a {@link TransactionManager} in order to run the transaction.
* The fluent requires a {@link Callable}, that will be the code block to be run in the transaction as well as a
* {@link RolledBackHandler} that will be call if the transaction has been rollback.
*
* An optional {@link CommittedHandler} that will be call on successful commit is also supported.
*
* {@code
* Grammar ::= 'transaction(' TransactionManager ')'
* '.with(' Callable ')'
* '.onRolledBack(' RolledBackHandler ')'
* ( '.onCommitted(' CommittedHandler ')' )?
* '.execute()
* }
*
* @param the return type of the transaction block.
* @author barjo
*/
public final class FluentTransaction {
private Callable txContent;
private RolledBackHandler txOnRolledBack;
private CommittedHandler txOnCommitted = null;
private final TransactionManager txManager;
/**
* Create a new FluentTransaction
* @param txManager The {@link TransactionManager} used to manage the transaction,begin,commit,rollback.
*/
private FluentTransaction(TransactionManager txManager) {
this.txManager = txManager;
}
/**
* Create a new FluentTransaction
* @param txManager The {@link TransactionManager} used to manage the transaction,begin,commit,rollback.
*/
public static FluentTransaction transaction(TransactionManager txManager){
return new FluentTransaction<>(txManager);
}
/**
* @return The {@link TransactionManager} used by this FluentTransaction.
*/
public TransactionManager getTransactionManager(){
return txManager;
}
/**
* The block that will be executed in a transaction.
*
* @param content The transaction block.
* @return Intermediate, This FluentTransaction with the transaction block defined.
*/
public Intermediate with(Callable content){
txContent = content;
return new Intermediate();
}
/**
* The Intermediate FluentTransaction contains the content of the transaction but does not have a defined
* {@link RolledBackHandler} yet.
*/
public final class Intermediate {
private Intermediate(){}
/**
* Set the {@link RolledBackHandler} that will be call if the transaction block failed and has been rollback.
* @param rollcall The {@link RolledBackHandler} that will be call
* @return OptionalIntermediate, This FluentTransaction that can be executed.
*/
public OptionalIntermediate onRolledBack(RolledBackHandler rollcall){
txOnRolledBack = rollcall;
return new OptionalIntermediate();
}
}
/**
* The OptionalIntermediate FluentTransaction has a content and a {@link RolledBackHandler} set, it can be executed.
* An optional {@link CommittedHandler} can be set too.
*/
public final class OptionalIntermediate extends Ready {
private OptionalIntermediate(){}
/**
* Set the optional {@link CommittedHandler} handler that will be call if this FluentTransaction
* has been properly committed.
* @param onCommitted The {@link CommittedHandler} that will be call on successful commit.
* @return This FluentTransaction ready to be executed.
*/
public Ready onCommitted(CommittedHandler onCommitted){
txOnCommitted = onCommitted;
return new Ready();
}
}
/**
* The FluentTransaction.Ready is ready to be executed.
*/
public class Ready {
private Ready(){}
/**
* Execute the transaction.
* @throws InitTransactionException if A problem occurred while the transaction is initiated.
* @throws RollBackHasCauseAnException if A problem occurred while the transaction is being rollback.
*/
public void execute() throws InitTransactionException,RollBackHasCauseAnException {
txManager.begin();
try{
R result = txContent.call();
txManager.commit();
if(txOnCommitted != null){
txOnCommitted.committed(result);
}
}catch (Exception cause){
txManager.rollback();
txOnRolledBack.rolledBack(cause);
} finally {
txManager.close();
}
}
}
}