]> SALOME platform Git repositories - tools/siman.git/blob - Workspace/Siman-Common/src/org/splat/service/SearchServiceImpl.java
Salome HOME
Reindex of studies is fixed.
[tools/siman.git] / Workspace / Siman-Common / src / org / splat / service / SearchServiceImpl.java
1 /*****************************************************************************
2  * Company         OPEN CASCADE
3  * Application     SIMAN
4  * File            $Id$ 
5  * Creation date   05.10.2012
6  * @author         $Author$
7  * @version        $Revision$
8  *****************************************************************************/
9
10 package org.splat.service;
11
12 import java.io.File;
13 import java.io.IOException;
14 import java.util.ArrayList;
15 import java.util.Iterator;
16 import java.util.List;
17
18 import org.apache.log4j.Logger;
19 import org.apache.lucene.index.Term;
20 import org.apache.lucene.search.BooleanClause;
21 import org.apache.lucene.search.BooleanFilter;
22 import org.apache.lucene.search.BooleanQuery;
23 import org.apache.lucene.search.FilterClause;
24 import org.apache.lucene.search.IndexSearcher;
25 import org.apache.lucene.search.ScoreDoc;
26 import org.apache.lucene.search.Sort;
27 import org.apache.lucene.search.SortField;
28 import org.apache.lucene.search.TermQuery;
29 import org.apache.lucene.search.TermsFilter;
30 import org.apache.lucene.search.TopFieldDocs;
31 import org.apache.lucene.store.Directory;
32 import org.apache.lucene.store.FSDirectory;
33 import org.splat.dal.bo.kernel.User;
34 import org.splat.dal.bo.som.KnowledgeElement;
35 import org.splat.dal.bo.som.KnowledgeElementType;
36 import org.splat.dal.bo.som.ProgressState;
37 import org.splat.dal.bo.som.Scenario;
38 import org.splat.dal.bo.som.SimulationContext;
39 import org.splat.dal.bo.som.Study;
40 import org.splat.dal.bo.som.Visibility;
41 import org.splat.service.dto.Proxy;
42 import org.splat.service.technical.IndexService;
43 import org.splat.service.technical.IndexServiceImpl;
44 import org.splat.service.technical.RepositoryService;
45 import org.springframework.transaction.annotation.Transactional;
46
47 /**
48  * Search service implementation.
49  * 
50  * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
51  */
52 public class SearchServiceImpl implements SearchService {
53
54         /**
55          * The service logger.
56          */
57         public final static Logger logger = Logger
58                         .getLogger(org.splat.service.SearchServiceImpl.class);
59
60         /**
61          * Injected repository service.
62          */
63         private RepositoryService _repositoryService;
64         /**
65          * Injected index service.
66          */
67         private IndexService _indexService;
68
69         /**
70          * Injected study service.
71          */
72         private StudyService _studyService;
73
74         /**
75          * Refresh lucene index for studies.
76          * 
77          * @param ridlist
78          *            list of studies id's
79          */
80         @Transactional(readOnly = true)
81         public void reindexStudies(String[] ridlist) {
82                 for (int i = 0; i < ridlist.length; i++) {
83                         long index = Long.valueOf(ridlist[i].trim());
84                         Study study = getStudyService().selectStudy(index);
85                         indexStudy(study);
86                 }
87         }
88
89         /**
90          * {@inheritDoc}
91          * 
92          * @see org.splat.service.SearchService#selectKnowledgeElementsWhere(org.splat.dal.bo.som.KnowledgeElement.Properties[])
93          */
94         public List<Proxy> selectKnowledgeElementsWhere(
95                         KnowledgeElement.Properties... kprop) {
96                 List<Proxy> result = new ArrayList<Proxy>();
97                 int hitsize = 20;
98                 try {
99
100                         // Creation of the Lucene query
101                         File indir = getRepositoryService().getRepositoryIndexDirectory();
102                         Directory index = FSDirectory.open(indir);
103                         IndexSearcher searcher = new IndexSearcher(index, true);
104                         BooleanQuery fulquery = new BooleanQuery();
105
106                         for (int i = 0; i < kprop.length; i++) {
107                                 BooleanQuery query = new BooleanQuery();
108                                 Term input; // Supposed initialized below at least by the visibility
109
110                                 Visibility area = kprop[i].getVisibility(); // Visibility
111                                 if (area != null) {
112                                         input = new Term("area");
113                                         query.add(new TermQuery(input.createTerm(area.toString())),
114                                                         BooleanClause.Occur.MUST);
115                                 }
116                                 ProgressState state = kprop[i].getProgressState(); // State
117                                 if (state != null) {
118                                         input = new Term("state");
119                                         query.add(
120                                                         new TermQuery(input.createTerm(state.toString())),
121                                                         BooleanClause.Occur.MUST);
122                                 }
123                                 String refid = kprop[i].getReference(); // Reference
124                                 if (refid != null) {
125                                         input = new Term("ref");
126                                         query.add(new TermQuery(input.createTerm(refid)),
127                                                         BooleanClause.Occur.MUST);
128                                 }
129                                 KnowledgeElementType type = kprop[i].getType(); // Type
130                                 if (type != null) {
131                                         input = new Term("type");
132                                         query.add(new TermQuery(input.createTerm(type.getName())),
133                                                         BooleanClause.Occur.MUST);
134                                 }
135                                 User manager = kprop[i].getAuthor(); // Author
136                                 if (manager != null) {
137                                         input = new Term("author");
138                                         query.add(new TermQuery(input
139                                                         .createTerm(manager.toString())),
140                                                         BooleanClause.Occur.MUST);
141                                 }
142                                 User actor = kprop[i].getActor(); // Contributor, Reviewer or Approver of the owner study
143                                 if (actor != null) {
144                                         input = new Term("actor");
145                                         query.add(
146                                                         new TermQuery(input.createTerm(actor.toString())),
147                                                         BooleanClause.Occur.MUST);
148                                 }
149                                 String title = kprop[i].getTitle(); // Title
150                                 if (title != null) {
151                                         input = new Term("contents");
152                                         BooleanQuery critext = new BooleanQuery();
153                                         String operator = "AND"; // Future user input
154                                         BooleanClause.Occur clause = BooleanClause.Occur.MUST;
155                                         if (operator.equals("OR"))
156                                                 clause = BooleanClause.Occur.SHOULD;
157                                         String[] word = title.split(" ");
158                                         for (int j = 0; j < word.length; j++) {
159                                                 critext.add(new TermQuery(input.createTerm(word[j])),
160                                                                 clause);
161                                         }
162                                         query.add(critext, BooleanClause.Occur.MUST);
163                                 }
164                                 List<SimulationContext> context = kprop[i]
165                                                 .getSimulationContexts();
166                                 if (context != null && context.size() > 0) {
167                                         BooleanQuery critext = new BooleanQuery();
168                                         for (Iterator<SimulationContext> j = context.iterator(); j
169                                                         .hasNext();) {
170                                                 SimulationContext seltext = j.next();
171                                                 input = new Term(String.valueOf(seltext.getType()
172                                                                 .getIndex()));
173                                                 critext.add(new TermQuery(input.createTerm(seltext
174                                                                 .getValue())), BooleanClause.Occur.MUST);
175                                         }
176                                         query.add(critext, BooleanClause.Occur.MUST);
177                                 }
178                                 fulquery.add(query, BooleanClause.Occur.SHOULD);
179                         }
180                         if (logger.isInfoEnabled()) {
181                                 logger.info("Searching knowledges by Lucene query \""
182                                                 + fulquery.toString() + "\".");
183                         }
184                         // Creation of the knowledge filter
185                         BooleanFilter filter = new BooleanFilter();
186                         TermsFilter select = new TermsFilter();
187                         Term mytype = new Term("class");
188                         select.addTerm(mytype.createTerm("KnowledgeElement"));
189                         filter.add(new FilterClause(select, BooleanClause.Occur.SHOULD));
190
191                         // Creation of the sort criteria
192                         Sort sort = new Sort(new SortField("title", SortField.STRING));
193
194                         // Search
195                         TopFieldDocs found = searcher.search(fulquery, filter, hitsize,
196                                         sort);
197
198                         if (found.totalHits < 1)
199                                 return result; // No study found
200
201                         // Construction of the result list
202                         ScoreDoc[] hits = found.scoreDocs;
203                         for (int i = 0; i < hits.length; i++) {
204                                 result.add(new IndexServiceImpl.ObjectProxy(searcher
205                                                 .doc(hits[i].doc)));
206                         }
207                         searcher.close();
208                 } catch (Exception error) {
209                         logger.error("Error during Lucene search, reason:", error);
210                 }
211                 return result;
212         }
213
214         /**
215          * {@inheritDoc}
216          * 
217          * @see org.splat.service.SearchService#selectStudiesWhere(org.splat.dal.bo.som.Study.Properties[])
218          */
219         public List<Proxy> selectStudiesWhere(Study.Properties... sprop) {
220                 List<Proxy> result = new ArrayList<Proxy>();
221                 int hitsize = 20;
222                 try {
223
224                         // Creation of the Lucene query
225                         File indir = getRepositoryService().getRepositoryIndexDirectory();
226                         Directory index = FSDirectory.open(indir);
227                         IndexSearcher searcher = new IndexSearcher(index, true);
228                         BooleanQuery fulquery = new BooleanQuery();
229
230                         for (int i = 0; i < sprop.length; i++) {
231                                 BooleanQuery query = new BooleanQuery();
232                                 Term input; // Supposed initialized below at least by the visibility
233
234                                 Visibility area = sprop[i].getVisibility(); // Visibility
235                                 if (area != null) {
236                                         input = new Term("area");
237                                         query.add(new TermQuery(input.createTerm(area.toString())),
238                                                         BooleanClause.Occur.MUST);
239                                 }
240                                 ProgressState state = sprop[i].getProgressState(); // State
241                                 if (state != null) {
242                                         input = new Term("state");
243                                         if (state == ProgressState.inPROGRESS) {
244                                                 BooleanQuery cristate = new BooleanQuery();
245                                                 cristate.add(new TermQuery(input.createTerm("inWORK")),
246                                                                 BooleanClause.Occur.SHOULD);
247                                                 cristate.add(
248                                                                 new TermQuery(input.createTerm("inDRAFT")),
249                                                                 BooleanClause.Occur.SHOULD);
250                                                 cristate.add(
251                                                                 new TermQuery(input.createTerm("inCHECK")),
252                                                                 BooleanClause.Occur.SHOULD);
253                                                 query.add(cristate, BooleanClause.Occur.MUST);
254                                         } else {
255                                                 query.add(new TermQuery(input.createTerm(state
256                                                                 .toString())), BooleanClause.Occur.MUST);
257                                         }
258                                 }
259                                 String refid = sprop[i].getReference(); // Reference
260                                 if (refid != null) {
261                                         input = new Term("ref");
262                                         query.add(new TermQuery(input.createTerm(refid)),
263                                                         BooleanClause.Occur.MUST);
264                                 }
265                                 User manager = sprop[i].getManager(); // Author
266                                 if (manager != null) {
267                                         input = new Term("author");
268                                         query.add(new TermQuery(input
269                                                         .createTerm(manager.toString())),
270                                                         BooleanClause.Occur.MUST);
271                                 }
272                                 User actor = sprop[i].getActor(); // Contributor, Reviewer or Approver
273                                 if (actor != null) {
274                                         input = new Term("actor");
275                                         query.add(
276                                                         new TermQuery(input.createTerm(actor.toString())),
277                                                         BooleanClause.Occur.MUST);
278                                 }
279                                 String title = sprop[i].getTitle(); // Title
280                                 if (title != null) {
281                                         input = new Term("contents");
282                                         BooleanQuery critext = new BooleanQuery();
283                                         String operator = "AND"; // Future user input
284                                         BooleanClause.Occur clause = BooleanClause.Occur.MUST;
285                                         if (operator.equals("OR"))
286                                                 clause = BooleanClause.Occur.SHOULD;
287                                         String[] word = title.split(" ");
288                                         for (int j = 0; j < word.length; j++) {
289                                                 critext.add(new TermQuery(input.createTerm(word[j])),
290                                                                 clause);
291                                         }
292                                         query.add(critext, BooleanClause.Occur.MUST);
293                                 }
294                                 List<SimulationContext> context = sprop[i]
295                                                 .getSimulationContexts();
296                                 if (context != null && context.size() > 0) {
297                                         BooleanQuery critext = new BooleanQuery();
298                                         for (Iterator<SimulationContext> j = context.iterator(); j
299                                                         .hasNext();) {
300                                                 SimulationContext seltext = j.next();
301                                                 input = new Term(String.valueOf(seltext.getType()
302                                                                 .getIndex()));
303                                                 critext.add(new TermQuery(input.createTerm(seltext
304                                                                 .getValue())), BooleanClause.Occur.MUST);
305                                         }
306                                         query.add(critext, BooleanClause.Occur.MUST);
307                                 }
308                                 fulquery.add(query, BooleanClause.Occur.SHOULD);
309                         }
310                         if (logger.isInfoEnabled()) {
311                                 logger.info("Searching studies by Lucene query \""
312                                                 + fulquery.toString() + "\".");
313                         }
314                         // Creation of the studies filter
315                         BooleanFilter filter = new BooleanFilter();
316                         TermsFilter select = new TermsFilter();
317                         Term mytype = new Term("class");
318                         select.addTerm(mytype.createTerm("Study"));
319                         filter.add(new FilterClause(select, BooleanClause.Occur.SHOULD));
320
321                         // Creation of the sort criteria
322                         Sort sort = new Sort(new SortField("title", SortField.STRING));
323
324                         // Search
325                         TopFieldDocs found = searcher.search(fulquery, filter, hitsize,
326                                         sort);
327
328                         if (found.totalHits < 1)
329                                 return result; // No study found
330
331                         // Construction of the result list
332                         ScoreDoc[] hits = found.scoreDocs;
333                         for (int i = 0; i < hits.length; i++) {
334                                 result.add(new IndexServiceImpl.ObjectProxy(searcher
335                                                 .doc(hits[i].doc)));
336                         }
337                         searcher.close();
338                 } catch (Exception error) {
339                         logger.error("Error during Lucene search, reason:", error);
340                 }
341                 return result;
342         }
343
344         /**
345          * {@inheritDoc}
346          * 
347          * @see org.splat.service.SearchService#indexStudy(org.splat.dal.bo.som.Study)
348          */
349         public void indexStudy(Study study) {
350                 logger.debug("Index study: id=" + study.getRid() + "; reference=" + study.getReference());
351                 try {
352                         Study.Properties sprop = new Study.Properties();
353                         List<Proxy> index = selectStudiesWhere(sprop.setReference(study
354                                         .getReference()));
355
356                         if (index.size() != 0) {
357                                 logger.debug("The given study is already indexed.");
358                                 return; // The given study is already indexed
359                         }
360
361                         IndexService lucin = getIndex();
362                         Scenario[] scenes = study.getScenarii();
363
364                         logger.debug("Number of study " + study.getReference() + " actors: " + study.getActor().size());
365                         lucin.add(study);
366                         if (study.getProgressState() != ProgressState.inWORK)
367                                 for (int i = 0; i < scenes.length; i++) {
368                                         List<KnowledgeElement> list = scenes[i]
369                                                         .getAllKnowledgeElements();
370                                         for (Iterator<KnowledgeElement> j = list.iterator(); j
371                                                         .hasNext();) {
372                                                 lucin.add(j.next());
373                                                 logger.debug("Knowlegge added: id=" + j.next().getIndex());
374                                         }
375                                 }
376                 } catch (Exception error) {
377                         logger.error("Unable to index the study '"
378                                         + study.getIndex() + "', reason:", error);
379                 }
380         }
381
382         /**
383          * Get lucene index handler. Create the index if it is not exist.
384          * 
385          * @return IndexService
386          * @throws IOException
387          *             if error when creating a new lucene index
388          */
389         private IndexService getIndex() throws IOException {
390                 IndexService lucin = getIndexService();
391                 if (!lucin.exists())
392                         lucin.create(); // Happens when re-indexing all studies
393                 return lucin;
394         }
395
396         /**
397          * Get the repositoryService.
398          * 
399          * @return the repositoryService
400          */
401         public RepositoryService getRepositoryService() {
402                 return _repositoryService;
403         }
404
405         /**
406          * Set the repositoryService.
407          * 
408          * @param repositoryService
409          *            the repositoryService to set
410          */
411         public void setRepositoryService(RepositoryService repositoryService) {
412                 _repositoryService = repositoryService;
413         }
414
415         /**
416          * Get the indexService.
417          * 
418          * @return the indexService
419          */
420         public IndexService getIndexService() {
421                 return _indexService;
422         }
423
424         /**
425          * Set the indexService.
426          * 
427          * @param indexService
428          *            the indexService to set
429          */
430         public void setIndexService(IndexService indexService) {
431                 _indexService = indexService;
432         }
433
434         /**
435          * Get the studyService.
436          * @return the studyService
437          */
438         public StudyService getStudyService() {
439                 return _studyService;
440         }
441
442         /**
443          * Set the studyService.
444          * @param studyService the studyService to set
445          */
446         public void setStudyService(StudyService studyService) {
447                 _studyService = studyService;
448         }
449 }