org.medici.bia.dao.volume.VolumeDAOJpaImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.medici.bia.dao.volume.VolumeDAOJpaImpl.java

Source

/*
 * VolumeDAOJpaImpl.java
 * 
 * Developed by Medici Archive Project (2010-2012).
 * 
 * This file is part of DocSources.
 * 
 * DocSources 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 2 of the License, or
 * (at your option) any later version.
 * 
 * DocSources 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 this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * As a special exception, if you link this library with other files to
 * produce an executable, this library does not by itself cause the
 * resulting executable to be covered by the GNU General Public License.
 * This exception does not however invalidate any other reasons why the
 * executable file might be covered by the GNU General Public License.
 */
package org.medici.bia.dao.volume;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.PersistenceException;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.ParameterExpression;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.hibernate.ejb.HibernateEntityManager;
import org.hibernate.search.FullTextSession;
import org.medici.bia.common.pagination.Page;
import org.medici.bia.common.pagination.PaginationFilter;
import org.medici.bia.common.pagination.PaginationFilter.Order;
import org.medici.bia.common.pagination.PaginationFilter.SortingCriteria;
import org.medici.bia.common.search.Search;
import org.medici.bia.dao.JpaDao;
import org.medici.bia.domain.Volume;
import org.springframework.stereotype.Repository;

/**
 * <b>VolumeDAOJpaImpl</b> is a default implementation of <b>VolumeDAO</b>.
 * 
 * @author Lorenzo Pasquinelli (<a href=mailto:l.pasquinelli@gmail.com>l.pasquinelli@gmail.com</a>)
 * @author Matteo Doni (<a href=mailto:donimatteo@gmail.com>donimatteo@gmail.com</a>)
 */
@Repository
public class VolumeDAOJpaImpl extends JpaDao<Integer, Volume> implements VolumeDAO {

    /**
     * 
     *  If a serializable class does not explicitly declare a serialVersionUID, 
     *  then the serialization runtime will calculate a default serialVersionUID 
     *  value for that class based on various aspects of the class, as described
     *  in the Java(TM) Object Serialization Specification. However, it is 
     *  strongly recommended that all serializable classes explicitly declare 
     *  serialVersionUID values, since the default serialVersionUID computation 
     *  is highly sensitive to class details that may vary depending on compiler
     *  implementations, and can thus result in unexpected 
     *  InvalidClassExceptions during deserialization. Therefore, to guarantee a
     *   consistent serialVersionUID value across different java compiler 
     *   implementations, a serializable class must declare an explicit 
     *  serialVersionUID value. It is also strongly advised that explicit 
     *  serialVersionUID declarations use the private modifier where possible, 
     *  since such declarations apply only to the immediately declaring 
     *  class--serialVersionUID fields are not useful as inherited members. 
     */
    private static final long serialVersionUID = -7671104408958929124L;

    private final Logger logger = Logger.getLogger(this.getClass());

    /**
     * {@inheritDoc}
     */
    @Override
    public Long countVolumeCreatedAfterDate(Date inputDate) throws PersistenceException {
        Query query = getEntityManager()
                .createQuery("SELECT COUNT(summaryId) FROM Volume WHERE dateCreated>=:inputDate");
        query.setParameter("inputDate", inputDate);

        return (Long) query.getSingleResult();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Volume findLastEntryVolume() throws PersistenceException {
        Query query = getEntityManager()
                .createQuery("FROM Volume WHERE logicalDelete = false ORDER BY dateCreated DESC");
        query.setMaxResults(1);

        return (Volume) query.getSingleResult();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Volume findVolume(Integer volNum, String volLetExt) {
        // Create criteria objects
        CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
        CriteriaQuery<Volume> criteriaQuery = criteriaBuilder.createQuery(Volume.class);
        Root<Volume> root = criteriaQuery.from(Volume.class);

        // Define predicate's elements
        ParameterExpression<Integer> parameterVolNum = criteriaBuilder.parameter(Integer.class, "volNum");
        ParameterExpression<String> parameterVolLetExt = StringUtils.isEmpty("volLetExt") ? null
                : criteriaBuilder.parameter(String.class, "volLetExt");

        criteriaQuery.where(criteriaBuilder.and(criteriaBuilder.equal(root.get("volNum"), parameterVolNum),
                StringUtils.isEmpty(volLetExt) ? criteriaBuilder.isNull(root.get("volLetExt"))
                        : criteriaBuilder.equal(root.get("volLetExt"), parameterVolLetExt),
                criteriaBuilder.equal(root.<Boolean>get("logicalDelete"), Boolean.FALSE)));

        // Set values in predicate's elements  
        TypedQuery<Volume> typedQuery = getEntityManager().createQuery(criteriaQuery);
        typedQuery.setParameter("volNum", volNum);
        if (!StringUtils.isEmpty(volLetExt)) {
            typedQuery.setParameter("volLetExt", volLetExt);
        }

        List<Volume> result = typedQuery.getResultList();

        if (result.size() == 1) {
            return result.get(0);
        } else {
            return null;
        }
    }

    /**
     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
    @Override
    public List<String> searchOtherLang(String query) throws PersistenceException {
        // TODO Auto-generated method stub
        StringBuilder stringBuilder = new StringBuilder(
                "SELECT DISTINCT otherLang FROM Volume WHERE otherLang LIKE'%");
        stringBuilder.append(query.toLowerCase());
        stringBuilder.append("%'");
        Query result = getEntityManager().createQuery(stringBuilder.toString());
        if (result.getResultList().size() == 0) {
            return null;
        } else {
            List<String> otherLang = result.getResultList();
            return otherLang;
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Page searchVolumes(Search searchContainer, PaginationFilter paginationFilter)
            throws PersistenceException {
        // We prepare object of return method.
        Page page = new Page(paginationFilter);

        // We obtain hibernate-search session
        FullTextSession fullTextSession = org.hibernate.search.Search
                .getFullTextSession(((HibernateEntityManager) getEntityManager()).getSession());

        // We convert SearchContainer to luceneQuery
        org.apache.lucene.search.Query query = searchContainer.toLuceneQuery();
        logger.info("Lucene Query " + query.toString());

        // We execute search
        org.hibernate.search.FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(query, Volume.class);

        // We set size of result.
        if (paginationFilter.getTotal() == null) {
            page.setTotal(new Long(fullTextQuery.getResultSize()));
        }

        // We set pagination  
        fullTextQuery.setFirstResult(paginationFilter.getFirstRecord());
        fullTextQuery.setMaxResults(paginationFilter.getLength());

        // We manage sorting (this manages sorting on multiple fields)
        paginationFilter = this.generatePaginationFilterHibernateSearch(paginationFilter);
        List<SortingCriteria> sortingCriterias = paginationFilter.getSortingCriterias();
        if (sortingCriterias.size() > 0) {
            SortField[] sortFields = new SortField[sortingCriterias.size()];
            for (int i = 0; i < sortingCriterias.size(); i++) {
                sortFields[i] = new SortField(sortingCriterias.get(i).getColumn(),
                        sortingCriterias.get(i).getColumnType(),
                        (sortingCriterias.get(i).getOrder().equals(Order.ASC) ? true : false));
            }
            fullTextQuery.setSort(new Sort(sortFields));
        }

        // We set search result on return method
        page.setList(fullTextQuery.list());

        return page;
    }

    //MD: Version with Lucene query
    //   /**
    //    * {@inheritDoc}
    //    */
    //   @SuppressWarnings({"unchecked"})
    //   @Override
    //   public List<Volume> searchVolumes(String query) throws PersistenceException {
    //      String[] outputFields = new String[]{"volNum", "volLetExt"};
    //      FullTextSession fullTextSession = org.hibernate.search.Search.getFullTextSession(((HibernateEntityManager)getEntityManager()).getSession());
    //      
    //      /*QueryParser parserTopicTitle = new QueryParser(Version.LUCENE_30, "topicTitle", fullTextSession.getSearchFactory().getAnalyzer("topicListAnalyzer"));
    //      try{
    //      org.apache.lucene.search.Query queryMapNameLf = parserTopicTitle.parse(alias.toLowerCase() + "*");
    //      BooleanQuery booleanQuery = new BooleanQuery();
    //      booleanQuery.add(new BooleanClause(queryMapNameLf, BooleanClause.Occur.SHOULD));
    //      String[] words = RegExUtils.splitPunctuationAndSpaceChars(alias);
    //      for (String singleWord:words) {
    //           booleanQuery.add(new BooleanClause(new WildcardQuery(new Term("topicTitle", singleWord.toLowerCase() + "*")), BooleanClause.Occur.SHOULD));
    //        }*/
    //      BooleanQuery booleanQuery = new BooleanQuery();
    //      //String[] words = RegExUtils.splitPunctuationAndSpaceChars(alias);
    //      //String singleWord;
    //      //for(int i = 0; i < words.length; i++){
    //      //   singleWord = words[i];
    //      //   if(i == 0){
    //      //      booleanQuery.add(new BooleanClause(new WildcardQuery(new Term("topicTitle", singleWord.toLowerCase() + "*")), BooleanClause.Occur.MUST));
    //      //   }
    //      //   else{
    //      //      booleanQuery.add(new BooleanClause(new WildcardQuery(new Term("topicTitle", singleWord.toLowerCase() + "*")), BooleanClause.Occur.SHOULD));
    //      //   }
    //      //}
    //      if(StringUtils.isNumeric(query)){
    //         booleanQuery.add(new BooleanClause(new WildcardQuery(new Term("volNum", query.toLowerCase() + "*")), BooleanClause.Occur.MUST));
    //      }else{
    //         booleanQuery.add(new BooleanClause(new WildcardQuery(new Term("volNum", query.toLowerCase())), BooleanClause.Occur.SHOULD));
    //         booleanQuery.add(new BooleanClause(new WildcardQuery(new Term("volLetExt", VolumeUtils.extractVolLetExt(query.toLowerCase()) + "*")), BooleanClause.Occur.SHOULD));
    //      }
    //
    //      org.hibernate.search.FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(booleanQuery, Volume.class);
    //      fullTextQuery.setProjection(outputFields);
    //      // Projection returns an array of Objects, using Transformer we can return a list of domain object  
    //      fullTextQuery.setResultTransformer(Transformers.aliasToBean(Volume.class));
    //
    //      List<Volume> listVolumes = fullTextQuery.list();
    //      
    //      
    //      Comparator fieldCompare = new BeanComparator( "volNum" );
    //      Collections.sort(listVolumes, fieldCompare );
    //
    //      return listVolumes;
    //   }

    //MD: Version with SQL query   
    /**
     * {@inheritDoc}
     */
    @SuppressWarnings({ "unchecked" })
    @Override
    public List<Volume> searchVolumes(String query) throws PersistenceException {
        StringBuilder stringBuilder = new StringBuilder("FROM Volume WHERE (CONVERT(volNum, CHAR)) LIKE '");
        if (query.matches("^\\d{1,5}[a-zA-Z]{1}")) {
            //In this case we have for ex. '1a' or '418b'
            stringBuilder.append(query.toLowerCase().substring(0, query.length() - 1));
            stringBuilder.append("' AND volLetExt LIKE '");
            stringBuilder.append(query.toLowerCase().charAt(query.length() - 1));
            stringBuilder.append("' ORDER BY volNum");
        } else {
            stringBuilder.append(query.toLowerCase());
            stringBuilder.append("%' ORDER BY volNum");
        }
        Query result = getEntityManager().createQuery(stringBuilder.toString());
        if (result.getResultList().size() == 0) {
            return null;
        } else {
            List<Volume> listVolumes = result.getResultList();
            return listVolumes;
        }
    }

    /**
     * {@inheritDoc}
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Override
    public Page searchVolumes(String text, PaginationFilter paginationFilter) throws PersistenceException {
        // Create criteria objects
        CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();

        Page page = new Page(paginationFilter);

        if (paginationFilter.getTotal() == null) {
            CriteriaQuery<Long> criteriaQueryCount = criteriaBuilder.createQuery(Long.class);
            Root<Volume> rootCount = criteriaQueryCount.from(Volume.class);
            criteriaQueryCount.select(criteriaBuilder.count(rootCount));

            List<Predicate> predicates = new ArrayList<Predicate>();
            predicates.add(
                    criteriaBuilder.like((Expression) rootCount.get("serieList").get("title"), "%" + text + "%"));
            predicates.add(criteriaBuilder.like((Expression) rootCount.get("serieList").get("subTitle1"),
                    "%" + text + "%"));
            predicates.add(criteriaBuilder.like((Expression) rootCount.get("serieList").get("subTitle2"),
                    "%" + text + "%"));
            predicates.add(criteriaBuilder.like((Expression) rootCount.get("orgNotes"), "%" + text + "%"));
            predicates.add(criteriaBuilder.like((Expression) rootCount.get("recips"), "%" + text + "%"));
            predicates.add(criteriaBuilder.like((Expression) rootCount.get("researcher"), "%" + text + "%"));
            predicates.add(criteriaBuilder.like((Expression) rootCount.get("senders"), "%" + text + "%"));

            //If we omiss criteriaBuilder.or every predicate is in conjunction with others  
            criteriaQueryCount.where(criteriaBuilder.or(predicates.toArray(new Predicate[] {})));

            TypedQuery typedQueryCount = getEntityManager().createQuery(criteriaQueryCount);
            page.setTotal(new Long((Long) typedQueryCount.getSingleResult()));
        }

        CriteriaQuery<Volume> criteriaQuery = criteriaBuilder.createQuery(Volume.class);
        Root<Volume> root = criteriaQuery.from(Volume.class);

        //We need to duplicate predicates beacause they are link to Root element
        List<Predicate> predicates = new ArrayList<Predicate>();
        predicates.add(criteriaBuilder.like((Expression) root.get("serieList").get("title"), "%" + text + "%"));
        predicates.add(criteriaBuilder.like((Expression) root.get("serieList").get("subTitle1"), "%" + text + "%"));
        predicates.add(criteriaBuilder.like((Expression) root.get("serieList").get("subTitle2"), "%" + text + "%"));
        predicates.add(criteriaBuilder.like((Expression) root.get("orgNotes"), "%" + text + "%"));
        predicates.add(criteriaBuilder.like((Expression) root.get("recips"), "%" + text + "%"));
        predicates.add(criteriaBuilder.like((Expression) root.get("researcher"), "%" + text + "%"));
        predicates.add(criteriaBuilder.like((Expression) root.get("senders"), "%" + text + "%"));

        //If we omiss criteriaBuilder.or every predicate is in conjunction with others  
        criteriaQuery.where(criteriaBuilder.or(predicates.toArray(new Predicate[] {})));
        criteriaQuery.orderBy(criteriaBuilder.asc(root.get("summaryId")));

        // Set values in predicate's elements  
        TypedQuery<Volume> typedQuery = getEntityManager().createQuery(criteriaQuery);
        typedQuery.setFirstResult(paginationFilter.getFirstRecord());
        typedQuery.setMaxResults(paginationFilter.getLength());
        page.setList(typedQuery.getResultList());

        return page;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Page searchVolumesByDigitization(Integer volNum, Integer volNumBetween,
            PaginationFilter paginationFilter) throws PersistenceException {
        Page page = new Page(paginationFilter);

        Query query = null;
        //String toSearch = new String("FROM People WHERE personId IN (SELECT DISTINCT person.personId FROM org.medici.bia.domain.PoLink WHERE titleOccList.titleOccId=" + titleOccToSearch + ")");
        //MD: The next query is builded for test if is possible order result by date of Title Occupation
        String toSearch = new String("FROM Volume WHERE volNum >= " + volNum + " AND volNum <= " + volNumBetween
                + " AND logicalDelete = false");

        if (paginationFilter.getTotal() == null) {
            String countQuery = "SELECT COUNT(*) " + toSearch;
            query = getEntityManager().createQuery(countQuery);
            page.setTotal(new Long((Long) query.getSingleResult()));
        }

        //MD: We have a pagination filter already parameterized
        //paginationFilter = generatePaginationFilterMYSQL(paginationFilter);

        query = getEntityManager().createQuery(toSearch + getOrderByQuery(paginationFilter.getSortingCriterias()));

        query.setFirstResult(paginationFilter.getFirstRecord());
        query.setMaxResults(paginationFilter.getLength());

        page.setList(query.getResultList());

        return page;
    }

    @Override
    public Integer updateNewDigitizedVolume(List<Integer> summaryIds) throws PersistenceException {
        String hql = "UPDATE Volume set digitized=true where summaryId in (:summaryIds)";

        Query query = getEntityManager().createQuery(hql);

        query.setParameter("summaryIds", summaryIds);

        return query.executeUpdate();
    }
}