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 Set<User> actors = study.getActors();
165 for (Iterator<User> i=actors.iterator(); i.hasNext(); ) {
166 String value = i.next().toString();
167 entry.add( new Field("actor", value, Field.Store.NO, Field.Index.NOT_ANALYZED) );
171 public static class ObjectProxy implements Proxy, Serializable {
172 // --------------------------------------------------------------
175 private ProgressState state;
176 private String title;
179 private static final long serialVersionUID = -4386494192709562221L;
181 public ObjectProxy (org.apache.lucene.document.Document ludoc) {
182 rid = Long.valueOf(ludoc.get("index"));
183 sid = ludoc.get("ref");
184 state = ProgressState.valueOf(ludoc.get("state"));
185 title = ludoc.get("title");
186 name = ludoc.get("author");
188 public String getAuthorName () {
191 public Long getIndex () {
194 public ProgressState getProgressState () {
197 public String getReference () {
200 public String getTitle () {
203 public String getType () {
208 // ==============================================================================================================================
210 // ==============================================================================================================================
212 public void configure () throws IOException {
213 File indir = getRepositoryService().getRepositoryIndexDirectory();
214 index = FSDirectory.open(indir);
215 body = new org.apache.lucene.document.Document();
216 body.add( new Field("index", "", Field.Store.YES, Field.Index.NOT_ANALYZED) );
217 body.add( new Field("class", "", Field.Store.NO, Field.Index.NOT_ANALYZED) );
218 body.add( new Field("type", "", Field.Store.YES, Field.Index.NOT_ANALYZED) );
219 body.add( new Field("ref", "", Field.Store.YES, Field.Index.NOT_ANALYZED) );
220 body.add( new Field("area", "", Field.Store.NO, Field.Index.NOT_ANALYZED) );
221 body.add( new Field("state", "", Field.Store.YES, Field.Index.NOT_ANALYZED) );
222 body.add( new Field("author", "", Field.Store.YES, Field.Index.NOT_ANALYZED) );
223 body.add( new Field("title", "", Field.Store.YES, Field.Index.NOT_ANALYZED) );
224 body.add( new Field("contents","", Field.Store.NO, Field.Index.ANALYZED) );
225 if ( !this.exists() ) this.create(); // Happens when re-indexing all studies
228 public void create () throws IOException {
229 // -------------------------------
230 Directory index = FSDirectory.open(getRepositoryService().getRepositoryIndexDirectory());
231 IndexWriter writer = new IndexWriter(index, analyzer, true, IndexWriter.MaxFieldLength.UNLIMITED);
232 writer.close(); // ==== Creates an empty index
235 // ==============================================================================================================================
237 // ==============================================================================================================================
239 public void add (Study study) throws IOException {
240 // --------------------------------
241 IndexServiceImpl.Entry entry = new Entry(study);
243 if (logger.isInfoEnabled()) {
244 logger.info("Study \"" + study.getIndex() + "\" indexed.");
248 public void add (KnowledgeElement kelm) throws IOException {
249 // ------------------------------------------
250 IndexServiceImpl.Entry entry = new Entry(kelm);
252 if (logger.isInfoEnabled()) {
253 logger.info("Knowledge \"" + kelm.getIndex() + "\" indexed.");
257 public boolean exists () {
258 // ---------------------------
260 return IndexReader.indexExists(index);
262 catch (IOException error) {
263 error.printStackTrace();
268 public void update (Study study) throws IOException {
269 // -----------------------------------
270 IndexServiceImpl.Entry entry = new Entry(study);
272 if (logger.isInfoEnabled()) {
273 logger.info("Study \"" + study.getIndex() + "\" re-indexed.");
277 public void update (KnowledgeElement kelm) throws IOException {
278 // ---------------------------------------------
279 IndexServiceImpl.Entry entry = new Entry(kelm);
281 if (logger.isInfoEnabled()) {
282 logger.info("Knowledge \"" + kelm.getIndex() + "\" re-indexed.");
286 * Get the projectElementService.
287 * @return the projectElementService
289 public ProjectElementService getProjectElementService() {
290 return _projectElementService;
294 * Set the projectElementService.
295 * @param projectElementService the projectElementService to set
297 public void setProjectElementService(ProjectElementService projectElementService) {
298 _projectElementService = projectElementService;
302 * Get the repositoryService.
303 * @return the repositoryService
305 public RepositoryService getRepositoryService() {
306 return _repositoryService;
310 * Set the repositoryService.
311 * @param repositoryService the repositoryService to set
313 public void setRepositoryService(RepositoryService repositoryService) {
314 _repositoryService = repositoryService;