1 /*****************************************************************************
5 * Creation date 05.10.2012
8 *****************************************************************************/
10 package org.splat.service;
13 import java.io.IOException;
14 import java.util.ArrayList;
15 import java.util.Iterator;
16 import java.util.List;
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;
51 public class SearchServiceImpl implements SearchService {
53 public final static Logger logger = Logger.getLogger(org.splat.service.SearchServiceImpl.class);
55 private RepositoryService _repositoryService;
57 private IndexService _indexService;
59 public List<Proxy> selectKnowledgeElementsWhere (KnowledgeElement.Properties... kprop) {
60 // ---------------------------------------------------------------------------------------------
61 List<Proxy> result = new ArrayList<Proxy>();
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();
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
75 Visibility area = kprop[i].getVisibility(); // Visibility
77 input = new Term("area");
78 query.add(new TermQuery(input.createTerm(area.toString())), BooleanClause.Occur.MUST);
80 ProgressState state = kprop[i].getProgressState(); // State
82 input = new Term("state");
83 query.add(new TermQuery(input.createTerm(state.toString())), BooleanClause.Occur.MUST);
85 String refid = kprop[i].getReference(); // Reference
87 input = new Term("ref");
88 query.add(new TermQuery(input.createTerm(refid)), BooleanClause.Occur.MUST);
90 KnowledgeElementType type = kprop[i].getType(); // Type
92 input = new Term("type");
93 query.add(new TermQuery(input.createTerm(type.getName())), BooleanClause.Occur.MUST);
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);
100 User actor = kprop[i].getActor(); // Contributor, Reviewer or Approver of the owner study
102 input = new Term("actor");
103 query.add(new TermQuery(input.createTerm(actor.toString())), BooleanClause.Occur.MUST);
105 String title = kprop[i].getTitle(); // Title
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);
116 query.add(critext, BooleanClause.Occur.MUST);
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);
126 query.add(critext, BooleanClause.Occur.MUST);
128 fulquery.add(query, BooleanClause.Occur.SHOULD);
130 if (logger.isInfoEnabled()) {
131 logger.info("Searching knowledges by Lucene query \"" + fulquery.toString() + "\".");
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));
140 // Creation of the sort criteria
141 Sort sort = new Sort(new SortField("title", SortField.STRING));
144 TopFieldDocs found = searcher.search(fulquery, filter, hitsize, sort);
146 if (found.totalHits < 1) return result; // No study found
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)) );
155 catch (Exception error) {
156 logger.error("Error during Lucene search, reason:", error);
161 public List<Proxy> selectStudiesWhere (Study.Properties... sprop) {
162 // ------------------------------------------------------------------------
163 List<Proxy> result = new ArrayList<Proxy>();
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();
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
177 Visibility area = sprop[i].getVisibility(); // Visibility
179 input = new Term("area");
180 query.add(new TermQuery(input.createTerm(area.toString())), BooleanClause.Occur.MUST);
182 ProgressState state = sprop[i].getProgressState(); // State
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);
192 query.add(new TermQuery(input.createTerm(state.toString())), BooleanClause.Occur.MUST);
195 String refid = sprop[i].getReference(); // Reference
197 input = new Term("ref");
198 query.add(new TermQuery(input.createTerm(refid)), BooleanClause.Occur.MUST);
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);
205 User actor = sprop[i].getActor(); // Contributor, Reviewer or Approver
207 input = new Term("actor");
208 query.add(new TermQuery(input.createTerm(actor.toString())), BooleanClause.Occur.MUST);
210 String title = sprop[i].getTitle(); // Title
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);
221 query.add(critext, BooleanClause.Occur.MUST);
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);
231 query.add(critext, BooleanClause.Occur.MUST);
233 fulquery.add(query, BooleanClause.Occur.SHOULD);
235 if (logger.isInfoEnabled()) {
236 logger.info("Searching studies by Lucene query \"" + fulquery.toString() + "\".");
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));
245 // Creation of the sort criteria
246 Sort sort = new Sort(new SortField("title", SortField.STRING));
249 TopFieldDocs found = searcher.search(fulquery, filter, hitsize, sort);
251 if (found.totalHits < 1) return result; // No study found
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)) );
260 catch (Exception error) {
261 logger.error("Error during Lucene search, reason:", error);
266 public void indexStudy (Study study) {
267 // -------------------------------------------
269 Study.Properties sprop = new Study.Properties();
270 List<Proxy> index = selectStudiesWhere(sprop.setReference(study.getReference()));
272 if (index.size() != 0) return; // The given study is already indexed
274 IndexService lucin = getIndex();
275 Scenario[] scenes = study.getScenarii();
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(); ) {
285 catch (Exception error) {
286 Database.logger.error("Unable to index the study '" + study.getIndex() + "', reason:", error);
290 public IndexService getIndex () throws IOException {
291 IndexService lucin = getIndexService();
292 if ( !lucin.exists() ) lucin.create(); // Happens when re-indexing all studies
297 * Get the repositoryService.
298 * @return the repositoryService
300 public RepositoryService getRepositoryService() {
301 return _repositoryService;
305 * Set the repositoryService.
306 * @param repositoryService the repositoryService to set
308 public void setRepositoryService(RepositoryService repositoryService) {
309 _repositoryService = repositoryService;
313 * Get the indexService.
314 * @return the indexService
316 public IndexService getIndexService() {
317 return _indexService;
321 * Set the indexService.
322 * @param indexService the indexService to set
324 public void setIndexService(IndexService indexService) {
325 _indexService = indexService;