1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package fr.paris.lutece.plugins.directory.service.directorysearch;
35
36 import fr.paris.lutece.plugins.directory.business.Directory;
37 import fr.paris.lutece.plugins.directory.business.DirectoryFilter;
38 import fr.paris.lutece.plugins.directory.business.DirectoryHome;
39 import fr.paris.lutece.plugins.directory.business.IndexerAction;
40 import fr.paris.lutece.plugins.directory.business.Record;
41 import fr.paris.lutece.plugins.directory.business.RecordField;
42 import fr.paris.lutece.plugins.directory.business.RecordFieldFilter;
43 import fr.paris.lutece.plugins.directory.business.RecordFieldHome;
44 import fr.paris.lutece.plugins.directory.service.DirectoryPlugin;
45 import fr.paris.lutece.plugins.directory.service.record.IRecordService;
46 import fr.paris.lutece.plugins.directory.service.record.RecordService;
47 import fr.paris.lutece.plugins.directory.utils.DirectoryUtils;
48 import fr.paris.lutece.portal.service.message.SiteMessageException;
49 import fr.paris.lutece.portal.service.plugin.Plugin;
50 import fr.paris.lutece.portal.service.plugin.PluginService;
51 import fr.paris.lutece.portal.service.spring.SpringContextService;
52 import fr.paris.lutece.portal.service.util.AppPropertiesService;
53
54 import org.apache.lucene.document.DateTools;
55 import org.apache.lucene.document.Document;
56 import org.apache.lucene.document.Field;
57 import org.apache.lucene.document.FieldType;
58 import org.apache.lucene.document.StringField;
59 import org.apache.lucene.document.TextField;
60 import org.apache.lucene.index.CorruptIndexException;
61 import org.apache.lucene.index.IndexWriter;
62 import org.apache.lucene.index.Term;
63
64 import java.io.IOException;
65
66 import java.util.ArrayList;
67 import java.util.Date;
68 import java.util.HashMap;
69 import java.util.Iterator;
70 import java.util.List;
71
72
73
74
75
76 public class DirectoryIndexer implements IDirectorySearchIndexer
77 {
78 private static final int LIST_RECORD_STEP = 50;
79 private static final String ENABLE_VALUE_TRUE = "1";
80 private static final String PROPERTY_INDEXER_DESCRIPTION = "directory.internalIndexer.description";
81 private static final String PROPERTY_INDEXER_NAME = "directory.internalIndexer.name";
82 private static final String PROPERTY_INDEXER_VERSION = "directory.internalIndexer.version";
83 private static final String PROPERTY_INDEXER_ENABLE = "directory.internalIndexer.enable";
84 private static final List<Integer> _lListIdRecordToDelete = new ArrayList<Integer>( );
85
86
87
88
89 @Override
90 public String getDescription( )
91 {
92 return AppPropertiesService.getProperty( PROPERTY_INDEXER_DESCRIPTION );
93 }
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109 private HashMap<Integer, List<Integer>> indexListRecord( IndexWriter indexWriter, HashMap<Integer, List<Integer>> lListId, Plugin plugin )
110 throws CorruptIndexException, IOException, InterruptedException
111 {
112 Iterator<Integer> it = lListId.keySet( ).iterator( );
113 IRecordService recordService = SpringContextService.getBean( RecordService.BEAN_SERVICE );
114
115 while ( it.hasNext( ) )
116 {
117 Integer nDirectoryId = it.next( );
118 Directory directory = DirectoryHome.findByPrimaryKey( nDirectoryId, plugin );
119 List<Integer> lListRecordId = lListId.get( nDirectoryId );
120
121 int nListRecordSize = lListRecordId.size( );
122
123 if ( nListRecordSize > LIST_RECORD_STEP )
124 {
125 int nIndex = 0;
126 int nMax = nListRecordSize - LIST_RECORD_STEP;
127
128 for ( int i = 0; i < nMax; i += LIST_RECORD_STEP )
129 {
130 List<RecordField> lListrecordField = RecordFieldHome.getRecordFieldListByRecordIdList( lListRecordId.subList( i, i + LIST_RECORD_STEP ),
131 plugin );
132
133 for ( RecordField recordField : lListrecordField )
134 {
135 indexWriter.addDocument( getDocument( recordField, recordField.getRecord( ), directory ) );
136 }
137
138 for ( Record record : recordService.loadListByListId( lListRecordId.subList( i, i + LIST_RECORD_STEP ), plugin ) )
139 {
140 indexWriter.addDocument( getDocument( record, directory ) );
141 }
142
143 nIndex = i;
144 }
145
146 nIndex += LIST_RECORD_STEP;
147
148 List<RecordField> lListrecordField = RecordFieldHome
149 .getRecordFieldListByRecordIdList( lListRecordId.subList( nIndex, nListRecordSize ), plugin );
150
151 for ( RecordField recordField : lListrecordField )
152 {
153 indexWriter.addDocument( getDocument( recordField, recordField.getRecord( ), directory ) );
154 }
155
156 for ( Record record : recordService.loadListByListId( lListRecordId.subList( nIndex, nListRecordSize ), plugin ) )
157 {
158 indexWriter.addDocument( getDocument( record, directory ) );
159 }
160 }
161 else
162 {
163 List<RecordField> lListrecordField = RecordFieldHome.getRecordFieldListByRecordIdList( lListRecordId, plugin );
164
165 for ( RecordField recordField : lListrecordField )
166 {
167 indexWriter.addDocument( getDocument( recordField, recordField.getRecord( ), directory ) );
168 }
169
170 for ( Record record : recordService.loadListByListId( lListRecordId, plugin ) )
171 {
172 indexWriter.addDocument( getDocument( record, directory ) );
173 }
174 }
175 }
176
177 return new HashMap<Integer, List<Integer>>( );
178 }
179
180
181
182
183
184
185
186
187
188
189
190
191 private HashMap<Integer, List<Integer>> appendKey( Integer nIdDirectory, Integer nIdAction, HashMap<Integer, List<Integer>> hm )
192 {
193 if ( hm.containsKey( nIdDirectory ) )
194 {
195 hm.get( nIdDirectory ).add( nIdAction );
196 }
197 else
198 {
199 List<Integer> lListIdRecord = new ArrayList<Integer>( );
200 lListIdRecord.add( nIdAction );
201 hm.put( nIdDirectory, lListIdRecord );
202 }
203
204 return hm;
205 }
206
207
208
209
210 @Override
211 public void processIndexing( IndexWriter indexWriter, boolean bCreate, StringBuffer sbLogs ) throws IOException, InterruptedException, SiteMessageException
212 {
213 Plugin plugin = PluginService.getPlugin( DirectoryPlugin.PLUGIN_NAME );
214 RecordFieldFilter recordFieldFilter = new RecordFieldFilter( );
215 HashMap<Integer, List<Integer>> hm = new HashMap<Integer, List<Integer>>( );
216 IRecordService recordService = SpringContextService.getBean( RecordService.BEAN_SERVICE );
217
218 if ( !bCreate )
219 {
220
221
222 for ( IndexerAction action : DirectorySearchService.getInstance( ).getAllIndexerActionByTask( IndexerAction.TASK_DELETE, plugin ) )
223 {
224 sbLogRecord( sbLogs, action.getIdRecord( ), DirectoryUtils.CONSTANT_ID_NULL, IndexerAction.TASK_DELETE );
225 indexWriter.deleteDocuments( new Term( DirectorySearchItem.FIELD_ID_DIRECTORY_RECORD, Integer.toString( action.getIdRecord( ) ) ) );
226 DirectorySearchService.getInstance( ).removeIndexerAction( action.getIdAction( ), plugin );
227 }
228
229
230 for ( Integer nIdRecord : _lListIdRecordToDelete )
231 {
232 indexWriter.deleteDocuments( new Term( DirectorySearchItem.FIELD_ID_DIRECTORY_RECORD, Integer.toString( nIdRecord ) ) );
233 }
234
235 _lListIdRecordToDelete.clear( );
236
237
238 for ( IndexerAction action : DirectorySearchService.getInstance( ).getAllIndexerActionByTask( IndexerAction.TASK_MODIFY, plugin ) )
239 {
240 Integer nDirectoryId = recordService.getDirectoryIdByRecordId( Integer.valueOf( action.getIdRecord( ) ), plugin );
241
242 if ( nDirectoryId != null )
243 {
244 sbLogRecord( sbLogs, action.getIdRecord( ), nDirectoryId.intValue( ), IndexerAction.TASK_MODIFY );
245
246 indexWriter.deleteDocuments( new Term( DirectorySearchItem.FIELD_ID_DIRECTORY_RECORD, Integer.toString( action.getIdRecord( ) ) ) );
247
248 this.appendKey( nDirectoryId, action.getIdRecord( ), hm );
249 }
250
251 DirectorySearchService.getInstance( ).removeIndexerAction( action.getIdAction( ), plugin );
252 }
253
254 hm = this.indexListRecord( indexWriter, hm, plugin );
255
256
257 for ( IndexerAction action : DirectorySearchService.getInstance( ).getAllIndexerActionByTask( IndexerAction.TASK_CREATE, plugin ) )
258 {
259 Integer nDirectoryId = recordService.getDirectoryIdByRecordId( Integer.valueOf( action.getIdRecord( ) ), plugin );
260
261 if ( nDirectoryId != null )
262 {
263 sbLogRecord( sbLogs, action.getIdRecord( ), nDirectoryId, IndexerAction.TASK_CREATE );
264
265 this.appendKey( nDirectoryId, action.getIdRecord( ), hm );
266 }
267
268 DirectorySearchService.getInstance( ).removeIndexerAction( action.getIdAction( ), plugin );
269 }
270
271 hm = this.indexListRecord( indexWriter, hm, plugin );
272 }
273 else
274 {
275
276 DirectoryFilter filter = new DirectoryFilter( );
277 filter.setIsIndexed( DirectoryFilter.FILTER_TRUE );
278
279 for ( Directory directory : DirectoryHome.getDirectoryList( filter, plugin ) )
280 {
281 sbLogs.append( "Indexing Directory" );
282 sbLogs.append( "\r\n" );
283 recordFieldFilter.setIdDirectory( directory.getIdDirectory( ) );
284
285 for ( Record record : recordService.getListRecord( recordFieldFilter, plugin ) )
286 {
287 sbLogRecord( sbLogs, record.getIdRecord( ), record.getDirectory( ).getIdDirectory( ), IndexerAction.TASK_CREATE );
288
289 this.appendKey( directory.getIdDirectory( ), record.getIdRecord( ), hm );
290 }
291 }
292
293 hm = this.indexListRecord( indexWriter, hm, plugin );
294 }
295 }
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312 private org.apache.lucene.document.Document getDocument( RecordField recordField, Record record, Directory directory ) throws IOException,
313 InterruptedException
314 {
315
316 org.apache.lucene.document.Document doc = new org.apache.lucene.document.Document( );
317
318 FieldType ft = new FieldType( StringField.TYPE_STORED );
319 ft.setOmitNorms( false );
320
321 HashMap<String, Object> mapSearchItemField;
322 doc.add( new Field( DirectorySearchItem.FIELD_ID_DIRECTORY, Integer.toString( directory.getIdDirectory( ) ), ft ) );
323
324 doc.add( new Field( DirectorySearchItem.FIELD_ID_DIRECTORY_RECORD, Integer.toString( record.getIdRecord( ) ), ft ) );
325
326 doc.add( new Field( DirectorySearchItem.FIELD_ID_DIRECTORY_ENTRY, Integer.toString( recordField.getEntry( ).getIdEntry( ) ), ft ) );
327
328 mapSearchItemField = new HashMap<String, Object>( );
329 recordField.getEntry( ).addSearchCriteria( mapSearchItemField, recordField );
330
331 if ( mapSearchItemField.containsKey( DirectorySearchItem.FIELD_ID_DIRECTORY_FIELD ) )
332 {
333 for ( Integer idField : (List<Integer>) mapSearchItemField.get( DirectorySearchItem.FIELD_ID_DIRECTORY_FIELD ) )
334 {
335 doc.add( new Field( DirectorySearchItem.FIELD_ID_DIRECTORY_FIELD, Integer.toString( idField ), ft ) );
336 }
337 }
338
339 if ( mapSearchItemField.containsKey( DirectorySearchItem.FIELD_DATE ) )
340 {
341 String strDate = DateTools.dateToString( (Date) mapSearchItemField.get( DirectorySearchItem.FIELD_DATE ), DateTools.Resolution.DAY );
342 doc.add( new Field( DirectorySearchItem.FIELD_DATE, strDate, ft ) );
343 }
344
345 if ( mapSearchItemField.containsKey( DirectorySearchItem.FIELD_CONTENTS ) )
346 {
347 doc.add( new Field( DirectorySearchItem.FIELD_CONTENTS, (String) mapSearchItemField.get( DirectorySearchItem.FIELD_CONTENTS ),
348 TextField.TYPE_NOT_STORED ) );
349 }
350
351
352 return doc;
353 }
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368 private org.apache.lucene.document.Document getDocument( Record record, Directory directory ) throws IOException, InterruptedException
369 {
370
371 org.apache.lucene.document.Document doc = new org.apache.lucene.document.Document( );
372
373 FieldType ft = new FieldType( StringField.TYPE_STORED );
374 ft.setOmitNorms( false );
375
376 if ( ( directory != null ) && ( record != null ) )
377 {
378 doc.add( new Field( DirectorySearchItem.FIELD_ID_DIRECTORY, Integer.toString( directory.getIdDirectory( ) ), ft ) );
379
380 doc.add( new Field( DirectorySearchItem.FIELD_ID_DIRECTORY_RECORD, Integer.toString( record.getIdRecord( ) ), ft ) );
381
382 if ( record.getWorkgroup( ) != null )
383 {
384 doc.add( new Field( DirectorySearchItem.FIELD_WORKGROUP_KEY, record.getWorkgroup( ), ft ) );
385 }
386
387 if ( record.getRoleKey( ) != null )
388 {
389 doc.add( new Field( DirectorySearchItem.FIELD_ROLE_KEY, record.getRoleKey( ), ft ) );
390 }
391
392 String strDate = DateTools.dateToString( record.getDateCreation( ), DateTools.Resolution.DAY );
393 doc.add( new Field( DirectorySearchItem.FIELD_DATE_CREATION, strDate, ft ) );
394
395 String strDateModification = DateTools.dateToString( record.getDateModification( ), DateTools.Resolution.DAY );
396 doc.add( new Field( DirectorySearchItem.FIELD_DATE_MODIFICATION, strDateModification, ft ) );
397 }
398
399
400 return doc;
401 }
402
403
404
405
406 @Override
407 public String getName( )
408 {
409 return AppPropertiesService.getProperty( PROPERTY_INDEXER_NAME );
410 }
411
412
413
414
415 @Override
416 public String getVersion( )
417 {
418 return AppPropertiesService.getProperty( PROPERTY_INDEXER_VERSION );
419 }
420
421
422
423
424 @Override
425 public boolean isEnable( )
426 {
427 boolean bReturn = false;
428 String strEnable = AppPropertiesService.getProperty( PROPERTY_INDEXER_ENABLE );
429
430 if ( ( strEnable != null ) && ( strEnable.equalsIgnoreCase( Boolean.TRUE.toString( ) ) || strEnable.equals( ENABLE_VALUE_TRUE ) ) )
431 {
432 bReturn = true;
433 }
434
435 return bReturn;
436 }
437
438
439
440
441
442
443
444
445
446
447
448
449
450 private void sbLogRecord( StringBuffer sbLogs, int nIdRecord, int nIdDirectory, int nAction )
451 {
452 sbLogs.append( "Indexing Directory record:" );
453
454 switch( nAction )
455 {
456 case IndexerAction.TASK_CREATE:
457 sbLogs.append( "Insert " );
458
459 break;
460
461 case IndexerAction.TASK_MODIFY:
462 sbLogs.append( "Modify " );
463
464 break;
465
466 case IndexerAction.TASK_DELETE:
467 sbLogs.append( "Delete " );
468
469 break;
470
471 default:
472 break;
473 }
474
475 sbLogs.append( "record :" );
476 sbLogs.append( "id_record=" );
477 sbLogs.append( nIdRecord );
478
479 if ( nIdDirectory != DirectoryUtils.CONSTANT_ID_NULL )
480 {
481 sbLogs.append( "&" );
482 sbLogs.append( "id_directory=" );
483 sbLogs.append( nIdDirectory );
484 }
485
486 sbLogs.append( "\r\n" );
487 }
488
489
490
491
492
493
494
495 public static void appendListRecordToDelete( List<Integer> lListIdRecord )
496 {
497 _lListIdRecordToDelete.addAll( lListIdRecord );
498 }
499 }