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.helpdesk.modules.solr.search;
35
36 import java.io.ByteArrayInputStream;
37 import java.io.IOException;
38 import java.io.InputStream;
39 import java.io.Reader;
40 import java.io.StringReader;
41 import java.nio.charset.StandardCharsets;
42 import java.util.ArrayList;
43 import java.util.Collection;
44 import java.util.List;
45
46 import org.apache.commons.lang.StringUtils;
47 import org.apache.tika.exception.TikaException;
48 import org.apache.tika.metadata.Metadata;
49 import org.apache.tika.parser.ParseContext;
50 import org.apache.tika.parser.html.HtmlParser;
51 import org.apache.tika.sax.BodyContentHandler;
52 import org.xml.sax.ContentHandler;
53 import org.xml.sax.SAXException;
54
55 import fr.paris.lutece.plugins.helpdesk.business.Faq;
56 import fr.paris.lutece.plugins.helpdesk.business.FaqHome;
57 import fr.paris.lutece.plugins.helpdesk.business.QuestionAnswer;
58 import fr.paris.lutece.plugins.helpdesk.business.Subject;
59 import fr.paris.lutece.plugins.helpdesk.business.SubjectHome;
60 import fr.paris.lutece.plugins.helpdesk.service.HelpdeskPlugin;
61 import fr.paris.lutece.plugins.helpdesk.service.helpdesksearch.HelpdeskSearchItem;
62 import fr.paris.lutece.plugins.helpdesk.utils.HelpdeskIndexerUtils;
63 import fr.paris.lutece.plugins.helpdesk.web.HelpdeskApp;
64 import fr.paris.lutece.plugins.search.solr.business.field.Field;
65 import fr.paris.lutece.plugins.search.solr.indexer.SolrIndexer;
66 import fr.paris.lutece.plugins.search.solr.indexer.SolrIndexerService;
67 import fr.paris.lutece.plugins.search.solr.indexer.SolrItem;
68 import fr.paris.lutece.plugins.search.solr.util.SolrConstants;
69 import fr.paris.lutece.portal.service.content.XPageAppService;
70 import fr.paris.lutece.portal.service.plugin.Plugin;
71 import fr.paris.lutece.portal.service.plugin.PluginService;
72 import fr.paris.lutece.portal.service.util.AppLogService;
73 import fr.paris.lutece.portal.service.util.AppPropertiesService;
74 import fr.paris.lutece.util.url.UrlItem;
75
76
77
78
79
80
81 public class SolrHelpdeskIndexer implements SolrIndexer
82 {
83 private static final String PROPERTY_DESCRIPTION = "helpdesk-solr.indexer.description";
84 private static final String PROPERTY_NAME = "helpdesk-solr.indexer.name";
85 private static final String PROPERTY_VERSION = "helpdesk-solr.indexer.version";
86 private static final String PROPERTY_INDEXER_ENABLE = "helpdesk-solr.indexer.enable";
87 public static final String SHORT_NAME_SUBJECT = "hds";
88 public static final String SHORT_NAME_QUESTION_ANSWER = "hdq";
89 private static final String BLANK = " ";
90 private static final String PROPERTY_PAGE_PATH_LABEL = "helpdesk.pagePathLabel";
91 private static final String PROPERTY_FAQ_ID_LABEL = "helpdesk-solr.indexer.faq_id.label";
92 private static final String PROPERTY_FAQ_ID_DESCRIPTION = "helpdesk-solr.indexer.faq_id.description";
93 private static final String PROPERTY_SUBJECT_LABEL = "helpdesk-solr.indexer.subject.label";
94 private static final String PROPERTY_SUBJECT_DESCRIPTION = "helpdesk-solr.indexer.subject.description";
95
96
97 private static final List<String> LIST_RESSOURCES_NAME = new ArrayList<String>( );
98 private static final String SUBJECT_INDEXATION_ERROR = "An error occured during the indexation of the subject number ";
99
100 public SolrHelpdeskIndexer( )
101 {
102 super( );
103 LIST_RESSOURCES_NAME.add( HelpdeskIndexerUtils.CONSTANT_QUESTION_ANSWER_TYPE_RESOURCE );
104 LIST_RESSOURCES_NAME.add( HelpdeskIndexerUtils.CONSTANT_SUBJECT_TYPE_RESOURCE );
105 }
106
107
108
109
110 public String getDescription( )
111 {
112 return AppPropertiesService.getProperty( PROPERTY_DESCRIPTION );
113 }
114
115
116
117
118 public String getName( )
119 {
120 return AppPropertiesService.getProperty( PROPERTY_NAME );
121 }
122
123
124
125
126 public String getVersion( )
127 {
128 return AppPropertiesService.getProperty( PROPERTY_VERSION );
129 }
130
131
132
133
134 public List<String> indexDocuments( )
135 {
136 Plugin plugin = PluginService.getPlugin( HelpdeskPlugin.PLUGIN_NAME );
137 List<String> lstErrors = new ArrayList<String>( );
138
139
140 for ( Faq faq : FaqHome.findAll( plugin ) )
141 {
142 for ( Subject subject : (Collection<Subject>) SubjectHome.getInstance( ).findByIdFaq( faq.getId( ), plugin ) )
143 {
144 try
145 {
146 indexSubject( faq, subject );
147 }
148 catch ( IOException e )
149 {
150 lstErrors.add( SolrIndexerService.buildErrorMessage( e ) );
151 AppLogService.error( SUBJECT_INDEXATION_ERROR + subject.getId( ), e );
152 }
153 }
154 }
155
156 return lstErrors;
157 }
158
159
160
161
162
163
164 public List<SolrItem> getDocuments( String strDocument )
165 {
166 List<SolrItem> listDocs = new ArrayList<SolrItem>( );
167 String strPortalUrl = SolrIndexerService.getBaseUrl( );
168 Plugin plugin = PluginService.getPlugin( HelpdeskPlugin.PLUGIN_NAME );
169
170 Subject subject = (Subject) SubjectHome.getInstance( ).findByPrimaryKey( Integer.parseInt( strDocument ),
171 plugin );
172
173 if ( subject != null )
174 {
175 UrlItem urlSubject = new UrlItem( strPortalUrl );
176 urlSubject.addParameter( XPageAppService.PARAM_XPAGE_APP,
177 AppPropertiesService.getProperty( PROPERTY_PAGE_PATH_LABEL ) );
178
179
180 int nIdParent = subject.getIdParent( );
181 Subject parentSubject = subject;
182
183 while ( nIdParent != SubjectHome.FIRST_ORDER )
184 {
185 parentSubject = (Subject) SubjectHome.getInstance( ).findByPrimaryKey( nIdParent, plugin );
186 nIdParent = parentSubject.getIdParent( );
187 }
188
189 Faq faq = FaqHome.findBySubjectId( parentSubject.getId( ), plugin );
190
191 if ( faq != null )
192 {
193 urlSubject.addParameter( HelpdeskApp.PARAMETER_FAQ_ID, faq.getId( ) );
194 urlSubject.setAnchor( HelpdeskApp.ANCHOR_SUBJECT + subject.getId( ) );
195
196 SolrItem docSubject;
197
198 try
199 {
200 docSubject = getDocument( subject, faq.getRoleKey( ), urlSubject.getUrl( ), plugin );
201
202 listDocs.add( docSubject );
203
204 for ( QuestionAnswer questionAnswer : (List<QuestionAnswer>) subject.getQuestions( ) )
205 {
206 if ( questionAnswer.isEnabled( ) )
207 {
208 UrlItem urlQuestionAnswer = new UrlItem( strPortalUrl );
209 urlQuestionAnswer.addParameter( XPageAppService.PARAM_XPAGE_APP,
210 AppPropertiesService.getProperty( PROPERTY_PAGE_PATH_LABEL ) );
211 urlQuestionAnswer.addParameter( HelpdeskApp.PARAMETER_FAQ_ID, faq.getId( ) );
212 urlQuestionAnswer.setAnchor( HelpdeskApp.ANCHOR_QUESTION_ANSWER +
213 questionAnswer.getIdQuestionAnswer( ) );
214
215 SolrItem docQuestionAnswer = getDocument( faq.getId( ), questionAnswer,
216 urlQuestionAnswer.getUrl( ), faq.getRoleKey( ), plugin );
217 listDocs.add( docQuestionAnswer );
218 }
219 }
220 }
221 catch ( IOException e )
222 {
223 throw new RuntimeException( e );
224 }
225 }
226 }
227
228 return listDocs;
229 }
230
231
232
233
234 public boolean isEnable( )
235 {
236 return "true".equalsIgnoreCase( AppPropertiesService.getProperty( PROPERTY_INDEXER_ENABLE ) );
237 }
238
239
240
241
242 public List<Field> getAdditionalFields( )
243 {
244 List<Field> fields = new ArrayList<Field>( );
245 Field fieldFaqId = new Field( );
246 fieldFaqId.setEnableFacet( false );
247 fieldFaqId.setName( HelpdeskSearchItem.FIELD_FAQ_ID );
248 fieldFaqId.setLabel( AppPropertiesService.getProperty( PROPERTY_FAQ_ID_LABEL ) );
249 fieldFaqId.setDescription( AppPropertiesService.getProperty( PROPERTY_FAQ_ID_DESCRIPTION ) );
250 fields.add( fieldFaqId );
251
252 Field fieldSubjectId = new Field( );
253 fieldSubjectId.setEnableFacet( true );
254 fieldSubjectId.setName( HelpdeskSearchItem.FIELD_SUBJECT );
255 fieldSubjectId.setLabel( AppPropertiesService.getProperty( PROPERTY_SUBJECT_LABEL ) );
256 fieldSubjectId.setDescription( AppPropertiesService.getProperty( PROPERTY_SUBJECT_DESCRIPTION ) );
257 fields.add( fieldSubjectId );
258
259 return fields;
260 }
261
262
263
264
265
266
267
268
269
270 private void indexSubject( Faq faq, Subject subject )
271 throws IOException
272 {
273 Plugin plugin = PluginService.getPlugin( HelpdeskPlugin.PLUGIN_NAME );
274
275 String strWebappName = SolrIndexerService.getBaseUrl( );
276 UrlItem urlSubject = new UrlItem( strWebappName );
277 urlSubject.addParameter( XPageAppService.PARAM_XPAGE_APP,
278 AppPropertiesService.getProperty( PROPERTY_PAGE_PATH_LABEL ) );
279 urlSubject.addParameter( HelpdeskApp.PARAMETER_FAQ_ID, faq.getId( ) );
280 urlSubject.setAnchor( HelpdeskApp.ANCHOR_SUBJECT + subject.getId( ) );
281
282
283 SolrItem itemSubject = getDocument( subject, faq.getRoleKey( ), urlSubject.getUrl( ), plugin );
284 SolrIndexerService.write( itemSubject );
285
286 for ( QuestionAnswer questionAnswer : (List<QuestionAnswer>) subject.getQuestions( ) )
287 {
288 if ( questionAnswer.isEnabled( ) )
289 {
290 UrlItem urlQuestionAnswer = new UrlItem( strWebappName );
291 urlQuestionAnswer.addParameter( XPageAppService.PARAM_XPAGE_APP,
292 AppPropertiesService.getProperty( PROPERTY_PAGE_PATH_LABEL ) );
293 urlQuestionAnswer.addParameter( HelpdeskApp.PARAMETER_FAQ_ID, faq.getId( ) );
294 urlQuestionAnswer.setAnchor( HelpdeskApp.ANCHOR_QUESTION_ANSWER +
295 questionAnswer.getIdQuestionAnswer( ) );
296
297
298 SolrItem itemQuestionAnswer = getDocument( faq.getId( ), questionAnswer, urlQuestionAnswer.getUrl( ),
299 faq.getRoleKey( ), plugin );
300 SolrIndexerService.write( itemQuestionAnswer );
301 }
302 }
303
304 Collection<Subject> children = subject.getChilds( plugin );
305
306 for ( Subject childSubject : children )
307 {
308 indexSubject( faq, childSubject );
309 }
310 }
311
312
313
314
315
316
317
318
319
320
321
322
323 private SolrItem getDocument( int nIdFaq, QuestionAnswer questionAnswer, String strUrl, String strRoleKey,
324 Plugin plugin ) throws IOException
325 {
326
327 SolrItem item = new SolrItem( );
328
329
330 item.addDynamicField( HelpdeskSearchItem.FIELD_FAQ_ID, String.valueOf( nIdFaq ) );
331
332
333 item.setRole( strRoleKey );
334
335
336 item.setUrl( strUrl );
337
338
339 item.addDynamicField( HelpdeskSearchItem.FIELD_SUBJECT, String.valueOf( questionAnswer.getIdSubject( ) ) );
340
341
342 String strIdQuestionAnswer = String.valueOf( questionAnswer.getIdQuestionAnswer( ) );
343 item.setUid( getResourceUid( strIdQuestionAnswer, HelpdeskIndexerUtils.CONSTANT_QUESTION_ANSWER_TYPE_RESOURCE ) );
344
345
346
347 item.setDate( questionAnswer.getCreationDate( ) );
348
349
350 String strContentToIndex = getContentToIndex( questionAnswer, plugin );
351
352 HtmlParser parser = new HtmlParser( );
353 ContentHandler handler = new BodyContentHandler();
354 Metadata metadata = new Metadata();
355 InputStream stream = new ByteArrayInputStream(strContentToIndex.getBytes(StandardCharsets.UTF_8));
356 try {
357 parser.parse(stream, handler, metadata, new ParseContext());
358 } catch (SAXException e) {
359 e.printStackTrace();
360 } catch (TikaException e) {
361 e.printStackTrace();
362 }
363
364 item.setContent( handler.toString( ) );
365
366
367 item.setTitle( questionAnswer.getQuestion( ) );
368
369
370 item.setSite( SolrIndexerService.getWebAppName( ) );
371
372
373 item.setType( HelpdeskPlugin.PLUGIN_NAME );
374
375
376 return item;
377 }
378
379
380
381
382
383
384
385
386
387
388
389 private SolrItem getDocument( Subject subject, String strRoleKey, String strUrl, Plugin plugin )
390 throws IOException
391 {
392
393 SolrItem item = new SolrItem( );
394
395
396 item.setUrl( strUrl );
397
398
399 String strIdSubject = String.valueOf( subject.getId( ) );
400 item.setUid( getResourceUid( strIdSubject, HelpdeskIndexerUtils.CONSTANT_SUBJECT_TYPE_RESOURCE ) );
401
402
403 String strContentToIndex = subject.getText( );
404
405 HtmlParser parser = new HtmlParser( );
406 ContentHandler handler = new BodyContentHandler();
407 Metadata metadata = new Metadata();
408 InputStream stream = new ByteArrayInputStream(strContentToIndex.getBytes(StandardCharsets.UTF_8));
409 try {
410 parser.parse(stream, handler, metadata, new ParseContext());
411 } catch (SAXException e) {
412 e.printStackTrace();
413 } catch (TikaException e) {
414 e.printStackTrace();
415 }
416
417 item.setContent( strContentToIndex.toString( ) );
418
419
420 item.setTitle( subject.getText( ) );
421
422
423 item.setSite( SolrIndexerService.getWebAppName( ) );
424
425
426 item.setType( HelpdeskPlugin.PLUGIN_NAME );
427
428
429 item.setRole( strRoleKey );
430
431
432 return item;
433 }
434
435
436
437
438
439
440
441 private static String getContentToIndex( QuestionAnswer questionAnswer, Plugin plugin )
442 {
443 StringBuffer sbContentToIndex = new StringBuffer( );
444
445 sbContentToIndex.append( questionAnswer.getQuestion( ) );
446 sbContentToIndex.append( BLANK );
447 sbContentToIndex.append( questionAnswer.getAnswer( ) );
448
449 return sbContentToIndex.toString( );
450 }
451
452
453
454
455 public List<String> getResourcesName( )
456 {
457 return LIST_RESSOURCES_NAME;
458 }
459
460
461
462
463 public String getResourceUid( String strResourceId, String strResourceType )
464 {
465 StringBuffer sb = new StringBuffer( );
466
467 if ( HelpdeskIndexerUtils.CONSTANT_QUESTION_ANSWER_TYPE_RESOURCE.equals( strResourceType ) )
468 {
469 sb.append( strResourceId ).append( SolrConstants.CONSTANT_UNDERSCORE ).append( SHORT_NAME_QUESTION_ANSWER );
470 }
471 else if ( HelpdeskIndexerUtils.CONSTANT_SUBJECT_TYPE_RESOURCE.equals( strResourceType ) )
472 {
473 sb.append( strResourceId ).append( SolrConstants.CONSTANT_UNDERSCORE ).append( SHORT_NAME_SUBJECT );
474 }
475
476 return StringUtils.isNotBlank( sb.toString( ) ) ? sb.toString( ) : null;
477 }
478 }