Salome HOME
6ed816e7bff5e1cba554bfd5e48b179b9560e405
[tools/siman.git] / Workspace / Siman-Common / src / org / splat / service / SearchServiceImpl.java
1 /*****************************************************************************
2  * Company         EURIWARE
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.dal.dao.som.Database;
42 import org.splat.service.dto.Proxy;
43 import org.splat.service.technical.IndexService;
44 import org.splat.service.technical.IndexServiceImpl;
45 import org.splat.service.technical.RepositoryService;
46
47 /**
48  * @author rkv
49  *
50  */
51 public class SearchServiceImpl implements SearchService {
52
53     public final static Logger   logger = Logger.getLogger(org.splat.service.SearchServiceImpl.class);
54     
55         private RepositoryService _repositoryService;
56
57         private IndexService _indexService;
58         
59         public List<Proxy> selectKnowledgeElementsWhere (KnowledgeElement.Properties... kprop) {
60         //  ---------------------------------------------------------------------------------------------
61               List<Proxy> result  = new ArrayList<Proxy>();
62               int         hitsize = 20;
63               try {
64         
65         //          Creation of the Lucene query
66                 File          indir    = getRepositoryService().getRepositoryIndexDirectory();
67                 Directory     index    = FSDirectory.open(indir);               
68                 IndexSearcher searcher = new IndexSearcher(index, true);
69                 BooleanQuery  fulquery = new BooleanQuery();
70                 
71                     for (int i=0; i<kprop.length; i++) {
72                       BooleanQuery  query = new BooleanQuery();
73                       Term          input;                                 // Supposed initialized below at least by the visibility
74                 
75                   Visibility area = kprop[i].getVisibility();          // Visibility
76                   if (area != null) {
77                     input = new Term("area");
78                     query.add(new TermQuery(input.createTerm(area.toString())), BooleanClause.Occur.MUST);
79                   }
80                   ProgressState state = kprop[i].getProgressState();   // State
81                   if (state != null) {
82                           input = new Term("state");
83                     query.add(new TermQuery(input.createTerm(state.toString())), BooleanClause.Occur.MUST);
84                   }
85                   String refid = kprop[i].getReference();              // Reference
86                   if (refid != null) {
87                     input = new Term("ref");
88                         query.add(new TermQuery(input.createTerm(refid)), BooleanClause.Occur.MUST);
89                   }
90                   KnowledgeElementType type = kprop[i].getType();      // Type
91                   if (type != null) {
92                     input = new Term("type");
93                         query.add(new TermQuery(input.createTerm(type.getName())), BooleanClause.Occur.MUST);
94                   }
95                   User manager = kprop[i].getAuthor();                 // Author
96                   if  (manager != null) {
97                     input = new Term("author");
98                         query.add(new TermQuery(input.createTerm(manager.toString())), BooleanClause.Occur.MUST);
99                   }
100                   User actor = kprop[i].getActor();                    // Contributor, Reviewer or Approver of the owner study
101                   if  (actor != null) {
102                         input = new Term("actor");
103                             query.add(new TermQuery(input.createTerm(actor.toString())), BooleanClause.Occur.MUST);
104                   }
105                   String title = kprop[i].getTitle();                  // Title
106                   if (title != null) {
107                     input = new Term("contents");
108                     BooleanQuery critext  = new BooleanQuery();
109                     String       operator = "AND";     // Future user input
110                     BooleanClause.Occur        clause = BooleanClause.Occur.MUST;
111                     if (operator.equals("OR")) clause = BooleanClause.Occur.SHOULD;
112                     String[] word = title.split(" ");
113                     for (int j=0; j<word.length; j++) {
114                       critext.add(new TermQuery(input.createTerm(word[j])), clause);
115                     }
116                     query.add(critext, BooleanClause.Occur.MUST);
117                   }
118                   List<SimulationContext> context = kprop[i].getSimulationContexts();
119                   if  (context != null && context.size() > 0) {
120                     BooleanQuery critext = new BooleanQuery();
121                     for (Iterator<SimulationContext> j=context.iterator(); j.hasNext();) {
122                       SimulationContext seltext = j.next();
123                       input =  new Term(String.valueOf(seltext.getType().getIndex()));
124                       critext.add(new TermQuery(input.createTerm(seltext.getValue())), BooleanClause.Occur.MUST);
125                     }
126                     query.add(critext, BooleanClause.Occur.MUST);
127                   }
128                 fulquery.add(query, BooleanClause.Occur.SHOULD);
129                     }
130                         if (logger.isInfoEnabled()) {
131                     logger.info("Searching knowledges by Lucene query \"" + fulquery.toString() + "\".");
132                 }
133         //    Creation of the knowledge filter
134                         BooleanFilter   filter = new BooleanFilter();
135                         TermsFilter     select = new TermsFilter();
136                         Term            mytype = new Term("class");
137                         select.addTerm( mytype.createTerm("KnowledgeElement") );
138                         filter.add(new FilterClause(select, BooleanClause.Occur.SHOULD));
139         
140         //    Creation of the sort criteria
141                         Sort  sort = new Sort(new SortField("title", SortField.STRING));
142         
143         //    Search
144                 TopFieldDocs found = searcher.search(fulquery, filter, hitsize, sort);
145                 
146                 if (found.totalHits < 1) return result;   // No study found
147         
148         //    Construction of the result list
149                 ScoreDoc[] hits = found.scoreDocs;
150                     for (int i=0; i<hits.length; i++) {
151                           result.add( new IndexServiceImpl.ObjectProxy(searcher.doc(hits[i].doc)) );
152                     }
153                     searcher.close();             
154               }
155               catch (Exception error) {
156                 logger.error("Error during Lucene search, reason:", error);
157               }
158               return result;
159                 }
160
161         public List<Proxy> selectStudiesWhere (Study.Properties... sprop) {
162         //  ------------------------------------------------------------------------
163               List<Proxy> result  = new ArrayList<Proxy>();
164               int         hitsize = 20;
165               try {
166         
167         //    Creation of the Lucene query
168                 File          indir    = getRepositoryService().getRepositoryIndexDirectory();
169                 Directory     index    = FSDirectory.open(indir);               
170                 IndexSearcher searcher = new IndexSearcher(index, true);
171                 BooleanQuery  fulquery = new BooleanQuery();
172                 
173                     for (int i=0; i<sprop.length; i++) {
174                       BooleanQuery  query = new BooleanQuery();
175                       Term          input;                                 // Supposed initialized below at least by the visibility
176         
177                   Visibility area = sprop[i].getVisibility();          // Visibility
178                   if (area != null) {
179                         input = new Term("area");
180                     query.add(new TermQuery(input.createTerm(area.toString())), BooleanClause.Occur.MUST);
181                   }
182                   ProgressState state = sprop[i].getProgressState();   // State
183                   if (state != null) {
184                         input = new Term("state");
185                     if (state == ProgressState.inPROGRESS) {
186                           BooleanQuery cristate = new BooleanQuery();
187                           cristate.add(new TermQuery(input.createTerm("inWORK")),  BooleanClause.Occur.SHOULD);
188                           cristate.add(new TermQuery(input.createTerm("inDRAFT")), BooleanClause.Occur.SHOULD);
189                           cristate.add(new TermQuery(input.createTerm("inCHECK")), BooleanClause.Occur.SHOULD);
190                       query.add(cristate, BooleanClause.Occur.MUST);
191                     } else {
192                       query.add(new TermQuery(input.createTerm(state.toString())), BooleanClause.Occur.MUST);
193                     }
194                   }
195                   String refid = sprop[i].getReference();              // Reference
196                   if (refid != null) {
197                     input = new Term("ref");
198                     query.add(new TermQuery(input.createTerm(refid)), BooleanClause.Occur.MUST);
199                   }
200                   User manager = sprop[i].getManager();                // Author
201                   if  (manager != null) {
202                         input = new Term("author");
203                             query.add(new TermQuery(input.createTerm(manager.toString())), BooleanClause.Occur.MUST);
204                   }
205                   User actor = sprop[i].getActor();                    // Contributor, Reviewer or Approver
206                   if  (actor != null) {
207                         input = new Term("actor");
208                             query.add(new TermQuery(input.createTerm(actor.toString())), BooleanClause.Occur.MUST);
209                   }
210                   String title = sprop[i].getTitle();                  // Title
211                   if (title != null) {
212                         input = new Term("contents");
213                         BooleanQuery critext  = new BooleanQuery();
214                         String       operator = "AND";     // Future user input
215                         BooleanClause.Occur        clause = BooleanClause.Occur.MUST;
216                         if (operator.equals("OR")) clause = BooleanClause.Occur.SHOULD;
217                         String[] word = title.split(" ");
218                         for (int j=0; j<word.length; j++) {
219                           critext.add(new TermQuery(input.createTerm(word[j])), clause);
220                         }
221                         query.add(critext, BooleanClause.Occur.MUST);
222                   }
223                   List<SimulationContext> context = sprop[i].getSimulationContexts();
224                   if  (context != null && context.size() > 0) {
225                     BooleanQuery critext = new BooleanQuery();
226                         for (Iterator<SimulationContext> j=context.iterator(); j.hasNext();) {
227                       SimulationContext seltext = j.next();
228                       input =  new Term(String.valueOf(seltext.getType().getIndex()));
229                       critext.add(new TermQuery(input.createTerm(seltext.getValue())), BooleanClause.Occur.MUST);
230                     }
231                     query.add(critext, BooleanClause.Occur.MUST);
232                   }          
233                   fulquery.add(query, BooleanClause.Occur.SHOULD);
234                     }
235                         if (logger.isInfoEnabled()) {
236                     logger.info("Searching studies by Lucene query \"" + fulquery.toString() + "\".");
237                 }
238         //    Creation of the studies filter
239                         BooleanFilter   filter = new BooleanFilter();
240                         TermsFilter     select = new TermsFilter();
241                         Term            mytype = new Term("class");
242                         select.addTerm( mytype.createTerm("Study") );
243                         filter.add(new FilterClause(select, BooleanClause.Occur.SHOULD));
244         
245         //    Creation of the sort criteria
246                         Sort  sort = new Sort(new SortField("title", SortField.STRING));
247         
248         //    Search
249                 TopFieldDocs found = searcher.search(fulquery, filter, hitsize, sort);
250                 
251                 if (found.totalHits < 1) return result;   // No study found
252         
253         //    Construction of the result list
254                 ScoreDoc[] hits = found.scoreDocs;
255                     for (int i=0; i<hits.length; i++) {
256                           result.add( new IndexServiceImpl.ObjectProxy(searcher.doc(hits[i].doc)) );
257                     }
258                     searcher.close();             
259               }
260               catch (Exception error) {
261                 logger.error("Error during Lucene search, reason:", error);
262               }
263               return result;
264             }
265
266         public void indexStudy (Study study) {
267         //  -------------------------------------------
268               try {
269                 Study.Properties sprop = new Study.Properties();
270                 List<Proxy>      index = selectStudiesWhere(sprop.setReference(study.getReference()));
271         
272                 if (index.size() != 0) return;     // The given study is already indexed
273         
274                 IndexService lucin = getIndex();
275                 Scenario[] scenes = study.getScenarii();
276         
277                 lucin.add(study);
278                 if (study.getProgressState() != ProgressState.inWORK) for (int i=0; i<scenes.length; i++) {
279                   List<KnowledgeElement> list = scenes[i].getAllKnowledgeElements();
280                   for (Iterator<KnowledgeElement> j=list.iterator(); j.hasNext(); ) {
281                         lucin.add(j.next());
282                   }
283                 }
284               }
285               catch (Exception error) {
286                 Database.logger.error("Unable to index the study '" + study.getIndex() + "', reason:", error);
287               }
288             }
289
290     public IndexService getIndex () throws IOException {
291                 IndexService lucin = getIndexService();
292                 if ( !lucin.exists() ) lucin.create();     // Happens when re-indexing all studies
293                 return lucin;
294     }
295     
296         /**
297          * Get the repositoryService.
298          * @return the repositoryService
299          */
300         public RepositoryService getRepositoryService() {
301                 return _repositoryService;
302         }
303
304         /**
305          * Set the repositoryService.
306          * @param repositoryService the repositoryService to set
307          */
308         public void setRepositoryService(RepositoryService repositoryService) {
309                 _repositoryService = repositoryService;
310         }
311
312         /**
313          * Get the indexService.
314          * @return the indexService
315          */
316         public IndexService getIndexService() {
317                 return _indexService;
318         }
319
320         /**
321          * Set the indexService.
322          * @param indexService the indexService to set
323          */
324         public void setIndexService(IndexService indexService) {
325                 _indexService = indexService;
326         }
327 }