fr.mby.opa.picsimpl.dao.DbProposalDao.java Source code

Java tutorial

Introduction

Here is the source code for fr.mby.opa.picsimpl.dao.DbProposalDao.java

Source

/**
 * Copyright 2013 Maxime Bossard
 *
 * 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.
 */

package fr.mby.opa.picsimpl.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.LockModeType;
import javax.persistence.PersistenceException;
import javax.persistence.Query;

import org.springframework.stereotype.Repository;
import org.springframework.util.Assert;

import com.google.common.collect.Iterables;

import fr.mby.opa.pics.dao.IProposalDao;
import fr.mby.opa.pics.exception.ProposalBagCommitedException;
import fr.mby.opa.pics.exception.ProposalBagNotFoundException;
import fr.mby.opa.pics.exception.ProposalBranchNotFoundException;
import fr.mby.opa.pics.model.AbstractUnitProposal;
import fr.mby.opa.pics.model.ProposalBag;
import fr.mby.opa.pics.model.ProposalBranch;
import fr.mby.utils.common.jpa.EmCallback;
import fr.mby.utils.common.jpa.TxCallback;
import fr.mby.utils.common.jpa.TxCallbackReturn;

/**
 * @author Maxime Bossard - 2013
 * 
 */
@Repository
public class DbProposalDao extends AbstractPicsDao implements IProposalDao {

    /** Page size used for pagination. */
    protected static final int PAGINATION_SIZE = 50;

    @Override
    public ProposalBranch createBranch(final ProposalBranch branch) {
        Assert.notNull(branch, "No ProposalBag supplied !");
        Assert.isNull(branch.getId(), "Id should not be set for creation !");

        new TxCallback(this.getEmf()) {

            @Override
            protected void executeInTransaction(final EntityManager em) {
                em.persist(branch);
            }
        };

        return branch;
    }

    @Override
    public ProposalBranch forkBranch(final ProposalBranch fork, final long branchToForkId) {
        Assert.notNull(fork, "No ProposalBag supplied !");
        Assert.isNull(fork.getId(), "Id should not be set for creation !");

        // Duplicate the branch to Fork
        new TxCallback(this.getEmf()) {

            @Override
            @SuppressWarnings("unchecked")
            protected void executeInTransaction(final EntityManager em) {
                final Query loadFullBranchQuery = em.createNamedQuery(ProposalBranch.LOAD_FULL_BRANCH);
                loadFullBranchQuery.setParameter("branchId", branchToForkId);
                final ProposalBranch branchToFork = Iterables.getFirst(loadFullBranchQuery.getResultList(), null);
                if (branchToFork == null) {
                    throw new ProposalBranchNotFoundException();
                }

                fork.setBags(branchToFork.getBags());
                em.persist(fork);
            }
        };

        return fork;
    }

    @Override
    public ProposalBranch updateBranch(final ProposalBranch branch) {
        Assert.notNull(branch, "No ProposalBag supplied !");
        Assert.notNull(branch.getId(), "Id should be set for update !");

        final TxCallbackReturn<ProposalBranch> txCallback = new TxCallbackReturn<ProposalBranch>(this.getEmf()) {

            @Override
            protected ProposalBranch executeInTransaction(final EntityManager em) {
                final ProposalBranch updatedBranch = em.merge(branch);
                em.flush();
                em.refresh(updatedBranch);
                return updatedBranch;
            }
        };

        final ProposalBranch updatedBag = txCallback.getReturnedValue();
        return updatedBag;
    }

    @Override
    public ProposalBranch findBranch(final long branchId) {
        final EmCallback<ProposalBranch> emCallback = new EmCallback<ProposalBranch>(this.getEmf()) {

            @Override
            protected ProposalBranch executeWithEntityManager(final EntityManager em) throws PersistenceException {

                return em.find(ProposalBranch.class, branchId);
            }
        };

        return emCallback.getReturnedValue();
    }

    @Override
    public ProposalBranch findBranchByName(final long albumId, final String name) {
        final EmCallback<ProposalBranch> emCallback = new EmCallback<ProposalBranch>(this.getEmf()) {

            @Override
            @SuppressWarnings("unchecked")
            protected ProposalBranch executeWithEntityManager(final EntityManager em) throws PersistenceException {
                final Query findBranchByNameQuery = em.createNamedQuery(ProposalBranch.FIND_BRANCH_BY_NAME);
                findBranchByNameQuery.setParameter("albumId", albumId);
                findBranchByNameQuery.setParameter("name", name);

                final ProposalBranch bag = Iterables.getFirst(findBranchByNameQuery.getResultList(), null);
                return bag;
            }
        };

        return emCallback.getReturnedValue();
    }

    @Override
    public ProposalBag createBag(final ProposalBag bag, final long branchId) {
        Assert.notNull(bag, "No ProposalBag supplied !");
        Assert.isNull(bag.getId(), "Id should not be set for creation !");

        new TxCallback(this.getEmf()) {

            @Override
            // @SuppressWarnings("unchecked")
            protected void executeInTransaction(final EntityManager em) {
                // Retrieve branch
                final ProposalBranch branch = em.find(ProposalBranch.class, branchId,
                        LockModeType.PESSIMISTIC_WRITE);
                if (branch == null) {
                    throw new ProposalBranchNotFoundException();
                }

                // Retrieve base bag (parent bag) and lock the row
                // final Query findParentQuery = em.createNamedQuery(ProposalBag.FIND_LAST_BRANCH_BAG);
                // findParentQuery.setParameter("branchId", branchId);
                // findParentQuery.setLockMode(LockModeType.PESSIMISTIC_WRITE);

                // Persist bag with its parent
                // final ProposalBag parentBag = Iterables.getFirst(findParentQuery.getResultList(), null);
                // bag.setBaseProposal(parentBag);
                // em.persist(bag);

                // Persist bag with its parent
                bag.setBaseProposal(branch.getHead());
                em.persist(bag);

                // Update branch head pointer
                branch.setHead(bag);
                em.merge(branch);
            }
        };

        return bag;
    }

    @Override
    public ProposalBag updateBag(final ProposalBag bag)
            throws ProposalBagNotFoundException, ProposalBagCommitedException {
        Assert.notNull(bag, "No ProposalBag supplied !");
        Assert.notNull(bag.getId(), "Id should be set for update !");

        if (bag.isCommited()) {
            throw new ProposalBagCommitedException();
        }

        return this._updateProposalBagInternal(bag);
    }

    @Override
    public ProposalBag commitBag(final ProposalBag bag)
            throws ProposalBagNotFoundException, ProposalBagCommitedException {
        Assert.notNull(bag, "No ProposalBag supplied !");
        if (bag.isCommited()) {
            throw new ProposalBagCommitedException();
        }

        this._checkProposalBagIntegrity(bag);

        bag.setCommited(true);

        return this._updateProposalBagInternal(bag);
    }

    // @Override
    public AbstractUnitProposal createProposal(final AbstractUnitProposal proposal) {
        Assert.notNull(proposal, "No Proposal supplied !");
        Assert.isNull(proposal.getId(), "Id should not be set for creation !");

        new TxCallback(this.getEmf()) {

            @Override
            protected void executeInTransaction(final EntityManager em) {
                em.persist(proposal);
            }
        };

        return proposal;
    }

    @Override
    public ProposalBag findBag(final long bagId) {
        final EmCallback<ProposalBag> emCallback = new EmCallback<ProposalBag>(this.getEmf()) {

            @Override
            protected ProposalBag executeWithEntityManager(final EntityManager em) throws PersistenceException {
                final ProposalBag bag = em.find(ProposalBag.class, bagId);
                return bag;
            }
        };

        return emCallback.getReturnedValue();
    }

    @Override
    public ProposalBag findLastBag(final long albumId) {
        final EmCallback<ProposalBag> emCallback = new EmCallback<ProposalBag>(this.getEmf()) {

            @Override
            @SuppressWarnings("unchecked")
            protected ProposalBag executeWithEntityManager(final EntityManager em) throws PersistenceException {
                final Query findLastBagQuery = em.createNamedQuery(ProposalBag.FIND_LAST_ALBUM_BAG);
                findLastBagQuery.setParameter("albumId", albumId);
                findLastBagQuery.setMaxResults(1);

                final ProposalBag bag = Iterables.getFirst(findLastBagQuery.getResultList(), null);
                return bag;
            }
        };

        return emCallback.getReturnedValue();
    }

    @Override
    public List<ProposalBranch> findAllBranches(final long albumId) {
        final EmCallback<List<ProposalBranch>> emCallback = new EmCallback<List<ProposalBranch>>(this.getEmf()) {

            @Override
            @SuppressWarnings("unchecked")
            protected List<ProposalBranch> executeWithEntityManager(final EntityManager em)
                    throws PersistenceException {
                final Query findLastBagQuery = em.createNamedQuery(ProposalBranch.FIND_BRANCHES_OF_ALBUM);
                findLastBagQuery.setParameter("albumId", albumId);

                final List<ProposalBranch> branches = findLastBagQuery.getResultList();
                return branches;
            }
        };

        return emCallback.getReturnedValue();
    }

    @Override
    public List<ProposalBag> findBagAncestry(final long branchId, final long until) {
        final EmCallback<List<ProposalBag>> emCallback = new EmCallback<List<ProposalBag>>(this.getEmf()) {

            @Override
            @SuppressWarnings("unchecked")
            protected List<ProposalBag> executeWithEntityManager(final EntityManager em)
                    throws PersistenceException {
                final Query findLastBagQuery = em.createNamedQuery(ProposalBag.FIND_BRANCH_BAGS_UNTIL);
                findLastBagQuery.setParameter("branchId", branchId);
                findLastBagQuery.setParameter("until", until);
                findLastBagQuery.setMaxResults(DbProposalDao.PAGINATION_SIZE);

                final List<ProposalBag> branches = findLastBagQuery.getResultList();
                return branches;
            }
        };

        return emCallback.getReturnedValue();
    }

    /**
     * @param proposalBag
     */
    protected void _checkProposalBagIntegrity(final ProposalBag proposalBag) {
        // TODO Auto-generated method stub

    }

    /**
     * @param proposalBag
     * @return
     */
    protected ProposalBag _updateProposalBagInternal(final ProposalBag proposalBag) {
        final TxCallbackReturn<ProposalBag> txCallback = new TxCallbackReturn<ProposalBag>(this.getEmf()) {

            @Override
            protected ProposalBag executeInTransaction(final EntityManager em) {
                final ProposalBag updatedBag = em.merge(proposalBag);
                em.flush();
                em.refresh(updatedBag);
                return updatedBag;
            }
        };

        final ProposalBag updatedBag = txCallback.getReturnedValue();
        return updatedBag;
    }

}