package fi.otavanopisto.pyramus.dao.resources; import java.util.Set; import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.PersistenceException; import org.apache.commons.lang.StringUtils; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.queryparser.classic.ParseException; import org.apache.lucene.queryparser.classic.QueryParser; import org.apache.lucene.search.MatchAllDocsQuery; import org.apache.lucene.search.Query; import org.apache.lucene.search.Sort; import org.apache.lucene.search.SortField; import org.hibernate.search.jpa.FullTextEntityManager; import org.hibernate.search.jpa.FullTextQuery; import org.hibernate.search.jpa.Search; import fi.otavanopisto.pyramus.dao.PyramusEntityDAO; import fi.otavanopisto.pyramus.domainmodel.base.Tag; import fi.otavanopisto.pyramus.domainmodel.resources.MaterialResource; import fi.otavanopisto.pyramus.domainmodel.resources.Resource; import fi.otavanopisto.pyramus.domainmodel.resources.ResourceCategory; import fi.otavanopisto.pyramus.domainmodel.resources.ResourceType; import fi.otavanopisto.pyramus.domainmodel.resources.WorkResource; import fi.otavanopisto.pyramus.persistence.search.SearchResult; @Stateless public class ResourceDAO extends PyramusEntityDAO<Resource> { @SuppressWarnings("unchecked") public SearchResult<Resource> searchResourcesBasic(int resultsPerPage, int page, String queryText) { int firstResult = page * resultsPerPage; StringBuilder queryBuilder = new StringBuilder(); if (!StringUtils.isBlank(queryText)) { queryBuilder.append("+("); addTokenizedSearchCriteria(queryBuilder, "name", queryText, false); addTokenizedSearchCriteria(queryBuilder, "tags.text", queryText, false); queryBuilder.append(")"); } EntityManager entityManager = getEntityManager(); FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager); try { QueryParser parser = new QueryParser("", new StandardAnalyzer()); String queryString = queryBuilder.toString(); Query luceneQuery; if (StringUtils.isBlank(queryString)) { luceneQuery = new MatchAllDocsQuery(); } else { luceneQuery = parser.parse(queryString); } FullTextQuery query = (FullTextQuery) fullTextEntityManager.createFullTextQuery(luceneQuery, WorkResource.class, MaterialResource.class) .setSort(new Sort(new SortField[]{SortField.FIELD_SCORE, new SortField("nameSortable", SortField.Type.STRING)})) .setFirstResult(firstResult) .setMaxResults(resultsPerPage); query.setFirstResult(firstResult).setMaxResults(resultsPerPage); query.enableFullTextFilter("ArchivedResource").setParameter("archived", Boolean.FALSE); int hits = query.getResultSize(); int pages = hits / resultsPerPage; if (hits % resultsPerPage > 0) { pages++; } int lastResult = firstResult + resultsPerPage - 1; if (lastResult > hits - 1) { lastResult = hits - 1; } return new SearchResult<>(page, pages, hits, firstResult, lastResult, query.getResultList()); } catch (ParseException e) { throw new PersistenceException(e); } } @SuppressWarnings("unchecked") public SearchResult<Resource> searchResources(int resultsPerPage, int page, String name, String tags, ResourceType resourceType, ResourceCategory resourceCategory, boolean filterArchived) { int firstResult = page * resultsPerPage; StringBuilder queryBuilder = new StringBuilder(); if (!StringUtils.isBlank(name)) { addTokenizedSearchCriteria(queryBuilder, "name", name, true); } if (!StringUtils.isBlank(tags)) { addTokenizedSearchCriteria(queryBuilder, "tags.text", tags, true); } if (resourceCategory != null) { addTokenizedSearchCriteria(queryBuilder, "category.id", resourceCategory.getId().toString(), true); } EntityManager entityManager = getEntityManager(); FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager); try { QueryParser parser = new QueryParser("", new StandardAnalyzer()); String queryString = queryBuilder.toString(); Query luceneQuery; if (StringUtils.isBlank(queryString)) { luceneQuery = new MatchAllDocsQuery(); } else { luceneQuery = parser.parse(queryString); } FullTextQuery query; if (resourceType == null) { query = (FullTextQuery) fullTextEntityManager.createFullTextQuery(luceneQuery, WorkResource.class, MaterialResource.class) .setSort(new Sort(new SortField[]{SortField.FIELD_SCORE, new SortField("nameSortable", SortField.Type.STRING)})) .setFirstResult(firstResult) .setMaxResults(resultsPerPage); } else { switch (resourceType) { case MATERIAL_RESOURCE: query = (FullTextQuery) fullTextEntityManager.createFullTextQuery(luceneQuery, MaterialResource.class) .setSort(new Sort(new SortField[]{SortField.FIELD_SCORE, new SortField("nameSortable", SortField.Type.STRING)})) .setFirstResult(firstResult) .setMaxResults(resultsPerPage); break; case WORK_RESOURCE: query = (FullTextQuery) fullTextEntityManager.createFullTextQuery(luceneQuery, WorkResource.class) .setSort(new Sort(new SortField[]{SortField.FIELD_SCORE, new SortField("nameSortable", SortField.Type.STRING)})) .setFirstResult(firstResult) .setMaxResults(resultsPerPage); break; default: throw new PersistenceException("Invalid resource type"); } } query.setFirstResult(firstResult).setMaxResults(resultsPerPage); if (filterArchived) { query.enableFullTextFilter("ArchivedResource").setParameter("archived", Boolean.FALSE); } int hits = query.getResultSize(); int pages = hits / resultsPerPage; if (hits % resultsPerPage > 0) { pages++; } int lastResult = firstResult + resultsPerPage - 1; if (lastResult > hits - 1) { lastResult = hits - 1; } return new SearchResult<>(page, pages, hits, firstResult, lastResult, query.getResultList()); } catch (ParseException e) { throw new PersistenceException(e); } } public void setResourceTags(Resource resource, Set<Tag> tags) { EntityManager entityManager = getEntityManager(); resource.setTags(tags); entityManager.persist(resource); } public void archiveResource(Resource resource) { EntityManager entityManager = getEntityManager(); resource.setArchived(Boolean.TRUE); entityManager.persist(resource); } public void unarchiveResource(Resource resource) { EntityManager entityManager = getEntityManager(); resource.setArchived(Boolean.FALSE); entityManager.persist(resource); } @Override public void delete(Resource resource) { super.delete(resource); } }