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;
39 * Implementation of the service for work with Lucen index.
41 public class IndexServiceImpl implements IndexService {
43 private Directory index;
44 private org.apache.lucene.document.Document body;
45 private ProjectElementService _projectElementService;
46 private RepositoryService _repositoryService;
48 protected static StandardAnalyzer analyzer = new StandardAnalyzer(
50 private static final Logger logger = Logger
51 .getLogger(IndexServiceImpl.class);
53 private class Entry extends IndexWriter {
54 private org.apache.lucene.document.Document entry;
56 private Entry(Study study) throws CorruptIndexException,
57 LockObtainFailedException, IOException {
58 super(index, analyzer, false, IndexWriter.MaxFieldLength.UNLIMITED);
60 // Addition of mandatory fields
61 entry = new org.apache.lucene.document.Document();
63 field = body.getField("index");
64 field.setValue(String.valueOf(study.getIndex()));
66 field = body.getField("class");
67 field.setValue("Study");
69 field = body.getField("type");
70 field.setValue(""); // Reserved for configurable Study type
72 field = body.getField("ref");
73 field.setValue(study.getReference());
75 field = body.getField("area");
76 field.setValue(study.getVisibility().toString());
78 field = body.getField("state");
79 field.setValue(study.getProgressState().toString());
81 field = body.getField("author");
82 field.setValue(study.getAuthor().toString());
84 field = body.getField("title");
85 field.setValue(study.getTitle());
87 field = body.getField("contents");
88 field.setValue(study.getTitle());
91 // Addition of optional fields
93 setContextAt(getProjectElementService().getSteps(study));
96 private Entry(KnowledgeElement kelm) throws CorruptIndexException,
97 LockObtainFailedException, IOException {
98 super(index, analyzer, false, IndexWriter.MaxFieldLength.UNLIMITED);
100 // Addition of mandatory fields
101 entry = new org.apache.lucene.document.Document();
103 field = body.getField("index");
104 field.setValue(String.valueOf(kelm.getIndex()));
106 field = body.getField("class");
107 field.setValue("KnowledgeElement");
109 field = body.getField("type");
110 field.setValue(kelm.getType().getName());
112 field = body.getField("ref");
113 field.setValue(kelm.getReference());
115 field = body.getField("area");
116 field.setValue(kelm.getVisibility().toString());
118 field = body.getField("state");
119 field.setValue(kelm.getProgressState().toString());
121 field = body.getField("author");
122 field.setValue(kelm.getAuthor().toString());
124 field = body.getField("title");
125 field.setValue(kelm.getTitle());
127 field = body.getField("contents");
128 field.setValue(kelm.getTitle());
131 // TODO: Addition of optional fields
132 Scenario scene = kelm.getOwnerScenario();
133 Study study = scene.getOwnerStudy();
134 setActorsOf(study); // For restricting the visibility of knowledges attached to private studies
135 setContextAt(getProjectElementService().getSteps(study));
136 setContextAt(getProjectElementService().getSteps(scene));
139 private void add() throws CorruptIndexException, IOException {
141 // Save the new entry
142 optimize(); // Should be called before committing the index
143 close(); // Commits the index
146 private void update() throws CorruptIndexException, IOException {
147 String value = entry.getField("ref").stringValue(); // Only field with unique value
148 Term term = new Term("ref").createTerm(value);
149 updateDocument(term, entry);
150 // Save the updated entry
151 optimize(); // Should be called before committing the index
152 close(); // Commits the index
155 private void setContextAt(Step[] step) {
156 for (int i = 0; i < step.length; i++) {
157 List<SimulationContext> contexts = step[i]
158 .getAllSimulationContexts();
159 for (Iterator<SimulationContext> j = contexts.iterator(); j
161 SimulationContext context = j.next();
162 String type = String.valueOf(context.getType().getIndex());
163 String value = context.getValue();
164 entry.add(new Field(type, value, Field.Store.NO,
165 Field.Index.NOT_ANALYZED));
170 private void setActorsOf(Study study) {
171 // RKV: This set is always not null. Let's assume that it must be initialized before reindexing: Set<User> actors =
172 // study.getActors();
173 Set<User> actors = study.getActor(); // RKV
174 if (logger.isDebugEnabled()) {
175 logger.debug("Study " + study.getReference()
176 + " actors number to be added to the lucen index: "
179 for (Iterator<User> i = actors.iterator(); i.hasNext();) {
180 String value = i.next().toString();
181 entry.add(new Field("actor", value, Field.Store.NO,
182 Field.Index.NOT_ANALYZED));
183 if (logger.isDebugEnabled()) {
184 logger.debug(" actor added to the lucen index: " + value);
190 public static class ObjectProxy implements Proxy, Serializable {
191 // --------------------------------------------------------------
194 private ProgressState state;
195 private String title;
198 private static final long serialVersionUID = -4386494192709562221L;
200 public ObjectProxy(org.apache.lucene.document.Document ludoc) {
201 rid = Long.valueOf(ludoc.get("index"));
202 sid = ludoc.get("ref");
203 state = ProgressState.valueOf(ludoc.get("state"));
204 title = ludoc.get("title");
205 name = ludoc.get("author");
208 public String getAuthorName() {
212 public Long getIndex() {
216 public ProgressState getProgressState() {
220 public String getReference() {
224 public String getTitle() {
228 public String getType() {
233 // ==============================================================================================================================
235 // ==============================================================================================================================
237 public void configure() throws IOException {
238 File indir = getRepositoryService().getRepositoryIndexDirectory();
239 index = FSDirectory.open(indir);
240 body = new org.apache.lucene.document.Document();
241 body.add(new Field("index", "", Field.Store.YES,
242 Field.Index.NOT_ANALYZED));
243 body.add(new Field("class", "", Field.Store.NO,
244 Field.Index.NOT_ANALYZED));
245 body.add(new Field("type", "", Field.Store.YES,
246 Field.Index.NOT_ANALYZED));
248 .add(new Field("ref", "", Field.Store.YES,
249 Field.Index.NOT_ANALYZED));
251 .add(new Field("area", "", Field.Store.NO,
252 Field.Index.NOT_ANALYZED));
253 body.add(new Field("state", "", Field.Store.YES,
254 Field.Index.NOT_ANALYZED));
255 body.add(new Field("author", "", Field.Store.YES,
256 Field.Index.NOT_ANALYZED));
257 body.add(new Field("title", "", Field.Store.YES,
258 Field.Index.NOT_ANALYZED));
260 .add(new Field("contents", "", Field.Store.NO,
261 Field.Index.ANALYZED));
263 this.create(); // Happens when re-indexing all studies
266 public void create() throws IOException {
267 // -------------------------------
268 Directory index = FSDirectory.open(getRepositoryService()
269 .getRepositoryIndexDirectory());
270 IndexWriter writer = new IndexWriter(index, analyzer, true,
271 IndexWriter.MaxFieldLength.UNLIMITED);
272 writer.close(); // ==== Creates an empty index
275 // ==============================================================================================================================
277 // ==============================================================================================================================
279 public void add(Study study) throws IOException {
280 // --------------------------------
281 IndexServiceImpl.Entry entry = new Entry(study);
283 if (logger.isInfoEnabled()) {
284 logger.info("Study \"" + study.getIndex() + "\" indexed.");
288 public void add(KnowledgeElement kelm) throws IOException {
289 // ------------------------------------------
290 IndexServiceImpl.Entry entry = new Entry(kelm);
292 if (logger.isInfoEnabled()) {
293 logger.info("Knowledge \"" + kelm.getIndex() + "\" indexed.");
297 public boolean exists() {
298 // ---------------------------
300 return IndexReader.indexExists(index);
301 } catch (IOException error) {
302 error.printStackTrace();
307 public void update(Study study) throws IOException {
308 // -----------------------------------
309 IndexServiceImpl.Entry entry = new Entry(study);
311 if (logger.isInfoEnabled()) {
312 logger.info("Study \"" + study.getIndex() + "\" re-indexed.");
316 public void update(KnowledgeElement kelm) throws IOException {
317 // ---------------------------------------------
318 IndexServiceImpl.Entry entry = new Entry(kelm);
320 if (logger.isInfoEnabled()) {
321 logger.info("Knowledge \"" + kelm.getIndex() + "\" re-indexed.");
326 * Get the projectElementService.
328 * @return the projectElementService
330 public ProjectElementService getProjectElementService() {
331 return _projectElementService;
335 * Set the projectElementService.
337 * @param projectElementService
338 * the projectElementService to set
340 public void setProjectElementService(
341 ProjectElementService projectElementService) {
342 _projectElementService = projectElementService;
346 * Get the repositoryService.
348 * @return the repositoryService
350 public RepositoryService getRepositoryService() {
351 return _repositoryService;
355 * Set the repositoryService.
357 * @param repositoryService
358 * the repositoryService to set
360 public void setRepositoryService(RepositoryService repositoryService) {
361 _repositoryService = repositoryService;