1 package org.splat.service.technical;
4 * @author Daniel Brunier-Coulin
5 * @copyright OPEN CASCADE 2012
9 import java.io.IOException;
10 import java.io.Serializable;
11 import java.util.Iterator;
12 import java.util.List;
15 import org.apache.log4j.Logger;
17 import org.apache.lucene.analysis.standard.StandardAnalyzer;
18 import org.apache.lucene.document.Field;
19 import org.apache.lucene.index.CorruptIndexException;
20 import org.apache.lucene.index.IndexReader;
21 import org.apache.lucene.index.IndexWriter;
22 import org.apache.lucene.index.Term;
23 import org.apache.lucene.store.Directory;
24 import org.apache.lucene.store.FSDirectory;
25 import org.apache.lucene.store.LockObtainFailedException;
26 import org.apache.lucene.util.Version;
27 import org.splat.dal.bo.kernel.User;
28 import org.splat.dal.bo.som.KnowledgeElement;
29 import org.splat.dal.bo.som.ProgressState;
30 import org.splat.dal.bo.som.Scenario;
31 import org.splat.dal.bo.som.SimulationContext;
32 import org.splat.dal.bo.som.Study;
33 import org.splat.dal.dao.som.Database;
34 import org.splat.service.ProjectElementService;
35 import org.splat.service.dto.Proxy;
36 import org.splat.som.Step;
39 public class IndexServiceImpl implements IndexService {
41 private Directory index;
42 private org.apache.lucene.document.Document body;
43 private ProjectElementService _projectElementService;
44 private RepositoryService _repositoryService;
46 protected static StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_29);
47 private static final Logger logger = Logger.getLogger(IndexServiceImpl.class);
49 private class Entry extends IndexWriter {
50 // ---------------------------------------
51 private org.apache.lucene.document.Document entry;
53 private Entry (Study study) throws CorruptIndexException, 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));
92 private Entry (KnowledgeElement kelm) throws CorruptIndexException, LockObtainFailedException, IOException
94 super(index, analyzer, false, IndexWriter.MaxFieldLength.UNLIMITED);
96 // Addition of mandatory fields
97 entry = new org.apache.lucene.document.Document();
99 field = body.getField("index");
100 field.setValue(String.valueOf(kelm.getIndex()));
102 field = body.getField("class");
103 field.setValue("KnowledgeElement");
105 field = body.getField("type");
106 field.setValue(kelm.getType().getName());
108 field = body.getField("ref");
109 field.setValue(kelm.getReference());
111 field = body.getField("area");
112 field.setValue(kelm.getVisibility().toString());
114 field = body.getField("state");
115 field.setValue(kelm.getProgressState().toString());
117 field = body.getField("author");
118 field.setValue(kelm.getAuthor().toString());
120 field = body.getField("title");
121 field.setValue(kelm.getTitle());
123 field = body.getField("contents");
124 field.setValue(kelm.getTitle());
127 //TODO: Addition of optional fields
128 Scenario scene = kelm.getOwnerScenario();
129 Study study = scene.getOwnerStudy();
130 setActorsOf(study); // For restricting the visibility of knowledges attached to private studies
131 setContextAt(getProjectElementService().getSteps(study));
132 setContextAt(getProjectElementService().getSteps(scene));
134 private void add () throws CorruptIndexException, IOException
137 // Save the new entry
138 optimize(); // Should be called before committing the index
139 close(); // Commits the index
141 private void update () throws CorruptIndexException, IOException
143 String value = entry.getField("ref").stringValue(); // Only field with unique value
144 Term term = new Term("ref").createTerm(value);
145 updateDocument(term, entry);
146 // Save the updated entry
147 optimize(); // Should be called before committing the index
148 close(); // Commits the index
150 private void setContextAt (Step[] step)
152 for (int i=0; i<step.length; i++) {
153 List<SimulationContext> contexts = step[i].getAllSimulationContexts();
154 for (Iterator<SimulationContext> j=contexts.iterator(); j.hasNext();) {
155 SimulationContext context = j.next();
156 String type = String.valueOf(context.getType().getIndex());
157 String value = context.getValue();
158 entry.add( new Field(type, value, Field.Store.NO, Field.Index.NOT_ANALYZED) );
162 private void setActorsOf (Study study)
164 //RKV: This set is always not null. Let's assume that it must be initialized before reindexing: Set<User> actors = study.getActors();
165 Set<User> actors = study.getActor(); //RKV
166 for (Iterator<User> i=actors.iterator(); i.hasNext(); ) {
167 String value = i.next().toString();
168 entry.add( new Field("actor", value, Field.Store.NO, Field.Index.NOT_ANALYZED) );
172 public static class ObjectProxy implements Proxy, Serializable {
173 // --------------------------------------------------------------
176 private ProgressState state;
177 private String title;
180 private static final long serialVersionUID = -4386494192709562221L;
182 public ObjectProxy (org.apache.lucene.document.Document ludoc) {
183 rid = Long.valueOf(ludoc.get("index"));
184 sid = ludoc.get("ref");
185 state = ProgressState.valueOf(ludoc.get("state"));
186 title = ludoc.get("title");
187 name = ludoc.get("author");
189 public String getAuthorName () {
192 public Long getIndex () {
195 public ProgressState getProgressState () {
198 public String getReference () {
201 public String getTitle () {
204 public String getType () {
209 // ==============================================================================================================================
211 // ==============================================================================================================================
213 public void configure () throws IOException {
214 File indir = getRepositoryService().getRepositoryIndexDirectory();
215 index = FSDirectory.open(indir);
216 body = new org.apache.lucene.document.Document();
217 body.add( new Field("index", "", Field.Store.YES, Field.Index.NOT_ANALYZED) );
218 body.add( new Field("class", "", Field.Store.NO, Field.Index.NOT_ANALYZED) );
219 body.add( new Field("type", "", Field.Store.YES, Field.Index.NOT_ANALYZED) );
220 body.add( new Field("ref", "", Field.Store.YES, Field.Index.NOT_ANALYZED) );
221 body.add( new Field("area", "", Field.Store.NO, Field.Index.NOT_ANALYZED) );
222 body.add( new Field("state", "", Field.Store.YES, Field.Index.NOT_ANALYZED) );
223 body.add( new Field("author", "", Field.Store.YES, Field.Index.NOT_ANALYZED) );
224 body.add( new Field("title", "", Field.Store.YES, Field.Index.NOT_ANALYZED) );
225 body.add( new Field("contents","", Field.Store.NO, Field.Index.ANALYZED) );
226 if ( !this.exists() ) this.create(); // Happens when re-indexing all studies
229 public void create () throws IOException {
230 // -------------------------------
231 Directory index = FSDirectory.open(getRepositoryService().getRepositoryIndexDirectory());
232 IndexWriter writer = new IndexWriter(index, analyzer, true, IndexWriter.MaxFieldLength.UNLIMITED);
233 writer.close(); // ==== Creates an empty index
236 // ==============================================================================================================================
238 // ==============================================================================================================================
240 public void add (Study study) throws IOException {
241 // --------------------------------
242 IndexServiceImpl.Entry entry = new Entry(study);
244 if (logger.isInfoEnabled()) {
245 logger.info("Study \"" + study.getIndex() + "\" indexed.");
249 public void add (KnowledgeElement kelm) throws IOException {
250 // ------------------------------------------
251 IndexServiceImpl.Entry entry = new Entry(kelm);
253 if (logger.isInfoEnabled()) {
254 logger.info("Knowledge \"" + kelm.getIndex() + "\" indexed.");
258 public boolean exists () {
259 // ---------------------------
261 return IndexReader.indexExists(index);
263 catch (IOException error) {
264 error.printStackTrace();
269 public void update (Study study) throws IOException {
270 // -----------------------------------
271 IndexServiceImpl.Entry entry = new Entry(study);
273 if (logger.isInfoEnabled()) {
274 logger.info("Study \"" + study.getIndex() + "\" re-indexed.");
278 public void update (KnowledgeElement kelm) throws IOException {
279 // ---------------------------------------------
280 IndexServiceImpl.Entry entry = new Entry(kelm);
282 if (logger.isInfoEnabled()) {
283 logger.info("Knowledge \"" + kelm.getIndex() + "\" re-indexed.");
287 * Get the projectElementService.
288 * @return the projectElementService
290 public ProjectElementService getProjectElementService() {
291 return _projectElementService;
295 * Set the projectElementService.
296 * @param projectElementService the projectElementService to set
298 public void setProjectElementService(ProjectElementService projectElementService) {
299 _projectElementService = projectElementService;
303 * Get the repositoryService.
304 * @return the repositoryService
306 public RepositoryService getRepositoryService() {
307 return _repositoryService;
311 * Set the repositoryService.
312 * @param repositoryService the repositoryService to set
314 public void setRepositoryService(RepositoryService repositoryService) {
315 _repositoryService = repositoryService;