org.javamexico.dao.hib3.QuestionDAO.java Source code

Java tutorial

Introduction

Here is the source code for org.javamexico.dao.hib3.QuestionDAO.java

Source

/*
This file is part of JavaMexico.
    
JavaMexico 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 (at your option) any later version.
    
JavaMexico 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 JavaMexico.
If not, see <http://www.gnu.org/licenses/>.
*/
package org.javamexico.dao.hib3;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import org.hibernate.LockMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.javamexico.dao.PreguntaDao;
import org.javamexico.entity.Usuario;
import org.javamexico.entity.pregunta.ComentPregunta;
import org.javamexico.entity.pregunta.ComentRespuesta;
import org.javamexico.entity.pregunta.Pregunta;
import org.javamexico.entity.pregunta.Respuesta;
import org.javamexico.entity.pregunta.TagPregunta;
import org.javamexico.entity.pregunta.VotoPregunta;
import org.javamexico.entity.pregunta.VotoRespuesta;
import org.javamexico.util.PrivilegioInsuficienteException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.transaction.annotation.Transactional;

/** Implementacion del DAO de preguntas, usando Hibernate 3 y el soporte de Spring.
 * 
 * @author Enrique Zamudio
 */
public class QuestionDAO implements PreguntaDao {

    protected final Logger log = LoggerFactory.getLogger(getClass());
    private SessionFactory sfact;
    private int minRepVotaPu = 10;
    private int minRepVotaRu = 20;
    private int minRepVotaPd = 5;
    private int minRepVotaRd = 10;

    /** Indica la reputacion minima requerida para dar votos negativos a una pregunta. */
    public void setMinRepVotoPreguntaDown(int value) {
        minRepVotaPd = value;
    }

    /** Indica la reputacion minima requerida para dar votos negativos a una respuesta. */
    public void setMinRepVotoRespuestaDown(int value) {
        minRepVotaRd = value;
    }

    /** Indica la reputacion minima requerida para dar votos positivos a una pregunta. */
    public void setMinRepVotoPreguntaUp(int value) {
        minRepVotaPu = value;
    }

    /** Indica la reputacion minima requerida para dar votos positivos a una respuesta. */
    public void setMinRepVotoRespuestaUp(int value) {
        minRepVotaRu = value;
    }

    @Required
    public void setSessionFactory(SessionFactory value) {
        sfact = value;
    }

    public SessionFactory getSessionFactory() {
        return sfact;
    }

    public Pregunta getPregunta(int id) {
        Session sess = sfact.getCurrentSession();
        Pregunta p = (Pregunta) sess.get(Pregunta.class, id);
        if (p != null) {
            p.getTags().size();
            p.getComentarios().size();
            p.getRespuestas().size();
        }
        return p;
    }

    public List<Pregunta> getPreguntasConTag(TagPregunta tag) {
        Session sess = sfact.getCurrentSession();
        sess.refresh(tag);
        return new ArrayList<Pregunta>(tag.getPreguntas());
    }

    public List<Pregunta> getPreguntasConTag(String tag) {
        Session sess = sfact.getCurrentSession();
        @SuppressWarnings("unchecked")
        List<TagPregunta> tags = sess.createCriteria(TagPregunta.class)
                .add(Restrictions.ilike("tag", tag, MatchMode.EXACT)).setMaxResults(1).list();
        List<Pregunta> qus = null;
        if (tags.size() > 0) {
            qus = new ArrayList<Pregunta>(tags.get(0).getPreguntas());
        } else {
            qus = Collections.emptyList();
        }
        return qus;
    }

    public List<Pregunta> getPreguntasConTags(Set<TagPregunta> tags) {
        Session sess = sfact.getCurrentSession();
        Set<Pregunta> qus = new TreeSet<Pregunta>();
        for (TagPregunta tag : tags) {
            sess.refresh(tag);
            qus.addAll(tag.getPreguntas());
        }
        return new ArrayList<Pregunta>(qus);
    }

    public List<Pregunta> getPreguntasMasVotadas(int limit) {
        Session sess = sfact.getCurrentSession();
        @SuppressWarnings("unchecked")
        List<Pregunta> qus = sess.createCriteria(Pregunta.class).add(Restrictions.gt("status", 0))
                .addOrder(Order.desc("votos")).setMaxResults(limit).list();
        return qus;
    }

    public List<Pregunta> getPreguntasRecientes(int page, int pageSize) {
        Session sess = sfact.getCurrentSession();
        @SuppressWarnings("unchecked")
        List<Pregunta> qus = sess.createCriteria(Pregunta.class).add(Restrictions.gt("status", 0))
                .addOrder(Order.desc("fechaPregunta")).setMaxResults(pageSize).setFirstResult((page - 1) * pageSize)
                .list();
        return qus;
    }

    public List<Pregunta> getPreguntasSinResolver(int limit) {
        Session sess = sfact.getCurrentSession();
        @SuppressWarnings("unchecked")
        List<Pregunta> qus = sess.createCriteria(Pregunta.class).add(Restrictions.eq("status", 1))
                .addOrder(Order.desc("fechaPregunta")).list();
        return qus;
    }

    public List<Pregunta> getPreguntasSinResponder(int limit) {
        Session sess = sfact.getCurrentSession();
        @SuppressWarnings("unchecked")
        List<Pregunta> qus = sess.createCriteria(Pregunta.class).add(Restrictions.sizeEq("respuestas", 0))
                .addOrder(Order.desc("fechaPregunta")).setMaxResults(limit).list();
        return qus;
    }

    public List<Pregunta> getPreguntasUsuario(Usuario user) {
        Session sess = sfact.getCurrentSession();
        @SuppressWarnings("unchecked")
        List<Pregunta> qus = sess.createCriteria(Pregunta.class).add(Restrictions.eq("autor", user))
                .addOrder(Order.desc("fechaPregunta")).list();
        return qus;
    }

    public List<Respuesta> getRespuestas(Pregunta q, int pageSize, int page, boolean crono) {
        Session sess = sfact.getCurrentSession();
        @SuppressWarnings("unchecked")
        List<Respuesta> resps = sess.createCriteria(Respuesta.class).add(Restrictions.eq("pregunta", q))
                .setMaxResults(pageSize).setFirstResult((page - 1) * pageSize)
                .addOrder(crono ? Order.desc("fecha") : Order.desc("votos")).list();
        return resps;
    }

    public List<TagPregunta> getTagsPopulares(int limit) {
        Session sess = sfact.getCurrentSession();
        @SuppressWarnings("unchecked")
        List<TagPregunta> tags = sess.createCriteria(TagPregunta.class).addOrder(Order.desc("count"))
                .setMaxResults(limit).list();
        return tags;
    }

    public VotoPregunta vota(Usuario user, Pregunta pregunta, boolean up) throws PrivilegioInsuficienteException {
        if ((up && user.getReputacion() < minRepVotaPu) || (!up && user.getReputacion() < minRepVotaPd)) {
            throw new PrivilegioInsuficienteException(
                    "El usuario no tiene privilegio suficiente para votar por una pregunta");
        }
        Session sess = sfact.getCurrentSession();
        VotoPregunta v = findVoto(user, pregunta);
        int updateRep = 0;
        if (v == null) {
            //Insertamos un nuevo voto
            v = new VotoPregunta();
            v.setFecha(new Date());
            v.setPregunta(pregunta);
            v.setUp(up);
            v.setUser(user);
            sess.save(v);
            updateRep = up ? 1 : -1;
        } else if (v.isUp() != up) {
            //Modificamos el voto existente
            v.setUp(up);
            v.setFecha(new Date());
            sess.update(v);
            //Al cambiar voto, debe afectarse por 2
            updateRep = up ? 2 : -2;
        }
        if (updateRep != 0) {
            //Actualizamos la reputacion del autor de la pregunta
            sess.refresh(pregunta);
            //Esto no es intuitivo pero si no lo hago asi, hib3 arroja excepcion marciana.
            user = (Usuario) sess.merge(pregunta.getAutor());
            sess.lock(user, LockMode.UPGRADE);
            sess.refresh(user);
            user.setReputacion(user.getReputacion() + updateRep);
            sess.update(user);
            sess.flush();
        }
        return v;
    }

    public VotoRespuesta vota(Usuario user, Respuesta resp, boolean up) throws PrivilegioInsuficienteException {
        if ((up && user.getReputacion() < minRepVotaRu) || (!up && user.getReputacion() < minRepVotaRd)) {
            throw new PrivilegioInsuficienteException(
                    "El usuario no tiene privilegio suficiente para votar por una respuesta");
        }
        Session sess = sfact.getCurrentSession();
        VotoRespuesta v = findVoto(user, resp);
        int updateRep = 0;
        if (v == null) {
            v = new VotoRespuesta();
            v.setFecha(new Date());
            v.setRespuesta(resp);
            v.setUp(up);
            v.setUser(user);
            sess.save(v);
            updateRep = up ? 1 : -1;
        } else if (v.isUp() != up) {
            v.setUp(up);
            v.setFecha(new Date());
            sess.update(v);
            updateRep = up ? 2 : -2;
        }
        if (updateRep != 0) {
            sess.refresh(resp);
            user = (Usuario) sess.merge(resp.getAutor());
            sess.lock(user, LockMode.UPGRADE);
            sess.refresh(user);
            user.setReputacion(user.getReputacion() + updateRep);
            sess.update(user);
            sess.flush();
        }
        return v;
    }

    public VotoPregunta findVoto(Usuario user, Pregunta pregunta) {
        Session sess = sfact.getCurrentSession();
        @SuppressWarnings("unchecked")
        List<VotoPregunta> v = sess.createCriteria(VotoPregunta.class).add(Restrictions.eq("user", user))
                .add(Restrictions.eq("pregunta", pregunta)).setMaxResults(1).list();
        return v.size() > 0 ? v.get(0) : null;
    }

    public VotoRespuesta findVoto(Usuario user, Respuesta respuesta) {
        Session sess = sfact.getCurrentSession();
        @SuppressWarnings("unchecked")
        List<VotoRespuesta> v = sess.createCriteria(VotoRespuesta.class).add(Restrictions.eq("user", user))
                .add(Restrictions.eq("respuesta", respuesta)).setMaxResults(1).list();
        return v.size() > 0 ? v.get(0) : null;
    }

    public void insert(Pregunta p) {
        Session sess = sfact.getCurrentSession();
        if (p.getFechaPregunta() == null) {
            p.setFechaPregunta(new Date());
        }
        sess.save(p);
    }

    public void update(Pregunta p) {
        Session sess = sfact.getCurrentSession();
        if (p.getFechaPregunta() == null) {
            p.setFechaPregunta(new Date());
        }
        sess.update(p);
    }

    @Transactional
    public void delete(Pregunta p) {
        Session sess = sfact.getCurrentSession();
        sess.delete(p);
    }

    public Respuesta addRespuesta(String resp, Pregunta p, Usuario autor) {
        Session sess = sfact.getCurrentSession();
        Respuesta r = new Respuesta();
        r.setFecha(new Date());
        r.setAutor(autor);
        r.setPregunta(p);
        r.setRespuesta(resp);
        sess.save(r);
        sess.flush();
        sess.refresh(p);
        p.getRespuestas().size();
        return r;
    }

    public ComentPregunta addComentario(String c, Pregunta p, Usuario autor) {
        Session sess = sfact.getCurrentSession();
        ComentPregunta cp = new ComentPregunta();
        cp.setAutor(autor);
        cp.setComentario(c);
        cp.setFecha(new Date());
        cp.setPregunta(p);
        sess.save(cp);
        sess.flush();
        sess.refresh(p);
        p.getComentarios().size();
        return cp;
    }

    public ComentRespuesta addComentario(String c, Respuesta r, Usuario autor) {
        Session sess = sfact.getCurrentSession();
        ComentRespuesta cr = new ComentRespuesta();
        cr.setRespuesta(r);
        cr.setAutor(autor);
        cr.setComentario(c);
        cr.setFecha(new Date());
        sess.save(cr);
        sess.flush();
        sess.refresh(r);
        r.getComentarios().size();
        return cr;
    }

    @Transactional
    public void addTag(String tag, Pregunta p) {
        Session sess = sfact.getCurrentSession();
        @SuppressWarnings("unchecked")
        List<TagPregunta> tags = sess.createCriteria(TagPregunta.class).add(Restrictions.ilike("tag", tag))
                .setMaxResults(1).list();
        TagPregunta utag = null;
        if (tags.size() == 0) {
            utag = new TagPregunta();
            utag.setTag(tag);
            sess.save(utag);
            sess.flush();
        } else {
            utag = tags.get(0);
        }
        if (p.getTags() == null) {
            sess.refresh(p);
        }
        p.getTags().add(utag);
        sess.update(p);
        p.getTags().size();
    }

    public List<TagPregunta> findMatchingTags(String parcial) {
        Session sess = sfact.getCurrentSession();
        @SuppressWarnings("unchecked")
        List<TagPregunta> tags = sess.createCriteria(TagPregunta.class)
                .add(Restrictions.ilike("tag", parcial, MatchMode.ANYWHERE)).list();
        return tags;
    }

}