package fi.otavanopisto.pyramus.dao.projects;
import java.util.Date;
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.EducationalTimeUnit;
import fi.otavanopisto.pyramus.domainmodel.base.Tag;
import fi.otavanopisto.pyramus.domainmodel.projects.Project;
import fi.otavanopisto.pyramus.domainmodel.users.User;
import fi.otavanopisto.pyramus.persistence.search.SearchResult;
@Stateless
public class ProjectDAO extends PyramusEntityDAO<Project> {
public Project create(String name, String description, Double optionalStudiesLength,
EducationalTimeUnit optionalStudiesLengthTimeUnit, User creatingUser) {
EntityManager entityManager = getEntityManager();
Date now = new Date(System.currentTimeMillis());
Project project = new Project();
project.setName(name);
project.setDescription(description);
project.getOptionalStudiesLength().setUnit(optionalStudiesLengthTimeUnit);
project.getOptionalStudiesLength().setUnits(optionalStudiesLength);
project.setCreator(creatingUser);
project.setCreated(now);
project.setLastModifier(creatingUser);
project.setLastModified(now);
entityManager.persist(project);
return project;
}
public Project updateTags(Project project, Set<Tag> tags) {
EntityManager entityManager = getEntityManager();
project.setTags(tags);
entityManager.persist(project);
return project;
}
public Project update(Project project, String name, String description, Double optionalStudiesLength,
EducationalTimeUnit optionalStudiesLengthTimeUnit, User user) {
EntityManager entityManager = getEntityManager();
Date now = new Date(System.currentTimeMillis());
project.setName(name);
project.setDescription(description);
project.getOptionalStudiesLength().setUnit(optionalStudiesLengthTimeUnit);
project.getOptionalStudiesLength().setUnits(optionalStudiesLength);
project.setLastModifier(user);
project.setLastModified(now);
entityManager.persist(project);
return project;
}
@SuppressWarnings("unchecked")
public SearchResult<Project> searchProjectsBasic(int resultsPerPage, int page, String text) {
int firstResult = page * resultsPerPage;
StringBuilder queryBuilder = new StringBuilder();
if (!StringUtils.isBlank(text)) {
queryBuilder.append("+(");
addTokenizedSearchCriteria(queryBuilder, "name", text, false);
addTokenizedSearchCriteria(queryBuilder, "description", text, false);
addTokenizedSearchCriteria(queryBuilder, "tags.text", text, 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, Project.class)
.setSort(new Sort(new SortField[]{SortField.FIELD_SCORE, new SortField("nameSortable", SortField.Type.STRING)}))
.setFirstResult(firstResult)
.setMaxResults(resultsPerPage);
query.enableFullTextFilter("ArchivedProject").setParameter("archived", Boolean.FALSE);
int hits = query.getResultSize();
int pages = hits / resultsPerPage;
if (hits % resultsPerPage > 0) {
pages++;
}
int lastResult = Math.min(firstResult + resultsPerPage, hits) - 1;
return new SearchResult<>(page, pages, hits, firstResult, lastResult, query.getResultList());
}
catch (ParseException e) {
throw new PersistenceException(e);
}
}
/**
* Returns a list of projects matching the given search terms.
*
* @param resultsPerPage
* The amount of projects per page
* @param page
* The search results page
* @param name
* The project name
* @param description
* The project description
* @param tags
* The projects tags
* @param filterArchived
* <code>true</code> if archived projects should be omitted, otherwise <code>false</code>
*
* @return A list of projects matching the given search terms
*/
@SuppressWarnings("unchecked")
public SearchResult<Project> searchProjects(int resultsPerPage, int page, String name, String description, String tags, boolean filterArchived) {
int firstResult = page * resultsPerPage;
StringBuilder queryBuilder = new StringBuilder();
if (!StringUtils.isBlank(name)) {
addTokenizedSearchCriteria(queryBuilder, "name", name, false);
}
if (!StringUtils.isBlank(description)) {
addTokenizedSearchCriteria(queryBuilder, "description", description, false);
}
if (!StringUtils.isBlank(tags)) {
addTokenizedSearchCriteria(queryBuilder, "tags.text", tags, false);
}
EntityManager entityManager = getEntityManager();
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
try {
String queryString = queryBuilder.toString();
Query luceneQuery;
QueryParser parser = new QueryParser("", new StandardAnalyzer());
if (StringUtils.isBlank(queryString)) {
luceneQuery = new MatchAllDocsQuery();
} else {
luceneQuery = parser.parse(queryString);
}
FullTextQuery query = (FullTextQuery) fullTextEntityManager.createFullTextQuery(luceneQuery, Project.class)
.setSort(new Sort(new SortField[] { SortField.FIELD_SCORE, new SortField("nameSortable", SortField.Type.STRING) })).setFirstResult(firstResult)
.setMaxResults(resultsPerPage);
if (filterArchived) {
query.enableFullTextFilter("ArchivedProject").setParameter("archived", Boolean.FALSE);
}
int hits = query.getResultSize();
int pages = hits / resultsPerPage;
if (hits % resultsPerPage > 0) {
pages++;
}
int lastResult = Math.min(firstResult + resultsPerPage, hits) - 1;
return new SearchResult<>(page, pages, hits, firstResult, lastResult, query.getResultList());
} catch (ParseException e) {
throw new PersistenceException(e);
}
}
public Project removeTag(Project project, Tag tag) {
project.removeTag(tag);
return persist(project);
}
}