Salome HOME
Search knowledge is implemented. Unit tests are improved. Lucene index is not used...
[tools/siman.git] / Workspace / Siman-Common / src / org / splat / service / SearchServiceImpl.java
index 7e62fd613ac69429ad80e180a0ca10fc9e6b26e6..34053560dacc1fe796de3d308da03b26b447cc10 100644 (file)
@@ -16,6 +16,7 @@ import java.util.Iterator;
 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;
@@ -46,9 +47,12 @@ import org.splat.dal.bo.som.Scenario;
 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;
@@ -86,6 +90,10 @@ public class SearchServiceImpl implements SearchService {
         * 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.
@@ -133,11 +141,104 @@ public class SearchServiceImpl implements SearchService {
                }
        }
 
+       /**
+        * {@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>();
@@ -227,7 +328,7 @@ public class SearchServiceImpl implements SearchService {
                        }
                        if (LOG.isInfoEnabled()) {
                                LOG.info("Searching knowledges by Lucene query \""
-                                               + fulquery.toString() + "\".");
+                                               + fulquery.toString());
                        }
                        // Creation of the knowledge filter
                        BooleanFilter filter = new BooleanFilter();
@@ -263,33 +364,18 @@ public class SearchServiceImpl implements SearchService {
        /**
         * {@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())) {
@@ -318,7 +404,7 @@ public class SearchServiceImpl implements SearchService {
                query.addOrder(Order.asc("title"));
 
                if (LOG.isInfoEnabled()) {
-                       LOG.info("Searching studies: \"" + query.toString() + "\".");
+                       LOG.info("Searching studies: \"" + query.toString());
                }
 
                // Search
@@ -360,11 +446,71 @@ public class SearchServiceImpl implements SearchService {
 
                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
@@ -398,7 +544,8 @@ public class SearchServiceImpl implements SearchService {
                                                                                        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;
        }
@@ -414,14 +561,7 @@ public class SearchServiceImpl implements SearchService {
        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
@@ -434,6 +574,27 @@ public class SearchServiceImpl implements SearchService {
 
        }
 
+       /**
+        * 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}
         * 
@@ -534,7 +695,7 @@ public class SearchServiceImpl implements SearchService {
                        }
                        if (LOG.isInfoEnabled()) {
                                LOG.info("Searching studies by Lucene query \""
-                                               + fulquery.toString() + "\".");
+                                               + fulquery.toString());
                        }
                        // Creation of the studies filter
                        BooleanFilter filter = new BooleanFilter();
@@ -618,6 +779,11 @@ public class SearchServiceImpl implements SearchService {
         */
        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
                }
@@ -699,4 +865,24 @@ public class SearchServiceImpl implements SearchService {
        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;
+       }
 }