All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.wisdom.api.model.FluentTransaction Maven / Gradle / Ivy

The newest version!
/*
 * #%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();
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy