package org.jtheque.films.persistence.dao.impl;
/*
* Copyright JTheque (Baptiste Wicht)
*
* 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.
*/
import org.jtheque.core.managers.Managers;
import org.jtheque.core.managers.collection.Collection;
import org.jtheque.core.managers.collection.IDaoCollections;
import org.jtheque.core.managers.log.ILoggingManager;
import org.jtheque.core.managers.persistence.GenericDao;
import org.jtheque.core.managers.persistence.Query;
import org.jtheque.core.managers.persistence.QueryMapper;
import org.jtheque.core.managers.persistence.able.Entity;
import org.jtheque.core.managers.persistence.context.IDaoPersistenceContext;
import org.jtheque.core.utils.db.DaoNotes;
import org.jtheque.films.persistence.dao.able.IDaoFilms;
import org.jtheque.films.persistence.od.able.Film;
import org.jtheque.films.persistence.od.impl.FilmActorRelation;
import org.jtheque.films.persistence.od.impl.FilmImpl;
import org.jtheque.films.persistence.od.impl.FilmKindRelation;
import org.jtheque.primary.dao.able.IDaoLendings;
import org.jtheque.primary.dao.able.IDaoPersons;
import org.jtheque.primary.dao.able.IDaoSimpleDatas;
import org.jtheque.primary.od.able.Person;
import org.jtheque.primary.od.able.SimpleData;
import org.jtheque.utils.StringUtils;
import org.jtheque.utils.collections.CollectionUtils;
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import javax.annotation.Resource;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* A DAO implementation for films.
*
* @author Baptiste Wicht
*/
public final class DaoFilms extends GenericDao<Film> implements IDaoFilms {
private final ParameterizedRowMapper<Film> rowMapper = new FilmRowMapper();
private final ParameterizedRowMapper<FilmKindRelation> relationKindRowMapper = new RelationKindRowMapper();
private final ParameterizedRowMapper<FilmActorRelation> relationActorRowMapper = new RelationActorRowMapper();
private final QueryMapper queryMapper = new FilmQueryMapper();
private java.util.Collection<FilmActorRelation> relationsToActors;
private java.util.Collection<FilmKindRelation> relationsToKinds;
@Resource
private IDaoPersistenceContext persistenceContext;
@Resource
private SimpleJdbcTemplate jdbcTemplate;
@Resource
private IDaoCollections daoCollections;
@Resource
private IDaoSimpleDatas daoKinds;
@Resource
private IDaoSimpleDatas daoTypes;
@Resource
private IDaoSimpleDatas daoSagas;
@Resource
private IDaoLendings daoLendings;
@Resource
private IDaoPersons daoPersons;
@Resource
private IDaoSimpleDatas daoLanguages;
/**
* Construct a new DaoFilms.
*/
public DaoFilms() {
super(TABLE);
}
@Override
@SuppressWarnings("unchecked")
public java.util.Collection<Film> getFilms() {
List<Film> films = CollectionUtils.copyOf(getFilms(daoCollections.getCurrentCollection()));
Collections.sort(films);
return films;
}
/**
* Return all the films of the collection.
*
* @param collection The collection.
*
* @return A List containing all the films of the collections.
*/
private java.util.Collection<Film> getFilms(Collection collection) {
if (collection == null || !collection.isSaved()) {
return getAll();
}
load();
java.util.Collection<Film> films = new ArrayList<Film>(getCache().size() / 2);
for (Film film : getCache().values()) {
if (film.getTheCollection().getId() == collection.getId()) {
films.add(film);
}
}
return films;
}
@Override
public Film getFilm(int id) {
return get(id);
}
@Override
public void createAll(Iterable<Film> films) {
for (Film film : films) {
create(film);
}
}
@Override
public Film createFilm() {
return new FilmImpl();
}
@Override
public boolean delete(Film film) {
boolean deleted = super.delete(film);
jdbcTemplate.update("DELETE FROM " + ACTORS_FILMS_TABLE + " WHERE THE_FILM_FK = ?", film.getId());
jdbcTemplate.update("DELETE FROM " + KINDS_FILMS_TABLE + " WHERE THE_FILM_FK = ?", film.getId());
return deleted;
}
@Override
public void save(Film film) {
super.save(film);
jdbcTemplate.update("DELETE FROM " + ACTORS_FILMS_TABLE + " WHERE THE_FILM_FK = ?", film.getId());
jdbcTemplate.update("DELETE FROM " + KINDS_FILMS_TABLE + " WHERE THE_FILM_FK = ?", film.getId());
updateLinksBetweenTable(film);
}
@Override
public void create(Film film) {
film.setTheCollection(daoCollections.getCurrentCollection());
super.create(film);
updateLinksBetweenTable(film);
}
/**
* Update the links between table.
*
* @param film The film.
*/
private void updateLinksBetweenTable(Film film) {
for (Person actor : film.getActors()) {
jdbcTemplate.update("INSERT INTO " + ACTORS_FILMS_TABLE + " (THE_FILM_FK, THE_ACTOR_FK) VALUES(?,?)", film.getId(), actor.getId());
}
for (SimpleData kind : film.getKinds()) {
jdbcTemplate.update("INSERT INTO " + KINDS_FILMS_TABLE + " (THE_FILM_FK, THE_KIND_FK) VALUES(?,?)", film.getId(), kind.getId());
}
}
@Override
protected ParameterizedRowMapper<Film> getRowMapper() {
return rowMapper;
}
@Override
protected QueryMapper getQueryMapper() {
return queryMapper;
}
@Override
protected void loadCache() {
relationsToActors = jdbcTemplate.query("SELECT * FROM " + ACTORS_FILMS_TABLE, relationActorRowMapper);
relationsToKinds = jdbcTemplate.query("SELECT * FROM " + KINDS_FILMS_TABLE, relationKindRowMapper);
java.util.Collection<Film> movies = persistenceContext.getSortedList(TABLE, rowMapper);
for (Film film : movies) {
getCache().put(film.getId(), film);
}
setCacheEntirelyLoaded();
relationsToActors.clear();
relationsToKinds.clear();
}
@Override
protected void load(int i) {
Film film = persistenceContext.getDataByID(TABLE, i, rowMapper);
getCache().put(i, film);
}
/**
* A row mapper to map resultset to relation between film and kind.
*
* @author Baptiste Wicht
*/
private static final class RelationKindRowMapper implements ParameterizedRowMapper<FilmKindRelation> {
@Override
public FilmKindRelation mapRow(ResultSet rs, int i) throws SQLException {
FilmKindRelation relation = new FilmKindRelation();
relation.setTheFilm(rs.getInt("THE_FILM_FK"));
relation.setTheKind(rs.getInt("THE_KIND_FK"));
return relation;
}
}
/**
* A row mapper to map resultset to relation between film and actor.
*
* @author Baptiste Wicht
*/
private static final class RelationActorRowMapper implements ParameterizedRowMapper<FilmActorRelation> {
@Override
public FilmActorRelation mapRow(ResultSet rs, int i) throws SQLException {
FilmActorRelation relation = new FilmActorRelation();
relation.setTheFilm(rs.getInt("THE_FILM_FK"));
relation.setTheActor(rs.getInt("THE_ACTOR_FK"));
return relation;
}
}
/**
* A row mapper to map resultset to film.
*
* @author Baptiste Wicht
*/
private final class FilmRowMapper implements ParameterizedRowMapper<Film> {
@Override
public Film mapRow(ResultSet rs, int i) throws SQLException {
Film film = createFilm();
film.setId(rs.getInt("ID"));
film.setTitle(rs.getString("TITLE"));
film.setYear(rs.getInt("YEAR"));
film.setComment(rs.getString("COMMENT"));
film.setDuration(rs.getInt("DURATION"));
film.setFilePath(rs.getString("FILEPATH"));
film.setImage(rs.getString("IMAGE"));
film.setResume(rs.getString("RESUME"));
film.setTheCollection(daoCollections.getCollection(rs.getInt("THE_COLLECTION_FK")));
film.setTheLanguage(daoLanguages.getSimpleData(rs.getInt("THE_LANGUAGE_FK")));
film.setTheLending(daoLendings.getLending(rs.getInt("THE_LENDING_FK")));
film.setTheRealizer(daoPersons.getPerson(rs.getInt("THE_REALIZER_FK")));
film.setTheSaga(daoSagas.getSimpleData(rs.getInt("THE_SAGA_FK")));
film.setTheType(daoTypes.getSimpleData(rs.getInt("THE_TYPE_FK")));
if (StringUtils.isNotEmpty(rs.getString("NOTE"))) {
film.setNote(DaoNotes.getInstance().getNote(DaoNotes.NoteType.getEnum(rs.getInt("NOTE"))));
}
mapRelations(film);
return film;
}
/**
* Map the relations.
*
* @param film The film to map the relations for.
*/
private void mapRelations(Film film) {
mapKindsRelations(film);
mapActorsRelations(film);
}
/**
* Map the kind relations.
*
* @param film The film to map the relations for.
*/
private void mapKindsRelations(Film film) {
if (relationsToKinds != null && !relationsToKinds.isEmpty()) {
for (FilmKindRelation relation : relationsToKinds) {
if (relation.getTheFilm() == film.getId()) {
film.addKind(daoKinds.getSimpleData(relation.getTheKind()));
}
}
} else {
relationsToKinds = jdbcTemplate.query("SELECT * FROM " + KINDS_FILMS_TABLE + " WHERE THE_FILM_FK = ?", relationKindRowMapper, film.getId());
for (FilmKindRelation relation : relationsToKinds) {
film.addKind(daoKinds.getSimpleData(relation.getTheKind()));
}
relationsToKinds.clear();
}
}
/**
* Map the actor relations.
*
* @param film The film to map the relations for.
*/
private void mapActorsRelations(Film film) {
if (relationsToActors != null && !relationsToActors.isEmpty()) {
for (FilmActorRelation relation : relationsToActors) {
if (relation.getTheFilm() == film.getId()) {
Person actor = daoPersons.getPerson(relation.getTheActor());
if (actor == null) {
Managers.getManager(ILoggingManager.class).getLogger(getClass()).error("Film ({}) references a null actor id = {}",
film.getId(), relation.getTheActor());
} else {
film.addActor(actor);
}
}
}
} else {
relationsToActors = jdbcTemplate.query("SELECT * FROM " + ACTORS_FILMS_TABLE + " WHERE THE_FILM_FK = ?", relationActorRowMapper, film.getId());
for (FilmActorRelation relation : relationsToActors) {
Person actor = daoPersons.getPerson(relation.getTheActor());
if (actor == null) {
Managers.getManager(ILoggingManager.class).getLogger(getClass()).error("Film ({}) references a null actor id = {}",
film.getId(), relation.getTheActor());
} else {
film.addActor(actor);
}
}
relationsToActors.clear();
}
}
}
/**
* A query mapper to map film to sql query.
*
* @author Baptiste Wicht
*/
private static final class FilmQueryMapper implements QueryMapper {
@Override
public Query constructInsertQuery(Entity entity) {
Film film = (Film) entity;
String query = "INSERT INTO " + TABLE + " (TITLE, NOTE, COMMENT, DURATION, FILEPATH, IMAGE, RESUME, THE_COLLECTION_FK, THE_LANGUAGE_FK, THE_LENDING_FK, " +
"THE_REALIZER_FK, THE_SAGA_FK, THE_TYPE_FK) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)";
Object[] parameters = {
film.getTitle(),
film.getNote() == null ? 0 : film.getNote().getValue().intValue(),
film.getComment(),
film.getDuration(),
film.getFilePath(),
film.getImage(),
film.getResume(),
film.getTheCollection().getId(),
film.getTheLanguage() == null ? null : film.getTheLanguage().getId(),
film.getTheLending() == null ? null : film.getTheLending().getId(),
film.getTheRealizer() == null ? null : film.getTheRealizer().getId(),
film.getTheSaga() == null ? null : film.getTheSaga().getId(),
film.getTheType() == null ? null : film.getTheType().getId(),
};
return new Query(query, parameters);
}
@Override
public Query constructUpdateQuery(Entity entity) {
Film film = (Film) entity;
String query = "UPDATE " + TABLE + " SET TITLE = ?, NOTE = ?, COMMENT = ?, DURATION = ?, FILEPATH = ?, IMAGE = ?, RESUME = ?, THE_COLLECTION_FK = ?, " +
"THE_LANGUAGE_FK = ?, THE_LENDING_FK = ?, THE_REALIZER_FK = ?, THE_SAGA_FK = ?, THE_TYPE_FK = ? WHERE ID = ?";
Object[] parameters = {
film.getTitle(),
film.getNote() == null ? 0 : film.getNote().getValue().intValue(),
film.getComment(),
film.getDuration(),
film.getFilePath(),
film.getImage(),
film.getResume(),
film.getTheCollection().getId(),
film.getTheLanguage() == null ? null : film.getTheLanguage().getId(),
film.getTheLending() == null ? null : film.getTheLending().getId(),
film.getTheRealizer() == null ? null : film.getTheRealizer().getId(),
film.getTheSaga() == null ? null : film.getTheSaga().getId(),
film.getTheType() == null ? null : film.getTheType().getId(),
film.getId()
};
return new Query(query, parameters);
}
}
}