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.search;
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.EntryFilter;
40 import fr.paris.lutece.plugins.directory.business.EntryHome;
41 import fr.paris.lutece.plugins.directory.business.IEntry;
42 import fr.paris.lutece.plugins.directory.business.Record;
43 import fr.paris.lutece.plugins.directory.business.RecordField;
44 import fr.paris.lutece.plugins.directory.business.RecordFieldFilter;
45 import fr.paris.lutece.plugins.directory.business.RecordFieldHome;
46 import fr.paris.lutece.plugins.directory.service.DirectoryPlugin;
47 import fr.paris.lutece.plugins.directory.service.record.IRecordService;
48 import fr.paris.lutece.plugins.directory.service.record.RecordService;
49 import fr.paris.lutece.plugins.directory.utils.DirectoryUtils;
50 import fr.paris.lutece.portal.service.content.XPageAppService;
51 import fr.paris.lutece.portal.service.message.SiteMessageException;
52 import fr.paris.lutece.portal.service.plugin.Plugin;
53 import fr.paris.lutece.portal.service.plugin.PluginService;
54 import fr.paris.lutece.portal.service.search.IndexationService;
55 import fr.paris.lutece.portal.service.search.SearchIndexer;
56 import fr.paris.lutece.portal.service.search.SearchItem;
57 import fr.paris.lutece.portal.service.spring.SpringContextService;
58 import fr.paris.lutece.portal.service.util.AppLogService;
59 import fr.paris.lutece.portal.service.util.AppPathService;
60 import fr.paris.lutece.portal.service.util.AppPropertiesService;
61 import fr.paris.lutece.util.url.UrlItem;
62
63 import org.apache.commons.lang.StringUtils;
64
65 import org.apache.lucene.document.DateTools;
66 import org.apache.lucene.document.Document;
67 import org.apache.lucene.document.Field;
68 import org.apache.lucene.document.FieldType;
69 import org.apache.lucene.document.StoredField;
70 import org.apache.lucene.document.StringField;
71 import org.apache.lucene.document.TextField;
72
73 import java.io.IOException;
74
75 import java.util.ArrayList;
76 import java.util.List;
77
78
79
80
81 public class DirectorySearchIndexer implements SearchIndexer
82 {
83 public static final String INDEXER_NAME = "DirectoryIndexer";
84 public static final String SHORT_NAME = "dry";
85 private static final String DIRECTORY = "directory";
86 private static final String INDEXER_DESCRIPTION = "Indexer service for directories";
87 private static final String INDEXER_VERSION = "1.0.0";
88 private static final String PARAMETER_ID_DIRECTORY_RECORD = "id_directory_record";
89 private static final String PARAMETER_VIEW_DIRECTORY_RECORD = "view_directory_record";
90 private static final String PROPERTY_INDEXER_ENABLE = "directory.globalIndexer.enable";
91 private static final String ROLE_NONE = "none";
92
93
94
95
96 @Override
97 public String getName( )
98 {
99 return INDEXER_NAME;
100 }
101
102
103
104
105 @Override
106 public String getDescription( )
107 {
108 return INDEXER_DESCRIPTION;
109 }
110
111
112
113
114 @Override
115 public String getVersion( )
116 {
117 return INDEXER_VERSION;
118 }
119
120
121
122
123 @Override
124 public boolean isEnable( )
125 {
126 String strEnable = AppPropertiesService.getProperty( PROPERTY_INDEXER_ENABLE );
127
128 return ( strEnable.equalsIgnoreCase( "true" ) );
129 }
130
131
132
133
134 @Override
135 public List<String> getListType( )
136 {
137 List<String> listType = new ArrayList<String>( 1 );
138 listType.add( DIRECTORY );
139
140 return listType;
141 }
142
143
144
145
146 @Override
147 public String getSpecificSearchAppUrl( )
148 {
149 UrlItem url = new UrlItem( AppPathService.getPortalUrl( ) );
150 url.addParameter( XPageAppService.PARAM_XPAGE_APP, DIRECTORY );
151
152 return url.getUrl( );
153 }
154
155
156
157
158 @Override
159 public List<Document> getDocuments( String recordId ) throws IOException, InterruptedException, SiteMessageException
160 {
161 Plugin plugin = PluginService.getPlugin( DirectoryPlugin.PLUGIN_NAME );
162
163 int nIdRecord;
164
165 try
166 {
167 nIdRecord = Integer.parseInt( recordId );
168 }
169 catch( NumberFormatException ne )
170 {
171 AppLogService.error( recordId + " not parseable to an int", ne );
172
173 return new ArrayList<Document>( 0 );
174 }
175
176 IRecordService recordService = SpringContextService.getBean( RecordService.BEAN_SERVICE );
177 Record record = recordService.findByPrimaryKey( nIdRecord, plugin );
178 Directory directory = record.getDirectory( );
179
180 if ( !record.isEnabled( ) || !directory.isEnabled( ) || !directory.isIndexed( ) )
181 {
182 return new ArrayList<Document>( 0 );
183 }
184
185 int nIdDirectory = directory.getIdDirectory( );
186
187
188 EntryFilter entryFilter = new EntryFilter( );
189 entryFilter.setIdDirectory( nIdDirectory );
190 entryFilter.setIsIndexed( EntryFilter.FILTER_TRUE );
191
192 List<IEntry> listIndexedEntry = EntryHome.getEntryList( entryFilter, plugin );
193
194 entryFilter = new EntryFilter( );
195 entryFilter.setIdDirectory( nIdDirectory );
196 entryFilter.setIsIndexedAsTitle( EntryFilter.FILTER_TRUE );
197
198 List<IEntry> listIndexedAsTitleEntry = EntryHome.getEntryList( entryFilter, plugin );
199
200 entryFilter = new EntryFilter( );
201 entryFilter.setIdDirectory( nIdDirectory );
202 entryFilter.setIsIndexedAsSummary( EntryFilter.FILTER_TRUE );
203
204 List<IEntry> listIndexedAsSummaryEntry = EntryHome.getEntryList( entryFilter, plugin );
205
206 Document doc = getDocument( record, listIndexedEntry, listIndexedAsTitleEntry, listIndexedAsSummaryEntry, plugin );
207
208 if ( doc != null )
209 {
210 List<Document> listDocument = new ArrayList<Document>( 1 );
211 listDocument.add( doc );
212
213 return listDocument;
214 }
215
216 return new ArrayList<Document>( 0 );
217 }
218
219
220
221
222 @Override
223 public void indexDocuments( ) throws IOException, InterruptedException, SiteMessageException
224 {
225 Plugin plugin = PluginService.getPlugin( DirectoryPlugin.PLUGIN_NAME );
226
227
228 DirectoryFilter dirFilter = new DirectoryFilter( );
229 dirFilter.setIsIndexed( DirectoryFilter.FILTER_TRUE );
230 dirFilter.setIsDisabled( DirectoryFilter.FILTER_TRUE );
231
232 IRecordService recordService = SpringContextService.getBean( RecordService.BEAN_SERVICE );
233
234 for ( Directory directory : DirectoryHome.getDirectoryList( dirFilter, plugin ) )
235 {
236 int nIdDirectory = directory.getIdDirectory( );
237
238
239 RecordFieldFilter recFilter = new RecordFieldFilter( );
240 recFilter.setIdDirectory( nIdDirectory );
241 recFilter.setIsDisabled( RecordFieldFilter.FILTER_TRUE );
242
243 List<Record> listRecord = recordService.getListRecord( recFilter, plugin );
244
245
246 if ( !listRecord.isEmpty( ) )
247 {
248
249 EntryFilter entryFilter = new EntryFilter( );
250 entryFilter.setIdDirectory( nIdDirectory );
251 entryFilter.setIsIndexed( EntryFilter.FILTER_TRUE );
252
253 List<IEntry> listIndexedEntry = EntryHome.getEntryList( entryFilter, plugin );
254
255 entryFilter = new EntryFilter( );
256 entryFilter.setIdDirectory( nIdDirectory );
257 entryFilter.setIsIndexedAsTitle( EntryFilter.FILTER_TRUE );
258
259 List<IEntry> listIndexedAsTitleEntry = EntryHome.getEntryList( entryFilter, plugin );
260
261 entryFilter = new EntryFilter( );
262 entryFilter.setIdDirectory( nIdDirectory );
263 entryFilter.setIsIndexedAsSummary( EntryFilter.FILTER_TRUE );
264
265 List<IEntry> listIndexedAsSummaryEntry = EntryHome.getEntryList( entryFilter, plugin );
266
267 for ( Record record : listRecord )
268 {
269 Document recordDoc = null;
270
271 try
272 {
273 recordDoc = getDocument( record, listIndexedEntry, listIndexedAsTitleEntry, listIndexedAsSummaryEntry, plugin );
274 }
275 catch( Exception e )
276 {
277 String strMessage = "Directory ID : " + directory.getIdDirectory( ) + " - Record ID : " + record.getIdRecord( );
278 IndexationService.error( this, e, strMessage );
279 }
280
281 if ( recordDoc != null )
282 {
283 IndexationService.write( recordDoc );
284 }
285 }
286 }
287 }
288 }
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305 public Document getDocument( Record record, List<IEntry> listContentEntry, List<IEntry> listTitleEntry, List<IEntry> listSummaryEntry, Plugin plugin )
306 {
307 Document doc = new Document( );
308
309 FieldType ft = new FieldType( StringField.TYPE_STORED );
310 ft.setOmitNorms( false );
311
312 FieldType ftNotStored = new FieldType( StringField.TYPE_NOT_STORED );
313 ftNotStored.setOmitNorms( false );
314 ftNotStored.setTokenized( false );
315
316 boolean bFallback = false;
317
318
319
320 if ( listTitleEntry.isEmpty( ) && !listContentEntry.isEmpty( ) )
321 {
322 listTitleEntry.add( listContentEntry.get( 0 ) );
323 bFallback = true;
324 }
325
326 String strTitle = getContentToIndex( record, listTitleEntry, plugin );
327
328
329
330 if ( StringUtils.isBlank( strTitle ) && !bFallback && !listContentEntry.isEmpty( ) )
331 {
332 listTitleEntry.clear( );
333 listTitleEntry.add( listContentEntry.get( 0 ) );
334 strTitle = getContentToIndex( record, listTitleEntry, plugin );
335 }
336
337
338 if ( StringUtils.isBlank( strTitle ) )
339 {
340 return null;
341 }
342
343 doc.add( new Field( SearchItem.FIELD_TITLE, strTitle, ft ) );
344
345 if ( !listContentEntry.isEmpty( ) )
346 {
347 String strContent = getContentToIndex( record, listContentEntry, plugin );
348
349 if ( StringUtils.isNotBlank( strContent ) )
350 {
351 doc.add( new Field( SearchItem.FIELD_CONTENTS, strContent, TextField.TYPE_NOT_STORED ) );
352 }
353 }
354
355 if ( !listSummaryEntry.isEmpty( ) )
356 {
357 String strSummary = getContentToIndex( record, listSummaryEntry, plugin );
358
359 if ( StringUtils.isNotBlank( strSummary ) )
360 {
361 doc.add( new StoredField( SearchItem.FIELD_SUMMARY, strSummary ) );
362 }
363 }
364
365 String strRoleKey = record.getRoleKey( );
366
367 if ( StringUtils.isBlank( strRoleKey ) )
368 {
369 strRoleKey = ROLE_NONE;
370 }
371
372 doc.add( new Field( SearchItem.FIELD_ROLE, strRoleKey, ft ) );
373
374 String strDate = DateTools.dateToString( record.getDateCreation( ), DateTools.Resolution.DAY );
375 doc.add( new Field( SearchItem.FIELD_DATE, strDate, ft ) );
376
377 String strDateModification = DateTools.dateToString( record.getDateModification( ), DateTools.Resolution.DAY );
378 doc.add( new Field( SearchItem.FIELD_DATE, strDateModification, ft ) );
379
380 doc.add( new Field( SearchItem.FIELD_TYPE, DIRECTORY, ft ) );
381
382 UrlItem url = new UrlItem( AppPathService.getPortalUrl( ) );
383 url.addParameter( XPageAppService.PARAM_XPAGE_APP, DIRECTORY );
384 url.addParameter( PARAMETER_ID_DIRECTORY_RECORD, record.getIdRecord( ) );
385 url.addParameter( PARAMETER_VIEW_DIRECTORY_RECORD, "" );
386 doc.add( new Field( SearchItem.FIELD_URL, url.getUrl( ), ft ) );
387
388
389
390
391 String strUID = Integer.toString( record.getIdRecord( ) ) + "_" + SHORT_NAME;
392 doc.add( new Field( SearchItem.FIELD_UID, strUID, ftNotStored ) );
393
394 return doc;
395 }
396
397
398
399
400
401
402
403
404
405
406
407
408 private String getContentToIndex( Record record, List<IEntry> listEntry, Plugin plugin )
409 {
410 List<Integer> listIdEntry = new ArrayList<Integer>( listEntry.size( ) );
411
412 for ( IEntry entry : listEntry )
413 {
414 listIdEntry.add( entry.getIdEntry( ) );
415 }
416
417 StringBuffer sb = new StringBuffer( );
418
419 List<RecordField> listField = RecordFieldHome.getRecordFieldSpecificList( listIdEntry, record.getIdRecord( ), plugin,
420 DirectoryUtils.getMapFieldsOfListEntry( listEntry, plugin ) );
421
422 for ( RecordField field : listField )
423 {
424 sb.append( RecordFieldHome.findByPrimaryKey( field.getIdRecordField( ), plugin ).getValue( ) );
425 sb.append( " " );
426 }
427
428 return sb.toString( );
429 }
430 }