1 package org.splat.service.technical;
5 * @author Daniel Brunier-Coulin
6 * @copyright OPEN CASCADE 2012
10 import java.io.IOException;
11 import java.io.Serializable;
12 import java.util.Iterator;
13 import java.util.List;
16 import org.apache.log4j.Logger;
18 import org.apache.lucene.analysis.standard.StandardAnalyzer;
19 import org.apache.lucene.document.Field;
20 import org.apache.lucene.index.CorruptIndexException;
21 import org.apache.lucene.index.IndexReader;
22 import org.apache.lucene.index.IndexWriter;
23 import org.apache.lucene.index.Term;
24 import org.apache.lucene.store.Directory;
25 import org.apache.lucene.store.FSDirectory;
26 import org.apache.lucene.store.LockObtainFailedException;
27 import org.apache.lucene.util.Version;
28 import org.splat.dal.bo.kernel.User;
29 import org.splat.dal.bo.som.KnowledgeElement;
30 import org.splat.dal.bo.som.ProgressState;
31 import org.splat.dal.bo.som.Scenario;
32 import org.splat.dal.bo.som.SimulationContext;
33 import org.splat.dal.bo.som.Study;
34 import org.splat.service.ProjectElementService;
35 import org.splat.service.dto.Proxy;
36 import org.splat.som.Step;
38 public class IndexServiceImpl implements IndexService {
40 private Directory index;
41 private org.apache.lucene.document.Document body;
42 private ProjectElementService _projectElementService;
43 private RepositoryService _repositoryService;
45 protected static StandardAnalyzer analyzer = new StandardAnalyzer(
47 private static final Logger logger = Logger
48 .getLogger(IndexServiceImpl.class);
50 private class Entry extends IndexWriter {
51 private org.apache.lucene.document.Document entry;
53 private Entry(Study study) throws CorruptIndexException,
54 LockObtainFailedException, IOException {
55 super(index, analyzer, false, IndexWriter.MaxFieldLength.UNLIMITED);
57 // Addition of mandatory fields
58 entry = new org.apache.lucene.document.Document();
60 field = body.getField("index");
61 field.setValue(String.valueOf(study.getIndex()));
63 field = body.getField("class");
64 field.setValue("Study");
66 field = body.getField("type");
67 field.setValue(""); // Reserved for configurable Study type
69 field = body.getField("ref");
70 field.setValue(study.getReference());
72 field = body.getField("area");
73 field.setValue(study.getVisibility().toString());
75 field = body.getField("state");
76 field.setValue(study.getProgressState().toString());
78 field = body.getField("author");
79 field.setValue(study.getAuthor().toString());
81 field = body.getField("title");
82 field.setValue(study.getTitle());
84 field = body.getField("contents");
85 field.setValue(study.getTitle());
88 // Addition of optional fields
90 setContextAt(getProjectElementService().getSteps(study));
93 private Entry(KnowledgeElement kelm) throws CorruptIndexException,
94 LockObtainFailedException, IOException {
95 super(index, analyzer, false, IndexWriter.MaxFieldLength.UNLIMITED);
97 // Addition of mandatory fields
98 entry = new org.apache.lucene.document.Document();
100 field = body.getField("index");
101 field.setValue(String.valueOf(kelm.getIndex()));
103 field = body.getField("class");
104 field.setValue("KnowledgeElement");
106 field = body.getField("type");
107 field.setValue(kelm.getType().getName());
109 field = body.getField("ref");
110 field.setValue(kelm.getReference());
112 field = body.getField("area");
113 field.setValue(kelm.getVisibility().toString());
115 field = body.getField("state");
116 field.setValue(kelm.getProgressState().toString());
118 field = body.getField("author");
119 field.setValue(kelm.getAuthor().toString());
121 field = body.getField("title");
122 field.setValue(kelm.getTitle());
124 field = body.getField("contents");
125 field.setValue(kelm.getTitle());
128 // TODO: Addition of optional fields
129 Scenario scene = kelm.getOwnerScenario();
130 Study study = scene.getOwnerStudy();
131 setActorsOf(study); // For restricting the visibility of knowledges attached to private studies
132 setContextAt(getProjectElementService().getSteps(study));
133 setContextAt(getProjectElementService().getSteps(scene));
136 private void add() throws CorruptIndexException, IOException {
138 // Save the new entry
139 optimize(); // Should be called before committing the index
140 close(); // Commits the index
143 private void update() throws CorruptIndexException, IOException {
144 String value = entry.getField("ref").stringValue(); // Only field with unique value
145 Term term = new Term("ref").createTerm(value);
146 updateDocument(term, entry);
147 // Save the updated entry
148 optimize(); // Should be called before committing the index
149 close(); // Commits the index
152 private void setContextAt(Step[] step) {
153 for (int i = 0; i < step.length; i++) {
154 List<SimulationContext> contexts = step[i]
155 .getAllSimulationContexts();
156 for (Iterator<SimulationContext> j = contexts.iterator(); j
158 SimulationContext context = j.next();
159 String type = String.valueOf(context.getType().getIndex());
160 String value = context.getValue();
161 entry.add(new Field(type, value, Field.Store.NO,
162 Field.Index.NOT_ANALYZED));
167 private void setActorsOf(Study study) {
168 // RKV: This set is always not null. Let's assume that it must be initialized before reindexing: Set<User> actors =
169 // study.getActors();
170 Set<User> actors = study.getActor(); // RKV
171 if (logger.isDebugEnabled()) {
172 logger.debug("Study " + study.getReference()
173 + " actors number to be added to the lucen index: "
176 for (Iterator<User> i = actors.iterator(); i.hasNext();) {
177 String value = i.next().toString();
178 entry.add(new Field("actor", value, Field.Store.NO,
179 Field.Index.NOT_ANALYZED));
180 if (logger.isDebugEnabled()) {
181 logger.debug(" actor added to the lucen index: " + value);
187 public static class ObjectProxy implements Proxy, Serializable {
188 // --------------------------------------------------------------
191 private ProgressState state;
192 private String title;
195 private static final long serialVersionUID = -4386494192709562221L;
197 public ObjectProxy(org.apache.lucene.document.Document ludoc) {
198 rid = Long.valueOf(ludoc.get("index"));
199 sid = ludoc.get("ref");
200 state = ProgressState.valueOf(ludoc.get("state"));
201 title = ludoc.get("title");
202 name = ludoc.get("author");
205 public String getAuthorName() {
209 public Long getIndex() {
213 public ProgressState getProgressState() {
217 public String getReference() {
221 public String getTitle() {
225 public String getType() {
230 // ==============================================================================================================================
232 // ==============================================================================================================================
234 public void configure() throws IOException {
235 File indir = getRepositoryService().getRepositoryIndexDirectory();
236 index = FSDirectory.open(indir);
237 body = new org.apache.lucene.document.Document();
238 body.add(new Field("index", "", Field.Store.YES,
239 Field.Index.NOT_ANALYZED));
240 body.add(new Field("class", "", Field.Store.NO,
241 Field.Index.NOT_ANALYZED));
242 body.add(new Field("type", "", Field.Store.YES,
243 Field.Index.NOT_ANALYZED));
245 .add(new Field("ref", "", Field.Store.YES,
246 Field.Index.NOT_ANALYZED));
248 .add(new Field("area", "", Field.Store.NO,
249 Field.Index.NOT_ANALYZED));
250 body.add(new Field("state", "", Field.Store.YES,
251 Field.Index.NOT_ANALYZED));
252 body.add(new Field("author", "", Field.Store.YES,
253 Field.Index.NOT_ANALYZED));
254 body.add(new Field("title", "", Field.Store.YES,
255 Field.Index.NOT_ANALYZED));
257 .add(new Field("contents", "", Field.Store.NO,
258 Field.Index.ANALYZED));
260 this.create(); // Happens when re-indexing all studies
263 public void create() throws IOException {
264 // -------------------------------
265 Directory index = FSDirectory.open(getRepositoryService()
266 .getRepositoryIndexDirectory());
267 IndexWriter writer = new IndexWriter(index, analyzer, true,
268 IndexWriter.MaxFieldLength.UNLIMITED);
269 writer.close(); // ==== Creates an empty index
272 // ==============================================================================================================================
274 // ==============================================================================================================================
276 public void add(Study study) throws IOException {
277 // --------------------------------
278 IndexServiceImpl.Entry entry = new Entry(study);
280 if (logger.isInfoEnabled()) {
281 logger.info("Study \"" + study.getIndex() + "\" indexed.");
285 public void add(KnowledgeElement kelm) throws IOException {
286 // ------------------------------------------
287 IndexServiceImpl.Entry entry = new Entry(kelm);
289 if (logger.isInfoEnabled()) {
290 logger.info("Knowledge \"" + kelm.getIndex() + "\" indexed.");
294 public boolean exists() {
295 // ---------------------------
297 return IndexReader.indexExists(index);
298 } catch (IOException error) {
299 error.printStackTrace();
304 public void update(Study study) throws IOException {
305 // -----------------------------------
306 IndexServiceImpl.Entry entry = new Entry(study);
308 if (logger.isInfoEnabled()) {
309 logger.info("Study \"" + study.getIndex() + "\" re-indexed.");
313 public void update(KnowledgeElement kelm) throws IOException {
314 // ---------------------------------------------
315 IndexServiceImpl.Entry entry = new Entry(kelm);
317 if (logger.isInfoEnabled()) {
318 logger.info("Knowledge \"" + kelm.getIndex() + "\" re-indexed.");
323 * Get the projectElementService.
325 * @return the projectElementService
327 public ProjectElementService getProjectElementService() {
328 return _projectElementService;
332 * Set the projectElementService.
334 * @param projectElementService
335 * the projectElementService to set
337 public void setProjectElementService(
338 ProjectElementService projectElementService) {
339 _projectElementService = projectElementService;
343 * Get the repositoryService.
345 * @return the repositoryService
347 public RepositoryService getRepositoryService() {
348 return _repositoryService;
352 * Set the repositoryService.
354 * @param repositoryService
355 * the repositoryService to set
357 public void setRepositoryService(RepositoryService repositoryService) {
358 _repositoryService = repositoryService;