org.yamj.core.database.service.MetadataStorageService.java Source code

Java tutorial

Introduction

Here is the source code for org.yamj.core.database.service.MetadataStorageService.java

Source

/*
 *      Copyright (c) 2004-2013 YAMJ Members
 *      https://github.com/organizations/YAMJ/teams
 *
 *      This file is part of the Yet Another Media Jukebox (YAMJ).
 *
 *      YAMJ is free software: you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation, either version 3 of the License, or
 *      any later version.
 *
 *      YAMJ is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with YAMJ.  If not, see <http://www.gnu.org/licenses/>.
 *
 *      Web: https://github.com/YAMJ/yamj-v3
 *
 */
package org.yamj.core.database.service;

import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.exception.ConstraintViolationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.support.DataAccessUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.yamj.common.type.StatusType;
import org.yamj.core.database.dao.CommonDao;
import org.yamj.core.database.dao.MetadataDao;
import org.yamj.core.database.model.*;
import org.yamj.core.database.model.dto.CreditDTO;
import org.yamj.core.database.model.dto.QueueDTO;
import org.yamj.common.type.MetaDataType;

@Service("metadataStorageService")
public class MetadataStorageService {

    private static final Logger LOG = LoggerFactory.getLogger(MetadataStorageService.class);
    @Autowired
    private CommonDao commonDao;
    @Autowired
    private MetadataDao metadataDao;

    @Transactional
    public void save(Object entity) {
        this.commonDao.saveEntity(entity);
    }

    @Transactional
    public void update(Object entity) {
        this.commonDao.updateEntity(entity);
    }

    @Transactional(readOnly = true)
    public List<QueueDTO> getMediaQueueForScanning(final int maxResults) {
        final StringBuilder sql = new StringBuilder();
        sql.append("select vd.id,'");
        sql.append(MetaDataType.MOVIE);
        sql.append("' as mediatype,vd.create_timestamp,vd.update_timestamp ");
        sql.append("from videodata vd ");
        sql.append("where vd.status in ('NEW','UPDATED') ");
        sql.append("and vd.episode<0 ");
        sql.append("union ");
        sql.append("select ser.id,'");
        sql.append(MetaDataType.SERIES);
        sql.append("' as mediatype,ser.create_timestamp,ser.update_timestamp ");
        sql.append("from series ser, season sea, videodata vd ");
        sql.append("where ser.id=sea.series_id ");
        sql.append("and sea.id=vd.season_id ");
        sql.append("and (ser.status in ('NEW','UPDATED') ");
        sql.append(" or  (ser.status='DONE' and sea.status in ('NEW','UPDATED')) ");
        sql.append(" or  (ser.status='DONE' and vd.status in  ('NEW','UPDATED'))) ");

        return metadataDao.getMetadataQueue(sql, maxResults);
    }

    @Transactional(readOnly = true)
    public List<QueueDTO> getPersonQueueForScanning(final int maxResults) {
        final StringBuilder sql = new StringBuilder();
        sql.append("select id, '");
        sql.append(MetaDataType.PERSON);
        sql.append("' as mediatype, create_timestamp, update_timestamp ");
        sql.append("from person ");
        sql.append("where status in ('");
        sql.append(StatusType.NEW);
        sql.append("','");
        sql.append(StatusType.UPDATED);
        sql.append("') ");

        return metadataDao.getMetadataQueue(sql, maxResults);
    }

    @Transactional(readOnly = true)
    public VideoData getRequiredVideoData(Long id) {
        final StringBuilder sb = new StringBuilder();
        sb.append("from VideoData vd ");
        sb.append("left outer join fetch vd.genres ");
        sb.append("left outer join fetch vd.credits c ");
        sb.append("where vd.id = :id");

        @SuppressWarnings("unchecked")
        List<VideoData> objects = this.commonDao.findById(sb, id);
        return DataAccessUtils.requiredUniqueResult(objects);
    }

    @Transactional(readOnly = true)
    public Series getRequiredSeries(Long id) {
        final StringBuilder sb = new StringBuilder();
        sb.append("from Series ser ");
        sb.append("join fetch ser.seasons sea ");
        sb.append("join fetch sea.videoDatas vd ");
        sb.append("left outer join fetch vd.credits c ");
        sb.append("where ser.id = :id");

        @SuppressWarnings("unchecked")
        List<Series> objects = this.commonDao.findById(sb, id);
        return DataAccessUtils.requiredUniqueResult(objects);
    }

    @Transactional(readOnly = true)
    public Person getRequiredPerson(Long id) {
        // later on there it could be necessary to fetch associated entities
        return metadataDao.getById(Person.class, id);
    }

    @Transactional
    public void storeGenre(String genreName) {
        Genre genre = commonDao.getGenre(genreName);
        if (genre == null) {
            // create new person
            genre = new Genre();
            genre.setName(genreName);
            commonDao.saveEntity(genre);
        }
    }

    @Transactional
    public void storePerson(CreditDTO dto) {
        Person person = metadataDao.getPerson(dto.getName());
        if (person == null) {
            // create new person
            person = new Person();
            person.setName(dto.getName());
            person.setPersonId(dto.getSourcedb(), dto.getSourcedbId());
            person.setStatus(StatusType.NEW);
            metadataDao.saveEntity(person);
        } else {
            // update person if ID has has been set
            if (person.setPersonId(dto.getSourcedb(), dto.getSourcedbId())) {
                metadataDao.updateEntity(person);
            }
        }
    }

    @Transactional
    public void updatePerson(Person person) {
        // update entity
        metadataDao.updateEntity(person);
    }

    @Transactional
    public void updateVideoData(VideoData videoData) {
        // update entity
        metadataDao.updateEntity(videoData);

        // update genres
        updateGenres(videoData);

        // update cast and crew
        updateCastCrew(videoData);
    }

    @Transactional
    public void updateSeries(Series series) {
        // update entity
        metadataDao.updateEntity(series);

        // update genres
        updateGenres(series);

        // update underlying seasons and episodes
        for (Season season : series.getSeasons()) {
            if (StatusType.PROCESSED.equals(season.getStatus())) {
                season.setStatus(StatusType.DONE);
                metadataDao.updateEntity(season);
            }
            for (VideoData videoData : season.getVideoDatas()) {
                if (StatusType.PROCESSED.equals(videoData.getStatus())) {
                    videoData.setStatus(StatusType.DONE);
                    updateVideoData(videoData);
                }
            }
        }
    }

    /**
     * Update genres for VideoData from the database
     *
     * @param videoData
     */
    private void updateGenres(VideoData videoData) {
        if (CollectionUtils.isEmpty(videoData.getGenreNames())) {
            return;
        }

        Set<Genre> genres = new LinkedHashSet<Genre>();
        for (String genreName : videoData.getGenreNames()) {
            Genre genre = commonDao.getByName(Genre.class, genreName);
            if (genre != null) {
                genres.add(genre);
            }
        }
        videoData.setGenres(genres);
    }

    /**
     * Update genres for Series from the database
     *
     * @param series
     */
    private void updateGenres(Series series) {
        if (CollectionUtils.isEmpty(series.getGenreNames())) {
            return;
        }

        Set<Genre> genres = new LinkedHashSet<Genre>();
        for (String genreName : series.getGenreNames()) {
            Genre genre = commonDao.getByName(Genre.class, genreName);
            if (genre != null) {
                genres.add(genre);
            }
        }
        series.setGenres(genres);
    }

    /**
     * Update cast and crew to the database
     *
     * @param videoData
     */
    private void updateCastCrew(VideoData videoData) {
        for (CreditDTO dto : videoData.getCreditDTOS()) {
            Person person = null;
            CastCrew castCrew = null;

            for (CastCrew credit : videoData.getCredits()) {
                if ((credit.getJobType() == dto.getJobType())
                        && StringUtils.equalsIgnoreCase(dto.getName(), credit.getPerson().getName())) {
                    castCrew = credit;
                    person = credit.getPerson();
                    break;
                }
            }

            // find person if not found
            if (person == null) {
                LOG.info("Attempting to retrieve information on '{}' from database", dto.getName());
                person = metadataDao.getByName(Person.class, dto.getName());
                if (person == null) {
                    // NOTE: person should have been stored before; just be sure
                    //       to avoid null constraint violation
                    LOG.warn("Person '{}' not found, skipping", dto.getName());
                    return;
                }
            } else {
                LOG.debug("Found '{}' in cast table", person.getName());
            }

            try {
                if (castCrew == null) {
                    // create new association between person and video
                    castCrew = new CastCrew();
                    castCrew.setPerson(person);
                    castCrew.setJob(dto.getJobType(), dto.getRole());
                    castCrew.setVideoData(videoData);
                    videoData.addCredit(castCrew);
                    metadataDao.saveEntity(castCrew);
                } else if (castCrew.setJob(castCrew.getJobType(), dto.getRole())) {
                    // updated role
                    metadataDao.updateEntity(castCrew);
                }
            } catch (ConstraintViolationException ex) {
                LOG.warn("Failed to save/update record for person {}-{}, job '{}', error: {}", person.getId(),
                        person.getName(), dto.getJobType(), ex.getMessage());
            }
        }
    }

    @Transactional
    public void errorVideoData(Long id) {
        VideoData videoData = metadataDao.getById(VideoData.class, id);
        if (videoData != null) {
            videoData.setStatus(StatusType.ERROR);
            metadataDao.updateEntity(videoData);
        }
    }

    @Transactional
    public void errorSeries(Long id) {
        Series series = metadataDao.getById(Series.class, id);
        if (series != null) {
            series.setStatus(StatusType.ERROR);
            metadataDao.updateEntity(series);
        }
    }

    @Transactional
    public void errorPerson(Long id) {
        Person person = metadataDao.getById(Person.class, id);
        if (person != null) {
            person.setStatus(StatusType.ERROR);
            metadataDao.updateEntity(person);
        }
    }

    @Transactional
    public void saveArtwork(Artwork artwork) {
        if (artwork != null) {
            metadataDao.saveEntity(artwork);
        }
    }

    @Transactional
    public void updateArtwork(Artwork artwork) {
        if (artwork != null) {
            metadataDao.updateEntity(artwork);
        }
    }
}