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