import java.util.List;
import org.apache.log4j.Logger;
+import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanFilter;
import org.splat.dal.bo.som.SimulationContext;
import org.splat.dal.bo.som.Study;
import org.splat.dal.bo.som.Visibility;
+import org.splat.dal.dao.som.KnowledgeElementDAO;
import org.splat.dal.dao.som.StudyDAO;
import org.splat.service.dto.ImportedStudyDTO;
+import org.splat.service.dto.KnowledgeSearchFilterDTO;
import org.splat.service.dto.Proxy;
+import org.splat.service.dto.SearchFilterDTO;
import org.splat.service.dto.StudyDTO;
import org.splat.service.dto.StudySearchFilterDTO;
import org.splat.service.technical.IndexService;
* Injected study DAO.
*/
private StudyDAO _studyDAO;
+ /**
+ * Injected knowledge element DAO.
+ */
+ private KnowledgeElementDAO _knowledgeElementDAO;
/**
* Get a list of studies which are currently not presented in the lucene index.
}
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.splat.service.SearchService#selectKnowledgeElementsWhere(org.splat.service.dto.KnowledgeSearchFilterDTO)
+ */
+ public List<Proxy> selectKnowledgeElementsWhere(
+ final KnowledgeSearchFilterDTO filter) {
+ List<Proxy> result = new ArrayList<Proxy>();
+
+ // Search matching all criteria
+ DetachedCriteria query = DetachedCriteria.forClass(
+ KnowledgeElement.class, "kelm");
+ query.createAlias("kelm.owner", "scen", Criteria.INNER_JOIN)
+ .createCriteria("scen.owner", "study", Criteria.INNER_JOIN)
+ .add(visibleStudyFilter(filter));
+
+ // Creation of the query
+ Junction topJunction = initQuery(filter);
+
+ addByWordsCriteria(topJunction, filter);
+
+ List<SimulationContext> context = filter.getSimContexts();
+ if (context != null && (!context.isEmpty())) {
+ // Get only studies which have given contexts
+ query.createAlias("study.contex", "ctx", Criteria.INNER_JOIN);
+ Junction critctx;
+ if (filter.isMatchAllContexts()) { // AND
+ critctx = Restrictions.conjunction();
+ } else { // OR
+ critctx = Restrictions.disjunction();
+ }
+ for (SimulationContext seltext : context) {
+ // (simctxType = seltext.getType() AND simctxValue = seltext.getValue())
+ critctx.add(Restrictions.and(Restrictions.eq("ctx.value",
+ seltext.getValue()), Restrictions.eq("ctx.type",
+ seltext.getType())));
+
+ }
+ topJunction.add(critctx);
+ }
+
+ query.add(topJunction);
+ // Group by study
+ query.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
+ // Creation of the sort criteria
+ query.addOrder(Order.asc("title"));
+
+ if (LOG.isInfoEnabled()) {
+ LOG.info("Searching knowledge elements: \"" + query.toString());
+ }
+
+ // Search
+ List<KnowledgeElement> found = getKnowledgeElementDAO()
+ .getFilteredList(query);
+
+ // Construction of the result list
+ for (KnowledgeElement kelm : found) {
+ result.add(new StudyDTO(kelm.getIndex(), kelm.getReference(), kelm
+ .getProgressState(), kelm.getTitle(), kelm.getAuthor()
+ .getDisplayName()));
+ }
+ return result;
+ }
+
+ /**
+ * Add search criteria for filtering by title contents.
+ *
+ * @param topJunction
+ * the search condition to be appended
+ * @param filter
+ * the criteria
+ */
+ private void addByWordsCriteria(final Junction topJunction,
+ final SearchFilterDTO filter) {
+ String title = filter.getWords(); // Title
+ if (title != null && (!title.isEmpty())) {
+ // Look for given words in titles
+ Junction critext;
+ if (filter.isMatchAllCriteria()) { // AND
+ critext = Restrictions.conjunction();
+ } else { // OR
+ critext = Restrictions.disjunction();
+ }
+
+ String[] word = title.split(" ");
+ for (int j = 0; j < word.length; j++) {
+ critext.add(Restrictions.like("title", "%" + word[j] + "%"));
+ }
+ topJunction.add(critext);
+ }
+ }
+
/**
* {@inheritDoc}
*
* @see org.splat.service.SearchService#selectKnowledgeElementsWhere(org.splat.dal.bo.som.KnowledgeElement.Properties[])
*/
+ @Deprecated
public List<Proxy> selectKnowledgeElementsWhere(
final KnowledgeElement.Properties... kprop) {
List<Proxy> result = new ArrayList<Proxy>();
}
if (LOG.isInfoEnabled()) {
LOG.info("Searching knowledges by Lucene query \""
- + fulquery.toString() + "\".");
+ + fulquery.toString());
}
// Creation of the knowledge filter
BooleanFilter filter = new BooleanFilter();
/**
* {@inheritDoc}
*
- * @see org.splat.service.SearchService#selectStudiesWhere(org.splat.dal.bo.som.Study.Properties[])
+ * @see org.splat.service.SearchService#selectStudiesWhere(org.splat.service.dto.StudySearchFilterDTO)
*/
public List<Proxy> selectStudiesWhere(final StudySearchFilterDTO filter) {
List<Proxy> result = new ArrayList<Proxy>();
DetachedCriteria query = DetachedCriteria
- .forClass(Study.class, "study");
+ .forClass(Study.class, "study").add(visibleStudyFilter(filter));
// Creation of the query
Junction topJunction = initQuery(filter);
- String title = filter.getWords(); // Title
- if (title != null && (!title.isEmpty())) {
- // Look for given words in study titles
- Junction critext;
- if (filter.isMatchAllCriteria()) { // AND
- critext = Restrictions.conjunction();
- } else { // OR
- critext = Restrictions.disjunction();
- }
-
- String[] word = title.split(" ");
- for (int j = 0; j < word.length; j++) {
- critext.add(Restrictions.like("title", "%" + word[j] + "%"));
- }
- topJunction.add(critext);
- }
+ addByWordsCriteria(topJunction, filter);
List<SimulationContext> context = filter.getSimContexts();
if (context != null && (!context.isEmpty())) {
query.addOrder(Order.asc("title"));
if (LOG.isInfoEnabled()) {
- LOG.info("Searching studies: \"" + query.toString() + "\".");
+ LOG.info("Searching studies: \"" + query.toString());
}
// Search
addDatesCriteria(topJunction, filter);
+ // Filter by study author
long authorId = Long.valueOf(filter.getAuthor());
- if (authorId > 0) { // Author
+ if (authorId > 0) {
topJunction.add(Restrictions.eq("manager.rid", authorId));
}
+ return topJunction;
+ }
+
+ /**
+ * Initialize query with base criteria.
+ *
+ * @param filter
+ * the criteria
+ * @return top junction of the search filter
+ */
+ private Junction initQuery(final KnowledgeSearchFilterDTO filter) {
+ Junction topJunction;
+ if (filter.isMatchAllCriteria()) { // AND
+ topJunction = Restrictions.conjunction();
+ } else { // OR
+ topJunction = Restrictions.disjunction();
+ }
+
+ // Filter by knowledge type
+ long ktypeId = Long.valueOf(filter.getKtype());
+ if (ktypeId > 0) {
+ topJunction.add(Restrictions.eq("kelm.type.rid", ktypeId));
+ }
+
+ String refid = filter.getReference(); // Reference
+ if (refid != null && !refid.isEmpty()) {
+ long id = Long.valueOf(refid.replaceAll("^KE(0)*", ""));
+ if (id > 0) {
+ topJunction.add(Restrictions.eq("kelm.rid", id));
+ }
+ }
+
+ addCreationDateCriteria(topJunction, filter, "date");
+
+ // Filter by knowledge author
+ long authorId = Long.valueOf(filter.getAuthor());
+ if (authorId > 0) {
+ topJunction.add(Restrictions.eq("kelm.author.rid", authorId));
+ }
+
+ return topJunction;
+ }
+
+ /**
+ * Filter for visible studies.
+ *
+ * @param filter
+ * search criteria
+ * @return search condition for studies to get only visible studies
+ */
+ private Junction visibleStudyFilter(final SearchFilterDTO filter) {
+ Junction topJunction;
+ if (filter.isMatchAllCriteria()) { // AND
+ topJunction = Restrictions.conjunction();
+ } else { // OR
+ topJunction = Restrictions.disjunction();
+ }
+
+ // Filter by connected user
long actorId = filter.getConnectedUserId(); // Contributor, Reviewer or Approver
if (actorId > 0) {
// User is loggen in - show public studies and studies where he is participating
Visibility.PUBLIC)));
} else {
// User is not logged in - show only public studies
- topJunction.add(Restrictions.eq("visibility", Visibility.PUBLIC));
+ topJunction.add(Restrictions.eq("study.visibility",
+ Visibility.PUBLIC));
}
return topJunction;
}
private void addDatesCriteria(final Junction topJunction,
final StudySearchFilterDTO filter) {
// Filter by creation date
- if (filter.getCreatedAfter() != null) {
- topJunction.add(Restrictions
- .gt("credate", filter.getCreatedAfter()));
- }
- if (filter.getCreatedBefore() != null) {
- topJunction.add(Restrictions.lt("credate", filter
- .getCreatedBefore()));
- }
+ addCreationDateCriteria(topJunction, filter, "credate");
// Filter by modification date
if (filter.getUpdatedAfter() != null) {
topJunction.add(Restrictions
}
+ /**
+ * Add search criteria by dates to the junction filter condition.
+ *
+ * @param topJunction
+ * the junction filter condition
+ * @param filter
+ * search criteria
+ */
+ private void addCreationDateCriteria(final Junction topJunction,
+ final SearchFilterDTO filter, final String propName) {
+ // Filter by creation date
+ if (filter.getCreatedAfter() != null) {
+ topJunction.add(Restrictions
+ .gt(propName, filter.getCreatedAfter()));
+ }
+ if (filter.getCreatedBefore() != null) {
+ topJunction.add(Restrictions.lt(propName, filter
+ .getCreatedBefore()));
+ }
+ }
+
/**
* {@inheritDoc}
*
}
if (LOG.isInfoEnabled()) {
LOG.info("Searching studies by Lucene query \""
- + fulquery.toString() + "\".");
+ + fulquery.toString());
}
// Creation of the studies filter
BooleanFilter filter = new BooleanFilter();
*/
private IndexService getIndex() throws IOException {
IndexService lucin = getIndexService();
+ if (IndexWriter.isLocked(FSDirectory.open(getRepositoryService()
+ .getRepositoryIndexDirectory()))) {
+ IndexWriter.unlock(FSDirectory.open(getRepositoryService()
+ .getRepositoryIndexDirectory()));
+ }
if (!lucin.exists()) {
lucin.create(); // Happens when re-indexing all studies
}
public void setStudyDAO(final StudyDAO studyDAO) {
_studyDAO = studyDAO;
}
+
+ /**
+ * Get the knowledgeElementDAO.
+ *
+ * @return the knowledgeElementDAO
+ */
+ public KnowledgeElementDAO getKnowledgeElementDAO() {
+ return _knowledgeElementDAO;
+ }
+
+ /**
+ * Set the knowledgeElementDAO.
+ *
+ * @param knowledgeElementDAO
+ * the knowledgeElementDAO to set
+ */
+ public void setKnowledgeElementDAO(
+ final KnowledgeElementDAO knowledgeElementDAO) {
+ _knowledgeElementDAO = knowledgeElementDAO;
+ }
}