AutoEmailRepositoryImpl.java

package com.tradecloud.repository.autoemail;

import com.tradecloud.domain.autoemail.*;
import com.tradecloud.domain.infrastructure.persistence.CriteriaBuilder;
import com.tradecloud.domain.party.Employee;
import com.tradecloud.repository.impl.GeneralRepositoryImpl;
import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Repository(value = "autoEmailRepository")
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
public class AutoEmailRepositoryImpl extends GeneralRepositoryImpl implements AutoEmailRepository {

    private static final long serialVersionUID = 1L;

    private static final String LIKE = "%";

    private static final String GROUP_NAME = "name";
    private static final String TASK_NAME = "name";

    private static final Logger log = Logger.getLogger(AutoEmailRepositoryImpl.class);

    @Override
    public List<Group> findGroups(String name) {
        DetachedCriteria criteria = DetachedCriteria.forClass(Group.class);

        if (name != null) {
            criteria.add(Restrictions.ilike(GROUP_NAME, LIKE + name + LIKE));
        }

        criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

        List<Group> list = getExecutableCriteriaList(criteria, Group.class);

        return list;
    }

    @Override
    public List<Group> findGroups(Employee buyer) {
        StringBuilder queryString = new StringBuilder("select DISTINCT g from Group g");

        if (buyer != null) {
            queryString.append(" where buyer = :buyer");
        }
        org.hibernate.query.Query query = getCurrentSession().createQuery(queryString.toString());

        if (buyer != null) {
            query.setParameter("buyer", buyer);
        }

        return query.getResultList();
    }

    @Override
    public List<Task> findTasks(String name) {
        DetachedCriteria criteria = DetachedCriteria.forClass(Task.class);

        if (name != null) {
            criteria.add(Restrictions.ilike(TASK_NAME, LIKE + name + LIKE));
        }

        criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

        List<Task> list = getExecutableCriteriaList(criteria, Task.class);

        return list;
    }

    @Override
    public List<Task> findTasks(EmailEventType emailEventType) {
        DetachedCriteria criteria = DetachedCriteria.forClass(Task.class);

        CriteriaBuilder.addExactMatch(criteria, "emailTaskEventType", emailEventType);

        criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

        List<Task> list = getExecutableCriteriaList(criteria, Task.class);

        return list;
    }

    @Override
    public List<Task> findTasksLinkedToSpecificReports(List<Report> reportList) {
        DetachedCriteria criteria = DetachedCriteria.forClass(Task.class);
        CriteriaBuilder.addDisjunctionIn(criteria, "report", reportList);
        criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
        List<Task> list = getExecutableCriteriaList(criteria, Task.class);

        return list;
    }

    @Override
    public List<AuditEntry> findAuditEntries(Task task, AuditEntryState state, Date from, Date to) {
        // Obtain the CriteriaBuilder instance
        javax.persistence.criteria.CriteriaBuilder cb = getSessionCustom().getCriteriaBuilder();

        // Create the CriteriaQuery
        CriteriaQuery<AuditEntry> cq = cb.createQuery(AuditEntry.class);
        Root<AuditEntry> root = cq.from(AuditEntry.class);

        // Predicate list for dynamic query conditions
        List<Predicate> predicates = new ArrayList<>();
        predicates.add(cb.isNotNull(root.get("created")));
        // Add conditions
        if (task != null) {
            predicates.add(cb.equal(root.get("task"), task));
        }
        if (state != null) {
            predicates.add(cb.equal(root.get("state"), state));
        }
        if (from != null && to != null) {
            predicates.add(cb.between(root.get("created"), from, to));
        } else if (from != null) {
            predicates.add(cb.greaterThanOrEqualTo(root.get("created"), from));
        } else if (to != null) {
            predicates.add(cb.lessThanOrEqualTo(root.get("created"), to));
        }

        // Apply predicates to the query
        cq.where(predicates.toArray(new Predicate[0]));

        // Avoid duplicate results
        cq.distinct(true);

        // Execute the query and get results
        return getSessionCustom().createQuery(cq).getResultList();
    }

    @Override
    public AuditEntry findMostRecentAuditEntryOrNull(Task task) {

        javax.persistence.criteria.CriteriaBuilder builder = getSessionCustom().getCriteriaBuilder();
        CriteriaQuery<AuditEntry> criteriaQuery = builder.createQuery(AuditEntry.class);
        Root<AuditEntry> root = criteriaQuery.from(AuditEntry.class);

        if (task != null) {
            criteriaQuery.where(builder.equal(root.get("task"), task));
        }

        criteriaQuery.orderBy(builder.desc(root.get("created")));
        org.hibernate.query.Query query = getSessionCustom().createQuery(criteriaQuery);
        query.setMaxResults(1);
        List<AuditEntry> list = query.getResultList();
        return list.isEmpty() ? null : list.get(0);
    }

    @Override
    public Group findGroupById(Long id) {
        String hql = "from Group where id=:id";
        Query query = getSession().createQuery(hql);
        query.setParameter("id", id);
        return (Group) query.uniqueResult();
    }
}