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.modules.multiview.service.search;
35
36 import java.io.IOException;
37 import java.util.ArrayList;
38 import java.util.Iterator;
39 import java.util.List;
40
41 import org.apache.commons.collections.CollectionUtils;
42 import org.apache.commons.lang.StringUtils;
43 import org.apache.commons.lang3.math.NumberUtils;
44 import org.apache.lucene.analysis.Analyzer;
45 import org.apache.lucene.document.Document;
46 import org.apache.lucene.queryparser.classic.ParseException;
47 import org.apache.lucene.queryparser.classic.QueryParser;
48 import org.apache.lucene.search.IndexSearcher;
49 import org.apache.lucene.search.Query;
50 import org.apache.lucene.search.ScoreDoc;
51 import org.apache.lucene.search.TopDocs;
52
53 import fr.paris.lutece.plugins.directory.modules.multiview.business.record.DirectoryRecordItem;
54 import fr.paris.lutece.plugins.directory.modules.multiview.business.record.panel.IRecordPanel;
55 import fr.paris.lutece.plugins.directory.service.directorysearch.DirectorySearchFactory;
56 import fr.paris.lutece.plugins.directory.service.directorysearch.DirectorySearchItem;
57 import fr.paris.lutece.portal.service.search.LuceneSearchEngine;
58 import fr.paris.lutece.portal.service.util.AppException;
59 import fr.paris.lutece.portal.service.util.AppLogService;
60
61
62
63
64 public class DirectoryMultiviewSearchService implements IDirectoryMultiviewSearchService
65 {
66
67 private Analyzer _analyzer;
68 private IndexSearcher _indexSearcher;
69 private DirectorySearchFactory _directorySearchFactory;
70
71
72
73
74 public DirectoryMultiviewSearchService( )
75 {
76 _directorySearchFactory = DirectorySearchFactory.getInstance( );
77 _analyzer = _directorySearchFactory.getAnalyzer( );
78 }
79
80
81
82
83
84
85
86
87
88
89
90 public DirectoryMultiviewSearchService( IndexSearcher indexSearcher, Analyzer analyzer ) throws AppException
91 {
92 if ( indexSearcher == null || analyzer == null )
93 {
94 throw new AppException( "The parameters of the search service musn't be null !" );
95 }
96 else
97 {
98 _indexSearcher = indexSearcher;
99 _analyzer = analyzer;
100 }
101 }
102
103
104
105
106 @Override
107 public void filterBySearchedText( IRecordPanel recordPanel, String strSearchText )
108 {
109 if ( recordPanel != null && StringUtils.isNotBlank( strSearchText ) )
110 {
111 List<DirectoryRecordItem> listDirectoryRecordItem = recordPanel.getDirectoryRecordItemList( );
112
113 if ( !CollectionUtils.isEmpty( listDirectoryRecordItem ) )
114 {
115 try
116 {
117 List<Integer> listIdRecord = searchIdRecordList( strSearchText );
118
119 if ( listIdRecord.isEmpty( ) )
120 {
121 recordPanel.setDirectoryRecordItemList( new ArrayList<>( ) );
122 }
123 else
124 {
125 removeDirectoryItemOutsideSearchResult( recordPanel, listIdRecord );
126 }
127 }
128 catch( IOException | ParseException exception )
129 {
130 AppLogService.error( "An error occurred during the search on the index: " + exception.getMessage( ) );
131 }
132 }
133 }
134 }
135
136
137
138
139
140
141
142
143
144
145
146
147 private List<Integer> searchIdRecordList( String strSearchText ) throws ParseException, IOException
148 {
149 IndexSearcher indexSearcher = _indexSearcher;
150 if ( _indexSearcher == null && _directorySearchFactory != null )
151 {
152 indexSearcher = _directorySearchFactory.getIndexSearcher( );
153 }
154
155 if ( indexSearcher == null )
156 {
157 throw new IOException( "The IndexSearcher is undefined !" );
158 }
159
160 List<Integer> listIdRecordResult = new ArrayList<>( );
161
162 Query querySearch = prepareQuery( strSearchText );
163
164 TopDocs topDocs = indexSearcher.search( querySearch, LuceneSearchEngine.MAX_RESPONSES );
165 if ( topDocs != null && topDocs.scoreDocs != null )
166 {
167 for ( ScoreDoc scoreDoc : topDocs.scoreDocs )
168 {
169 int nIdRecord = retrieveIdRecordFromDoc( indexSearcher, scoreDoc );
170 if ( nIdRecord != NumberUtils.INTEGER_MINUS_ONE )
171 {
172 listIdRecordResult.add( nIdRecord );
173 }
174 }
175 }
176
177 return listIdRecordResult;
178 }
179
180
181
182
183
184
185
186
187
188
189 private Query prepareQuery( String strSearchText ) throws ParseException
190 {
191 QueryParser queryParser = new QueryParser( DirectorySearchItem.FIELD_CONTENTS, _analyzer );
192 Query queryParsed = queryParser.parse( strSearchText );
193
194 return queryParsed;
195 }
196
197
198
199
200
201
202
203
204
205
206
207
208 private int retrieveIdRecordFromDoc( IndexSearcher indexSearcher, ScoreDoc scoreDoc ) throws IOException
209 {
210 int nIdRecord = NumberUtils.INTEGER_MINUS_ONE;
211
212 if ( scoreDoc != null )
213 {
214 int nIdDoc = scoreDoc.doc;
215 Document document = indexSearcher.doc( nIdDoc );
216 if ( document != null )
217 {
218 String strIdRecord = document.get( DirectorySearchItem.FIELD_ID_DIRECTORY_RECORD );
219 nIdRecord = NumberUtils.toInt( strIdRecord, NumberUtils.INTEGER_MINUS_ONE );
220 }
221 }
222
223 return nIdRecord;
224 }
225
226
227
228
229
230
231
232
233
234 private void removeDirectoryItemOutsideSearchResult( IRecordPanel recordPanel, List<Integer> listIdRecord )
235 {
236 List<DirectoryRecordItem> listDirectoryRecordItem = recordPanel.getDirectoryRecordItemList( );
237 Iterator<DirectoryRecordItem> iteratorDirectoryRecordItem = listDirectoryRecordItem.iterator( );
238
239 while ( iteratorDirectoryRecordItem.hasNext( ) )
240 {
241 DirectoryRecordItem directoryRecordItem = iteratorDirectoryRecordItem.next( );
242 int nIdRecord = directoryRecordItem.getIdRecord( );
243
244 if ( !listIdRecord.contains( nIdRecord ) )
245 {
246 iteratorDirectoryRecordItem.remove( );
247 }
248 }
249 }
250 }