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.calendar.service.search;
35
36 import fr.paris.lutece.plugins.calendar.business.Agenda;
37 import fr.paris.lutece.plugins.calendar.business.CalendarHome;
38 import fr.paris.lutece.plugins.calendar.business.Event;
39 import fr.paris.lutece.plugins.calendar.business.OccurrenceEvent;
40 import fr.paris.lutece.plugins.calendar.business.SimpleEvent;
41 import fr.paris.lutece.plugins.calendar.business.category.Category;
42 import fr.paris.lutece.plugins.calendar.service.AgendaResource;
43 import fr.paris.lutece.plugins.calendar.service.CalendarPlugin;
44 import fr.paris.lutece.plugins.calendar.service.Utils;
45 import fr.paris.lutece.plugins.calendar.web.Constants;
46 import fr.paris.lutece.portal.service.content.XPageAppService;
47 import fr.paris.lutece.portal.service.message.SiteMessageException;
48 import fr.paris.lutece.portal.service.plugin.Plugin;
49 import fr.paris.lutece.portal.service.plugin.PluginService;
50 import fr.paris.lutece.portal.service.search.IndexationService;
51 import fr.paris.lutece.portal.service.search.SearchIndexer;
52 import fr.paris.lutece.portal.service.search.SearchItem;
53 import fr.paris.lutece.portal.service.util.AppException;
54 import fr.paris.lutece.portal.service.util.AppPathService;
55 import fr.paris.lutece.portal.service.util.AppPropertiesService;
56 import fr.paris.lutece.util.url.UrlItem;
57
58 import java.io.ByteArrayInputStream;
59 import java.io.IOException;
60 import java.util.ArrayList;
61 import java.util.Collection;
62 import java.util.Iterator;
63 import java.util.List;
64
65 import org.apache.lucene.document.Document;
66 import org.apache.lucene.document.Field;
67 import org.apache.lucene.document.FieldType;
68 import org.apache.lucene.document.StringField;
69 import org.apache.lucene.document.TextField;
70 import org.apache.tika.exception.TikaException;
71 import org.apache.tika.metadata.Metadata;
72 import org.apache.tika.parser.ParseContext;
73 import org.apache.tika.parser.html.HtmlParser;
74 import org.apache.tika.sax.BodyContentHandler;
75 import org.xml.sax.ContentHandler;
76 import org.xml.sax.SAXException;
77
78
79
80
81
82 public class CalendarIndexer implements SearchIndexer
83 {
84
85 public static final String PROPERTY_INDEXER_NAME = "calendar.indexer.name";
86 public static final String SHORT_NAME = "cld";
87 private static final String ENABLE_VALUE_TRUE = "1";
88 private static final String PROPERTY_INDEXER_DESCRIPTION = "calendar.indexer.description";
89 private static final String PROPERTY_INDEXER_VERSION = "calendar.indexer.version";
90 private static final String PROPERTY_INDEXER_ENABLE = "calendar.indexer.enable";
91 private static final String PROPERTY_DESCRIPTION_MAX_CHARACTERS = "calendar.description.max.characters";
92 private static final String BLANK = " ";
93 private static final String PROPERTY_DESCRIPTION_ETC = "...";
94 private static final String JSP_SEARCH_CALENDAR = "jsp/site/Portal.jsp?page=calendar&action=search";
95
96
97
98
99
100
101
102
103 public void indexDocuments( ) throws IOException, InterruptedException, SiteMessageException
104 {
105 String sRoleKey = "";
106
107 for ( AgendaResource agenda : Utils.getAgendaResourcesWithOccurrences( ) )
108 {
109 sRoleKey = agenda.getRole( );
110
111 String strAgenda = agenda.getId( );
112
113 for ( Event oEvent : agenda.getAgenda( ).getEvents( ) )
114 {
115 indexSubject( oEvent, sRoleKey, strAgenda );
116 }
117 }
118 }
119
120
121
122
123
124
125
126
127
128 public void indexSubject( Event oEvent, String sRoleKey, String strAgenda ) throws IOException,
129 InterruptedException
130 {
131 OccurrenceEvent occurrence = (OccurrenceEvent) oEvent;
132
133 if ( occurrence.getStatus( ).equals(
134 AppPropertiesService.getProperty( Constants.PROPERTY_EVENT_STATUS_CONFIRMED ) ) )
135 {
136 String strPortalUrl = AppPathService.getPortalUrl( );
137
138 UrlItem urlEvent = new UrlItem( strPortalUrl );
139 urlEvent.addParameter( XPageAppService.PARAM_XPAGE_APP, CalendarPlugin.PLUGIN_NAME );
140 urlEvent.addParameter( Constants.PARAMETER_ACTION, Constants.ACTION_SHOW_RESULT );
141 urlEvent.addParameter( Constants.PARAMETER_EVENT_ID, occurrence.getEventId( ) );
142 urlEvent.addParameter( Constants.PARAM_AGENDA, strAgenda );
143
144 org.apache.lucene.document.Document docSubject = null;
145 try
146 {
147 docSubject = getDocument( occurrence, sRoleKey, urlEvent.getUrl( ), strAgenda );
148 }
149 catch ( Exception e )
150 {
151 String strMessage = "Agenda ID : " + strAgenda + " - Occurrence ID : " + occurrence.getId( );
152 IndexationService.error( this, e, strMessage );
153 }
154 if ( docSubject != null )
155 {
156 IndexationService.write( docSubject );
157 }
158 }
159 }
160
161
162
163
164
165
166
167
168
169 public List<Document> getDocuments( String strDocument ) throws IOException, InterruptedException,
170 SiteMessageException
171 {
172 List<org.apache.lucene.document.Document> listDocs = new ArrayList<org.apache.lucene.document.Document>( );
173 String strPortalUrl = AppPathService.getPortalUrl( );
174 Plugin plugin = PluginService.getPlugin( CalendarPlugin.PLUGIN_NAME );
175
176 OccurrenceEvent occurrence = CalendarHome.findOccurrence( Integer.parseInt( strDocument ), plugin );
177 if ( !occurrence.getStatus( ).equals(
178 AppPropertiesService.getProperty( Constants.PROPERTY_EVENT_STATUS_CONFIRMED ) ) )
179 {
180 return null;
181 }
182
183 SimpleEvent event = CalendarHome.findEvent( occurrence.getEventId( ), plugin );
184
185 AgendaResource agendaResource = CalendarHome.findAgendaResource( event.getIdCalendar( ), plugin );
186 Utils.loadAgendaOccurrences( agendaResource, plugin );
187
188 String sRoleKey = agendaResource.getRole( );
189 Agenda agenda = agendaResource.getAgenda( );
190
191 UrlItem urlEvent = new UrlItem( strPortalUrl );
192 urlEvent.addParameter( XPageAppService.PARAM_XPAGE_APP, CalendarPlugin.PLUGIN_NAME );
193 urlEvent.addParameter( Constants.PARAMETER_ACTION, Constants.ACTION_SHOW_RESULT );
194 urlEvent.addParameter( Constants.PARAMETER_EVENT_ID, occurrence.getEventId( ) );
195 urlEvent.addParameter( Constants.PARAM_AGENDA, agenda.getKeyName( ) );
196
197 org.apache.lucene.document.Document docEvent = getDocument( occurrence, sRoleKey, urlEvent.getUrl( ),
198 agenda.getKeyName( ) );
199
200 listDocs.add( docEvent );
201
202 return listDocs;
203 }
204
205
206
207
208
209
210
211
212
213
214
215
216 public static org.apache.lucene.document.Document getDocument( OccurrenceEvent occurrence, String strRoleKey,
217 String strUrl, String strAgenda ) throws IOException, InterruptedException
218 {
219
220 org.apache.lucene.document.Document doc = new org.apache.lucene.document.Document( );
221
222 FieldType ft = new FieldType( StringField.TYPE_STORED );
223 ft.setOmitNorms( false );
224
225 FieldType ftNotStored = new FieldType( StringField.TYPE_NOT_STORED );
226 ft.setOmitNorms( false );
227
228
229 doc.add( new Field( Constants.FIELD_CALENDAR_ID, strAgenda + "_" + Constants.CALENDAR_SHORT_NAME, ftNotStored ) );
230
231
232 Collection<Category> arrayCategories = occurrence.getListCategories( );
233 String strCategories = Constants.EMPTY_STRING;
234
235 if ( arrayCategories != null )
236 {
237 Iterator<Category> i = arrayCategories.iterator( );
238
239 while ( i.hasNext( ) )
240 {
241 strCategories += ( i.next( ).getId( ) + BLANK );
242 }
243 }
244
245 doc.add( new Field( Constants.FIELD_CATEGORY, strCategories, TextField.TYPE_NOT_STORED ) );
246
247 doc.add( new Field( SearchItem.FIELD_ROLE, strRoleKey, ft ) );
248
249
250
251 doc.add( new Field( SearchItem.FIELD_URL, strUrl, ft ) );
252
253
254
255
256 String strIdEvent = String.valueOf( occurrence.getId( ) );
257 doc.add( new Field( SearchItem.FIELD_UID, strIdEvent + "_" + Constants.CALENDAR_SHORT_NAME, ft ) );
258
259
260
261
262 String strDate = Utils.getDate( occurrence.getDate( ) );
263 doc.add( new Field( SearchItem.FIELD_DATE, strDate, ft ) );
264
265 String strContentToIndex = getContentToIndex( occurrence );
266 ContentHandler handler = new BodyContentHandler( );
267 Metadata metadata = new Metadata( );
268
269 try
270 {
271 new HtmlParser( ).parse( new ByteArrayInputStream( strContentToIndex.getBytes( ) ), handler, metadata,
272 new ParseContext( ) );
273 }
274 catch ( SAXException e )
275 {
276 throw new AppException( "Error during page parsing." );
277 }
278 catch ( TikaException e )
279 {
280 throw new AppException( "Error during page parsing." );
281 }
282
283
284
285 StringBuilder sb = new StringBuilder( occurrence.getTitle( ) + " - " + handler.toString( ) );
286
287
288
289 int length = AppPropertiesService.getPropertyInt( PROPERTY_DESCRIPTION_MAX_CHARACTERS, 200 );
290 String strDescription = Utils.parseHtmlToPlainTextString( occurrence.getDescription( ) );
291
292 if ( strDescription.length( ) > length )
293 {
294 strDescription = strDescription.substring( 0, length ) + PROPERTY_DESCRIPTION_ETC;
295 }
296
297 doc.add( new Field( SearchItem.FIELD_SUMMARY, strDescription, TextField.TYPE_STORED ) );
298 doc.add( new Field( CalendarSearchItem.FIELD_HTML_SUMMARY, occurrence.getDescription( ), TextField.TYPE_STORED ) );
299
300
301
302 doc.add( new Field( SearchItem.FIELD_CONTENTS, sb.toString( ), TextField.TYPE_NOT_STORED ) );
303
304
305
306 doc.add( new Field( SearchItem.FIELD_TITLE, occurrence.getTitle( ), TextField.TYPE_STORED ) );
307
308 doc.add( new Field( SearchItem.FIELD_TYPE, CalendarPlugin.PLUGIN_NAME, ft ) );
309
310
311 return doc;
312 }
313
314
315
316
317
318
319 private static String getContentToIndex( Event event )
320 {
321 StringBuffer sbContentToIndex = new StringBuffer( );
322
323 sbContentToIndex.append( event.getDescription( ) );
324 sbContentToIndex.append( BLANK );
325 sbContentToIndex.append( event.getLocationAddress( ) );
326 sbContentToIndex.append( BLANK );
327 sbContentToIndex.append( event.getLocationTown( ) );
328 sbContentToIndex.append( BLANK );
329 sbContentToIndex.append( event.getLocationZip( ) );
330
331 return sbContentToIndex.toString( );
332 }
333
334
335
336
337
338 public String getName( )
339 {
340 return AppPropertiesService.getProperty( PROPERTY_INDEXER_NAME );
341 }
342
343
344
345
346
347 public String getVersion( )
348 {
349 return AppPropertiesService.getProperty( PROPERTY_INDEXER_VERSION );
350 }
351
352
353
354
355
356 public String getDescription( )
357 {
358 return AppPropertiesService.getProperty( PROPERTY_INDEXER_DESCRIPTION );
359 }
360
361
362
363
364
365 public boolean isEnable( )
366 {
367 boolean bReturn = false;
368 String strEnable = AppPropertiesService.getProperty( PROPERTY_INDEXER_ENABLE );
369
370 if ( ( strEnable != null )
371 && ( strEnable.equalsIgnoreCase( Boolean.TRUE.toString( ) ) || strEnable.equals( ENABLE_VALUE_TRUE ) )
372 && PluginService.isPluginEnable( CalendarPlugin.PLUGIN_NAME ) )
373 {
374 bReturn = true;
375 }
376
377 return bReturn;
378 }
379
380
381
382
383 public List<String> getListType( )
384 {
385 List<String> listType = new ArrayList<String>( );
386 listType.add( CalendarPlugin.PLUGIN_NAME );
387
388 return listType;
389 }
390
391
392
393
394 public String getSpecificSearchAppUrl( )
395 {
396 return JSP_SEARCH_CALENDAR;
397 }
398 }