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

Java tutorial

Introduction

Here is the source code for fr.mby.opa.picsimpl.dao.DbPictureDao.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.sql.Timestamp;
import java.util.Collections;
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.IPictureDao;
import fr.mby.opa.pics.exception.PictureAlreadyExistsException;
import fr.mby.opa.pics.exception.PictureNotFoundException;
import fr.mby.opa.pics.model.Album;
import fr.mby.opa.pics.model.BinaryImage;
import fr.mby.opa.pics.model.Picture;
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 DbPictureDao extends AbstractPicsDao implements IPictureDao {

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

    @Override
    public Picture createPicture(final Picture picture, final Album album) throws PictureAlreadyExistsException {
        Assert.notNull(picture, "No Picture supplied !");
        Assert.notNull(album, "No Album supplied !");
        Assert.isNull(picture.getId(), "Id should not be set for creation !");

        picture.setAlbum(album);

        new TxCallback(this.getEmf()) {

            @Override
            protected void executeInTransaction(final EntityManager em) {
                DbPictureDao.this.testHashUniqueness(picture, em);
                em.persist(picture);
            }
        };

        return picture;
    }

    @Override
    public Picture updatePicture(final Picture picture) throws PictureNotFoundException {
        Assert.notNull(picture, "No Picture supplied !");
        Assert.notNull(picture.getId(), "Id should be set for update !");

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

            @Override
            protected Picture executeInTransaction(final EntityManager em) {
                final Picture updatedPicture = em.merge(picture);
                em.flush();
                em.refresh(updatedPicture);
                return updatedPicture;
            }
        };

        final Picture updatedPicture = txCallback.getReturnedValue();

        return updatedPicture;
    }

    @Override
    public void deletePicture(final Picture picture) throws PictureNotFoundException {
        Assert.notNull(picture, "No Picture supplied !");
        Assert.notNull(picture.getId(), "Id should be set for delete !");

        new TxCallback(this.getEmf()) {

            @Override
            protected void executeInTransaction(final EntityManager em) {
                final Picture managedPicture = em.find(Picture.class, picture.getId(), LockModeType.WRITE);
                if (managedPicture == null) {
                    throw new PictureNotFoundException();
                }

                em.remove(picture);
                em.lock(picture, LockModeType.NONE);
            }
        };
    }

    @Override
    public List<Picture> findPicturesByAlbumId(final Long albumId, final Long since) {
        Assert.notNull(albumId, "Album Id should be supplied !");
        final Timestamp sinceTimstamp = new Timestamp((since != null) ? since : 0L);

        final EmCallback<List<Picture>> emCallback = new EmCallback<List<Picture>>(this.getEmf()) {

            @Override
            @SuppressWarnings("unchecked")
            protected List<Picture> executeWithEntityManager(final EntityManager em) throws PersistenceException {
                final Query findByAlbumQuery = em.createNamedQuery(Picture.FIND_PICTURE_BY_ALBUM_ORDER_BY_DATE);
                findByAlbumQuery.setParameter("albumId", albumId);
                findByAlbumQuery.setParameter("since", sinceTimstamp);
                findByAlbumQuery.setMaxResults(DbPictureDao.PAGINATION_SIZE);

                final List<Picture> pictureId = findByAlbumQuery.getResultList();
                return pictureId;
            }
        };

        List<Picture> pictures = emCallback.getReturnedValue();
        if (pictures == null) {
            pictures = Collections.emptyList();
        }

        return pictures;
    }

    @Override
    public Picture findPictureById(final long id) {
        Assert.notNull(id, "Picture Id should be supplied !");

        final EmCallback<Picture> emCallback = new EmCallback<Picture>(this.getEmf()) {

            @Override
            protected Picture executeWithEntityManager(final EntityManager em) throws PersistenceException {
                return em.find(Picture.class, id);
            }
        };

        return emCallback.getReturnedValue();
    }

    @Override
    public Long findPictureIdByHash(final String hash) {
        Assert.hasText(hash, "Picture hash should be supplied !");

        final EmCallback<Long> emCallback = new EmCallback<Long>(this.getEmf()) {

            @Override
            @SuppressWarnings("unchecked")
            protected Long executeWithEntityManager(final EntityManager em) throws PersistenceException {
                final Query findByHashQuery = em.createNamedQuery(Picture.FIND_PICTURE_ID_BY_HASH);
                findByHashQuery.setParameter("hash", hash);

                final Long pictureId = Iterables.getFirst(findByHashQuery.getResultList(), null);
                return pictureId;
            }
        };

        return emCallback.getReturnedValue();
    }

    @Override
    public Picture loadFullPictureById(final long id) {
        Assert.notNull(id, "Picture Id should be supplied !");

        final EmCallback<Picture> emCallback = new EmCallback<Picture>(this.getEmf()) {

            @Override
            @SuppressWarnings("unchecked")
            protected Picture executeWithEntityManager(final EntityManager em) throws PersistenceException {
                final Query findByIdQuery = em.createNamedQuery(Picture.LOAD_FULL_PICTURE_BY_ID);
                findByIdQuery.setParameter("id", id);

                final Picture picture = Iterables.getFirst(findByIdQuery.getResultList(), null);
                return picture;
            }
        };

        return emCallback.getReturnedValue();
    }

    @Override
    public BinaryImage findImageById(final long id) {
        Assert.notNull(id, "Image Id should be supplied !");

        final EmCallback<BinaryImage> emCallback = new EmCallback<BinaryImage>(this.getEmf()) {

            @Override
            protected BinaryImage executeWithEntityManager(final EntityManager em) throws PersistenceException {
                return em.find(BinaryImage.class, id);
            }
        };

        return emCallback.getReturnedValue();
    }

    @Override
    @SuppressWarnings("unchecked")
    public List<Picture> findAllPictures(final Long since) {
        final Timestamp sinceTimstamp = new Timestamp((since != null) ? since : 0L);

        final EmCallback<List<Picture>> emCallback = new EmCallback<List<Picture>>(this.getEmf()) {

            @Override
            protected List<Picture> executeWithEntityManager(final EntityManager em) throws PersistenceException {
                final Query findAllQuery = em.createNamedQuery(Picture.FIND_ALL_PICTURES_ORDER_BY_DATE);
                findAllQuery.setParameter("since", sinceTimstamp);
                findAllQuery.setMaxResults(DbPictureDao.PAGINATION_SIZE);

                return findAllQuery.getResultList();
            }
        };

        List<Picture> pictures = emCallback.getReturnedValue();

        if (pictures == null) {
            pictures = Collections.emptyList();
        }

        return pictures;
    }

    /**
     * Test if a picture is already presents in DB.
     * 
     * @param picture
     * @param em
     * @throws PictureAlreadyExistsException
     */
    protected void testHashUniqueness(final Picture picture, final EntityManager em)
            throws PictureAlreadyExistsException {
        final Query findPicByHashQuery = em.createNamedQuery(Picture.FIND_PICTURE_ID_BY_HASH);
        findPicByHashQuery.setParameter("hash", picture.getOriginalHash());
        final List<?> results = findPicByHashQuery.getResultList();
        if (!results.isEmpty()) {
            // A picture with same hash was found
            throw new PictureAlreadyExistsException(picture.getFilename());
        }
    }

}