Salome HOME
2baaf40465a22fe33f4766392c8c34755c63da60
[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.IndexWriter;
20 import org.apache.lucene.index.Term;
21 import org.apache.lucene.search.BooleanClause;
22 import org.apache.lucene.search.BooleanFilter;
23 import org.apache.lucene.search.BooleanQuery;
24 import org.apache.lucene.search.FilterClause;
25 import org.apache.lucene.search.IndexSearcher;
26 import org.apache.lucene.search.ScoreDoc;
27 import org.apache.lucene.search.Sort;
28 import org.apache.lucene.search.SortField;
29 import org.apache.lucene.search.TermQuery;
30 import org.apache.lucene.search.TermsFilter;
31 import org.apache.lucene.search.TopFieldDocs;
32 import org.apache.lucene.store.Directory;
33 import org.apache.lucene.store.FSDirectory;
34 import org.hibernate.Criteria;
35 import org.hibernate.Hibernate;
36 import org.hibernate.criterion.DetachedCriteria;
37 import org.hibernate.criterion.Disjunction;
38 import org.hibernate.criterion.Junction;
39 import org.hibernate.criterion.Order;
40 import org.hibernate.criterion.Restrictions;
41 import org.hibernate.type.Type;
42 import org.splat.dal.bo.kernel.User;
43 import org.splat.dal.bo.som.KnowledgeElement;
44 import org.splat.dal.bo.som.ProgressState;
45 import org.splat.dal.bo.som.Scenario;
46 import org.splat.dal.bo.som.SimulationContext;
47 import org.splat.dal.bo.som.Study;
48 import org.splat.dal.bo.som.Visibility;
49 import org.splat.dal.dao.som.KnowledgeElementDAO;
50 import org.splat.dal.dao.som.StudyDAO;
51 import org.splat.service.dto.ImportedStudyDTO;
52 import org.splat.service.dto.KnowledgeSearchFilterDTO;
53 import org.splat.service.dto.Proxy;
54 import org.splat.service.dto.SearchFilterDTO;
55 import org.splat.service.dto.StudyDTO;
56 import org.splat.service.dto.StudySearchFilterDTO;
57 import org.splat.service.technical.IndexService;
58 import org.splat.service.technical.IndexServiceImpl;
59 import org.splat.service.technical.RepositoryService;
60 import org.splat.util.BeanHelper;
61 import org.springframework.transaction.annotation.Transactional;
62
63 /**
64  * Search service implementation.
65  * 
66  * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
67  */
68 public class SearchServiceImpl implements SearchService {
69
70         /**
71          * The service logger.
72          */
73         public final static Logger LOG = Logger
74                         .getLogger(org.splat.service.SearchServiceImpl.class);
75         /**
76          * "title" property name.
77          */
78         private final static String PROP_TITLE = "title";
79
80         /**
81          * Injected repository service.
82          */
83         private RepositoryService _repositoryService;
84         /**
85          * Injected index service.
86          */
87         private IndexService _indexService;
88         /**
89          * Injected study service.
90          */
91         private StudyService _studyService;
92         /**
93          * Injected study DAO.
94          */
95         private StudyDAO _studyDAO;
96         /**
97          * Injected knowledge element DAO.
98          */
99         private KnowledgeElementDAO _knowledgeElementDAO;
100
101         /**
102          * Get a list of studies which are currently not presented in the lucene index.
103          * 
104          * @return list of ImportedStudy DTO
105          */
106         @Transactional(readOnly = true)
107         public List<ImportedStudyDTO> selectStudies() {
108                 List<ImportedStudyDTO> table = new ArrayList<ImportedStudyDTO>();
109                 Study.Properties sprop = new Study.Properties();
110                 List<Study> dbStudies = getStudyDAO().getAll();
111
112                 for (Study aStudy : dbStudies) {
113                         try {
114                                 sprop.clear();
115                                 if (selectStudiesWhere(
116                                                 sprop.setReference(aStudy.getReference())).size() != 0) {
117                                         // If this study was already indexed and found in the lucene index
118                                         // then skip it to avoid adding to the index it again.
119                                         continue;
120                                 }
121                         } catch (Exception error) {
122                                 continue;
123                         }
124                         // Add the study to the list of studies which are
125                         // currently not presented in the lucene index.
126                         table.add(BeanHelper.copyBean(aStudy, ImportedStudyDTO.class));
127                 }
128                 return table;
129         }
130
131         /**
132          * Refresh lucene index for studies.
133          * 
134          * @param ridlist
135          *            list of studies id's
136          */
137         @Transactional(readOnly = true)
138         @Deprecated
139         public void reindexStudies(final String[] ridlist) {
140                 for (int i = 0; i < ridlist.length; i++) {
141                         long index = Long.valueOf(ridlist[i].trim());
142                         Study study = getStudyService().selectStudy(index);
143                         indexStudy(study);
144                 }
145         }
146
147         /**
148          * {@inheritDoc}
149          * 
150          * @see org.splat.service.SearchService#selectKnowledgeElementsWhere(org.splat.service.dto.KnowledgeSearchFilterDTO)
151          */
152         public List<Proxy> selectKnowledgeElementsWhere(
153                         final KnowledgeSearchFilterDTO filter) {
154                 List<Proxy> result = new ArrayList<Proxy>();
155
156                 // Search matching all criteria
157                 DetachedCriteria query = DetachedCriteria.forClass(
158                                 KnowledgeElement.class, "kelm");
159                 query.createAlias("kelm.owner", "scen", Criteria.INNER_JOIN)
160                                 .createCriteria("scen.owner", "study", Criteria.INNER_JOIN)
161                                 .add(visibleStudyFilter(filter));
162
163                 // Creation of the query
164                 Junction topJunction = initQuery(filter);
165
166                 addByWordsCriteria(topJunction, filter);
167
168                 List<SimulationContext> context = filter.getSimContexts();
169                 if (context != null && (!context.isEmpty())) {
170                         // Get only studies which have given contexts
171                         query.createAlias("study.contex", "ctx", Criteria.INNER_JOIN);
172                         Junction critctx;
173                         if (filter.isMatchAllContexts()) { // AND
174                                 critctx = Restrictions.conjunction();
175                         } else { // OR
176                                 critctx = Restrictions.disjunction();
177                         }
178                         for (SimulationContext seltext : context) {
179                                 // (simctxType = seltext.getType() AND simctxValue = seltext.getValue())
180                                 critctx.add(Restrictions.and(Restrictions.eq("ctx.value",
181                                                 seltext.getValue()), Restrictions.eq("ctx.type",
182                                                 seltext.getType())));
183
184                         }
185                         topJunction.add(critctx);
186                 }
187
188                 query.add(topJunction);
189                 // Group by study
190                 query.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
191                 // Creation of the sort criteria
192                 query.addOrder(Order.asc(PROP_TITLE));
193
194                 if (LOG.isInfoEnabled()) {
195                         LOG.info("Searching knowledge elements: \"" + query.toString());
196                 }
197
198                 // Search
199                 List<KnowledgeElement> found = getKnowledgeElementDAO()
200                                 .getFilteredList(query);
201
202                 // Construction of the result list
203                 for (KnowledgeElement kelm : found) {
204                         result.add(new StudyDTO(kelm.getIndex(), kelm.getReference(), kelm
205                                         .getProgressState(), kelm.getTitle(), kelm.getAuthor()
206                                         .getDisplayName()));
207                 }
208                 return result;
209         }
210
211         /**
212          * Add search criteria for filtering by title contents.
213          * 
214          * @param topJunction
215          *            the search condition to be appended
216          * @param filter
217          *            the criteria
218          */
219         private void addByWordsCriteria(final Junction topJunction,
220                         final SearchFilterDTO filter) {
221                 String title = filter.getWords(); // Title
222                 if (title != null && (!title.isEmpty())) {
223                         // Look for given words in titles
224                         Junction critext;
225                         if (filter.isMatchAllCriteria()) { // AND
226                                 critext = Restrictions.conjunction();
227                         } else { // OR
228                                 critext = Restrictions.disjunction();
229                         }
230
231                         String[] word = title.split(" ");
232                         for (int j = 0; j < word.length; j++) {
233                                 critext.add(Restrictions.like(PROP_TITLE, "%"
234                                                 + processWildcards(word[j]) + "%"));
235                         }
236                         topJunction.add(critext);
237                 }
238         }
239
240         /**
241          * Escape wildcard characters and insert them instead of ? and *.
242          * 
243          * @param str
244          *            the original string
245          * @return the transformed string
246          */
247         private String processWildcards(final String str) {
248                 if (LOG.isDebugEnabled()) {
249                         LOG.debug("   Original search string: " + str);
250                         LOG.debug("Transformed search string: "
251                                         + str.replaceAll("\\\\", "\\\\\\\\").replaceAll("%",
252                                                         "\\\\%").replaceAll("_", "\\\\_").replaceAll("\\?",
253                                                         "_").replaceAll("\\*", "%"));
254                 }
255                 return str.replaceAll("\\\\", "\\\\\\\\").replaceAll("%", "\\\\%")
256                                 .replaceAll("_", "\\\\_").replaceAll("\\?", "_").replaceAll(
257                                                 "\\*", "%");
258         }
259
260         /**
261          * {@inheritDoc}
262          * 
263          * @see org.splat.service.SearchService#selectStudiesWhere(org.splat.service.dto.StudySearchFilterDTO)
264          */
265         public List<Proxy> selectStudiesWhere(final StudySearchFilterDTO filter) {
266                 List<Proxy> result = new ArrayList<Proxy>();
267
268                 DetachedCriteria query = DetachedCriteria
269                                 .forClass(Study.class, "study").add(visibleStudyFilter(filter));
270
271                 // Creation of the query
272                 Junction topJunction = initQuery(filter);
273
274                 addByWordsCriteria(topJunction, filter);
275
276                 List<SimulationContext> context = filter.getSimContexts();
277                 if (context != null && (!context.isEmpty())) {
278                         // Get only studies which have given contexts
279                         query.createAlias("contex", "ctx", Criteria.INNER_JOIN);
280                         Junction critctx;
281                         if (filter.isMatchAllContexts()) { // AND
282                                 critctx = Restrictions.conjunction();
283                         } else { // OR
284                                 critctx = Restrictions.disjunction();
285                         }
286                         for (SimulationContext seltext : context) {
287                                 // (simctxType = seltext.getType() AND simctxValue = seltext.getValue())
288                                 critctx.add(Restrictions.and(Restrictions.eq("ctx.value",
289                                                 seltext.getValue()), Restrictions.eq("ctx.type",
290                                                 seltext.getType())));
291
292                         }
293                         topJunction.add(critctx);
294                 }
295
296                 query.add(topJunction);
297                 // Group by study
298                 query.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
299                 // Creation of the sort criteria
300                 query.addOrder(Order.asc(PROP_TITLE));
301
302                 if (LOG.isInfoEnabled()) {
303                         LOG.info("Searching studies: \"" + query.toString());
304                 }
305
306                 // Search
307                 List<Study> found = getStudyDAO().getFilteredList(query);
308
309                 // Construction of the result list
310                 for (Study std : found) {
311                         result.add(new StudyDTO(std.getIndex(), std.getReference(), std
312                                         .getProgressState(), std.getTitle(), std.getAuthor()
313                                         .getDisplayName()));
314                 }
315                 return result;
316         }
317
318         /**
319          * Initialize query with base criteria.
320          * 
321          * @param filter
322          *            the criteria
323          * @return top junction of the search filter
324          */
325         private Junction initQuery(final StudySearchFilterDTO filter) {
326                 Junction topJunction;
327                 if (filter.isMatchAllCriteria()) { // AND
328                         topJunction = Restrictions.conjunction();
329                 } else { // OR
330                         topJunction = Restrictions.disjunction();
331                 }
332                 if (!SearchFilterDTO.ANY_STATE.equals(filter.getState())) {
333                         ProgressState state = ProgressState.valueOf(filter.getState()); // State
334                         if (state != null) {
335                                 topJunction.add(Restrictions.eq("state", state));
336                         }
337                 }
338                 String refid = filter.getReference(); // Reference
339                 if (refid != null && !refid.isEmpty()) {
340                         topJunction.add(Restrictions.like("sid", processWildcards(refid)));
341                 }
342
343                 // Filter by creation date
344                 addCreationDateCriteria(topJunction, filter, "credate");
345                 // Filter by modification date
346                 if (filter.getUpdatedAfter() != null) {
347                         topJunction.add(Restrictions
348                                         .gt("lasdate", filter.getUpdatedAfter()));
349                 }
350                 if (filter.getUpdatedBefore() != null) {
351                         topJunction.add(Restrictions.lt("lasdate", filter
352                                         .getUpdatedBefore()));
353                 }
354
355                 // Filter by study author
356                 long authorId = Long.valueOf(filter.getAuthor());
357                 if (authorId > 0) {
358                         topJunction.add(Restrictions.eq("manager.rid", authorId));
359                 }
360
361                 return topJunction;
362         }
363
364         /**
365          * Initialize query with base criteria.
366          * 
367          * @param filter
368          *            the criteria
369          * @return top junction of the search filter
370          */
371         private Junction initQuery(final KnowledgeSearchFilterDTO filter) {
372                 Junction topJunction;
373                 if (filter.isMatchAllCriteria()) { // AND
374                         topJunction = Restrictions.conjunction();
375                 } else { // OR
376                         topJunction = Restrictions.disjunction();
377                 }
378
379                 // Filter by knowledge type
380                 long ktypeId = Long.valueOf(filter.getKtype());
381                 if (ktypeId > 0) {
382                         topJunction.add(Restrictions.eq("kelm.type.rid", ktypeId));
383                 }
384
385                 if (!SearchFilterDTO.ANY_STATE.equals(filter.getState())) {
386                         ProgressState state = ProgressState.valueOf(filter.getState()); // State
387                         if (state != null) {
388                                 topJunction.add(Restrictions.eq("kelm.state", state));
389                         }
390                 }
391
392                 String refid = filter.getReference(); // Reference
393                 if (refid != null && !refid.isEmpty()) {
394                         long id = Long.valueOf(refid.replaceAll("^KE(0)*", ""));
395                         if (id > 0) {
396                                 topJunction.add(Restrictions.eq("kelm.rid", id));
397                         }
398                 }
399
400                 addCreationDateCriteria(topJunction, filter, "date");
401
402                 // Filter by knowledge author
403                 long authorId = Long.valueOf(filter.getAuthor());
404                 if (authorId > 0) {
405                         topJunction.add(Restrictions.eq("kelm.author.rid", authorId));
406                 }
407
408                 return topJunction;
409         }
410
411         /**
412          * Filter for visible studies.
413          * 
414          * @param filter
415          *            search criteria
416          * @return search condition for studies to get only visible studies
417          */
418         private Junction visibleStudyFilter(final SearchFilterDTO filter) {
419                 Junction topJunction;
420                 if (filter.isMatchAllCriteria()) { // AND
421                         topJunction = Restrictions.conjunction();
422                 } else { // OR
423                         topJunction = Restrictions.disjunction();
424                 }
425
426                 // Filter by connected user
427                 long actorId = filter.getConnectedUserId(); // Contributor, Reviewer or Approver
428                 if (actorId > 0) {
429                         // User is loggen in - show public studies and studies where he is participating
430                         Disjunction orCrit = Restrictions.disjunction();
431                         topJunction
432                                         .add(orCrit
433                                                         .add(
434                                                                         /* If the user is a validation cycle participant */
435                                                                         Restrictions
436                                                                                         .sqlRestriction(
437                                                                                                         "{alias}.rid in ("
438                                                                                                                         + "select vcrel.owner from cycle_rel vcrel "
439                                                                                                                         + "inner join cycle vc on vcrel.refer = vc.rid "
440                                                                                                                         + "where {alias}.rid = vcrel.owner "
441                                                                                                                         + "AND (vc.publisher = ? OR vc.reviewer = ? OR vc.approver = ? OR vc.signatory = ?) "
442                                                                                                                         + "group by vcrel.owner)",
443                                                                                                         new Object[] { actorId,
444                                                                                                                         actorId, actorId,
445                                                                                                                         actorId },
446                                                                                                         new Type[] {
447                                                                                                                         Hibernate.LONG,
448                                                                                                                         Hibernate.LONG,
449                                                                                                                         Hibernate.LONG,
450                                                                                                                         Hibernate.LONG }))
451                                                         .add(
452                                                                         /* If the user is contributor */
453                                                                         Restrictions
454                                                                                         .sqlRestriction(
455                                                                                                         "{alias}.rid in ("
456                                                                                                                         + "select rel.owner from contributor_rel rel "
457                                                                                                                         + "where {alias}.rid = rel.owner AND rel.refer = ?)",
458                                                                                                         actorId, Hibernate.LONG))
459                                                         .add(
460                                                                         /* If the user is reader */
461                                                                         Restrictions
462                                                                                         .sqlRestriction(
463                                                                                                         "{alias}.rid in ("
464                                                                                                                         + "select rel.owner from reader_rel rel "
465                                                                                                                         + "where {alias}.rid = rel.owner AND rel.refer = ?)",
466                                                                                                         actorId, Hibernate.LONG))
467                                                         .add(
468                                                         /* If the user is author */
469                                                         Restrictions.eq("study.manager.rid", actorId)).add(
470                                                                         /* If the study is public */
471                                                                         Restrictions.eq("study.visibility",
472                                                                                         Visibility.PUBLIC)));
473                 } else {
474                         // User is not logged in - show only public studies
475                         topJunction.add(Restrictions.eq("study.visibility",
476                                         Visibility.PUBLIC));
477                 }
478                 return topJunction;
479         }
480
481         /**
482          * Add search criteria by dates to the junction filter condition.
483          * 
484          * @param topJunction
485          *            the junction filter condition
486          * @param filter
487          *            search criteria
488          * @param propName
489          *            creation date property name
490          */
491         private void addCreationDateCriteria(final Junction topJunction,
492                         final SearchFilterDTO filter, final String propName) {
493                 // Filter by creation date
494                 if (filter.getCreatedAfter() != null) {
495                         topJunction
496                                         .add(Restrictions.gt(propName, filter.getCreatedAfter()));
497                 }
498                 if (filter.getCreatedBefore() != null) {
499                         topJunction.add(Restrictions
500                                         .lt(propName, filter.getCreatedBefore()));
501                 }
502         }
503
504         /**
505          * {@inheritDoc}
506          * 
507          * @see org.splat.service.SearchService#selectStudiesWhere(org.splat.dal.bo.som.Study.Properties[])
508          */
509         @Deprecated
510         public List<Proxy> selectStudiesWhere(final Study.Properties... sprop) {
511                 List<Proxy> result = new ArrayList<Proxy>();
512                 int hitsize = 20;
513                 try {
514
515                         // Creation of the Lucene query
516                         File indir = getRepositoryService().getRepositoryIndexDirectory();
517                         Directory index = FSDirectory.open(indir);
518                         IndexSearcher searcher = new IndexSearcher(index, true);
519                         BooleanQuery fulquery = new BooleanQuery();
520
521                         for (int i = 0; i < sprop.length; i++) {
522                                 BooleanQuery query = new BooleanQuery();
523                                 Term input; // Supposed initialized below at least by the visibility
524
525                                 Visibility area = sprop[i].getVisibility(); // Visibility
526                                 if (area != null) {
527                                         input = new Term("area");
528                                         query.add(new TermQuery(input.createTerm(area.toString())),
529                                                         BooleanClause.Occur.MUST);
530                                 }
531                                 ProgressState state = sprop[i].getProgressState(); // State
532                                 if (state != null) {
533                                         input = new Term("state");
534                                         if (state == ProgressState.inPROGRESS) {
535                                                 BooleanQuery cristate = new BooleanQuery();
536                                                 cristate.add(new TermQuery(input.createTerm("inWORK")),
537                                                                 BooleanClause.Occur.SHOULD);
538                                                 cristate.add(
539                                                                 new TermQuery(input.createTerm("inDRAFT")),
540                                                                 BooleanClause.Occur.SHOULD);
541                                                 cristate.add(
542                                                                 new TermQuery(input.createTerm("inCHECK")),
543                                                                 BooleanClause.Occur.SHOULD);
544                                                 query.add(cristate, BooleanClause.Occur.MUST);
545                                         } else {
546                                                 query.add(new TermQuery(input.createTerm(state
547                                                                 .toString())), BooleanClause.Occur.MUST);
548                                         }
549                                 }
550                                 String refid = sprop[i].getReference(); // Reference
551                                 if (refid != null) {
552                                         input = new Term("ref");
553                                         query.add(new TermQuery(input.createTerm(refid)),
554                                                         BooleanClause.Occur.MUST);
555                                 }
556                                 User manager = sprop[i].getManager(); // Author
557                                 if (manager != null) {
558                                         input = new Term("author");
559                                         query.add(new TermQuery(input
560                                                         .createTerm(manager.toString())),
561                                                         BooleanClause.Occur.MUST);
562                                 }
563                                 User actor = sprop[i].getActor(); // Contributor, Reviewer or Approver
564                                 if (actor != null) {
565                                         input = new Term("actor");
566                                         query.add(
567                                                         new TermQuery(input.createTerm(actor.toString())),
568                                                         BooleanClause.Occur.MUST);
569                                 }
570                                 String title = sprop[i].getTitle(); // Title
571                                 if (title != null) {
572                                         input = new Term("contents");
573                                         BooleanQuery critext = new BooleanQuery();
574                                         String operator = "AND"; // Future user input
575                                         BooleanClause.Occur clause = BooleanClause.Occur.MUST;
576                                         if (operator.equals("OR")) {
577                                                 clause = BooleanClause.Occur.SHOULD;
578                                         }
579                                         String[] word = title.split(" ");
580                                         for (int j = 0; j < word.length; j++) {
581                                                 critext.add(new TermQuery(input.createTerm(word[j])),
582                                                                 clause);
583                                         }
584                                         query.add(critext, BooleanClause.Occur.MUST);
585                                 }
586                                 List<SimulationContext> context = sprop[i]
587                                                 .getSimulationContexts();
588                                 if (context != null && context.size() > 0) {
589                                         BooleanQuery critext = new BooleanQuery();
590                                         for (Iterator<SimulationContext> j = context.iterator(); j
591                                                         .hasNext();) {
592                                                 SimulationContext seltext = j.next();
593                                                 input = new Term(String.valueOf(seltext.getType()
594                                                                 .getIndex()));
595                                                 critext.add(new TermQuery(input.createTerm(seltext
596                                                                 .getValue())), BooleanClause.Occur.MUST);
597                                         }
598                                         query.add(critext, BooleanClause.Occur.MUST);
599                                 }
600                                 fulquery.add(query, BooleanClause.Occur.SHOULD);
601                         }
602                         if (LOG.isInfoEnabled()) {
603                                 LOG.info("Searching studies by Lucene query \""
604                                                 + fulquery.toString());
605                         }
606                         // Creation of the studies filter
607                         BooleanFilter filter = new BooleanFilter();
608                         TermsFilter select = new TermsFilter();
609                         Term mytype = new Term("class");
610                         select.addTerm(mytype.createTerm("Study"));
611                         filter.add(new FilterClause(select, BooleanClause.Occur.SHOULD));
612
613                         // Creation of the sort criteria
614                         Sort sort = new Sort(new SortField(PROP_TITLE, SortField.STRING));
615
616                         // Search
617                         TopFieldDocs found = searcher.search(fulquery, filter, hitsize,
618                                         sort);
619
620                         if (found.totalHits < 1) {
621                                 return result; // No study found
622                         }
623
624                         // Construction of the result list
625                         ScoreDoc[] hits = found.scoreDocs;
626                         for (int i = 0; i < hits.length; i++) {
627                                 result.add(new IndexServiceImpl.ObjectProxy(searcher
628                                                 .doc(hits[i].doc)));
629                         }
630                         searcher.close();
631                 } catch (Exception error) {
632                         LOG.error("Error during Lucene search, reason:", error);
633                 }
634                 return result;
635         }
636
637         /**
638          * {@inheritDoc}
639          * 
640          * @see org.splat.service.SearchService#indexStudy(org.splat.dal.bo.som.Study)
641          */
642         @Deprecated
643         public void indexStudy(final Study study) {
644                 LOG.debug("Index study: id=" + study.getRid() + "; reference="
645                                 + study.getReference());
646                 try {
647                         Study.Properties sprop = new Study.Properties();
648                         List<Proxy> index = selectStudiesWhere(sprop.setReference(study
649                                         .getReference()));
650
651                         if (index.size() != 0) {
652                                 LOG.debug("The given study is already indexed.");
653                                 return; // The given study is already indexed
654                         }
655
656                         IndexService lucin = getIndex();
657                         Scenario[] scenes = study.getScenarii();
658
659                         LOG.debug("Number of study " + study.getReference() + " actors: "
660                                         + study.getActor().size());
661                         lucin.add(study);
662                         if (study.getProgressState() != ProgressState.inWORK) {
663                                 for (int i = 0; i < scenes.length; i++) {
664                                         List<KnowledgeElement> list = scenes[i]
665                                                         .getAllKnowledgeElements();
666                                         for (Iterator<KnowledgeElement> j = list.iterator(); j
667                                                         .hasNext();) {
668                                                 lucin.add(j.next());
669                                                 LOG.debug("Knowlegge added: id=" + j.next().getIndex());
670                                         }
671                                 }
672                         }
673                 } catch (Exception error) {
674                         LOG.error("Unable to index the study '" + study.getIndex()
675                                         + "', reason:", error);
676                 }
677         }
678
679         /**
680          * Get lucene index handler. Create the index if it is not exist.
681          * 
682          * @return IndexService
683          * @throws IOException
684          *             if error when creating a new lucene index
685          */
686         private IndexService getIndex() throws IOException {
687                 IndexService lucin = getIndexService();
688                 if (IndexWriter.isLocked(FSDirectory.open(getRepositoryService()
689                                 .getRepositoryIndexDirectory()))) {
690                         IndexWriter.unlock(FSDirectory.open(getRepositoryService()
691                                         .getRepositoryIndexDirectory()));
692                 }
693                 if (!lucin.exists()) {
694                         lucin.create(); // Happens when re-indexing all studies
695                 }
696                 return lucin;
697         }
698
699         /**
700          * Get the repositoryService.
701          * 
702          * @return the repositoryService
703          */
704         public RepositoryService getRepositoryService() {
705                 return _repositoryService;
706         }
707
708         /**
709          * Set the repositoryService.
710          * 
711          * @param repositoryService
712          *            the repositoryService to set
713          */
714         public void setRepositoryService(final RepositoryService repositoryService) {
715                 _repositoryService = repositoryService;
716         }
717
718         /**
719          * Get the indexService.
720          * 
721          * @return the indexService
722          */
723         public IndexService getIndexService() {
724                 return _indexService;
725         }
726
727         /**
728          * Set the indexService.
729          * 
730          * @param indexService
731          *            the indexService to set
732          */
733         public void setIndexService(final IndexService indexService) {
734                 _indexService = indexService;
735         }
736
737         /**
738          * Get the studyService.
739          * 
740          * @return the studyService
741          */
742         public StudyService getStudyService() {
743                 return _studyService;
744         }
745
746         /**
747          * Set the studyService.
748          * 
749          * @param studyService
750          *            the studyService to set
751          */
752         public void setStudyService(final StudyService studyService) {
753                 _studyService = studyService;
754         }
755
756         /**
757          * Get the studyDAO.
758          * 
759          * @return the studyDAO
760          */
761         public StudyDAO getStudyDAO() {
762                 return _studyDAO;
763         }
764
765         /**
766          * Set the studyDAO.
767          * 
768          * @param studyDAO
769          *            the studyDAO to set
770          */
771         public void setStudyDAO(final StudyDAO studyDAO) {
772                 _studyDAO = studyDAO;
773         }
774
775         /**
776          * Get the knowledgeElementDAO.
777          * 
778          * @return the knowledgeElementDAO
779          */
780         public KnowledgeElementDAO getKnowledgeElementDAO() {
781                 return _knowledgeElementDAO;
782         }
783
784         /**
785          * Set the knowledgeElementDAO.
786          * 
787          * @param knowledgeElementDAO
788          *            the knowledgeElementDAO to set
789          */
790         public void setKnowledgeElementDAO(
791                         final KnowledgeElementDAO knowledgeElementDAO) {
792                 _knowledgeElementDAO = knowledgeElementDAO;
793         }
794 }