1 package org.apache.maven.index;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.IOException;
23 import java.util.ArrayList;
24 import java.util.HashSet;
25 import java.util.List;
26 import java.util.Set;
27
28 import org.apache.lucene.document.Document;
29 import org.apache.lucene.index.CorruptIndexException;
30 import org.apache.lucene.index.IndexReader;
31 import org.apache.lucene.index.Term;
32 import org.apache.lucene.search.IndexSearcher;
33 import org.apache.lucene.search.TermQuery;
34 import org.apache.lucene.search.TopScoreDocCollector;
35 import org.apache.maven.index.context.IndexingContext;
36 import org.codehaus.plexus.logging.AbstractLogEnabled;
37
38
39
40
41
42
43 public class DefaultScannerListener
44 extends AbstractLogEnabled
45 implements ArtifactScanningListener
46 {
47 private final IndexingContext context;
48
49 private final IndexerEngine indexerEngine;
50
51 private final boolean update;
52
53 private final ArtifactScanningListener listener;
54
55 private final Set<String> uinfos = new HashSet<String>();
56
57 private final Set<String> processedUinfos = new HashSet<String>();
58
59 private final Set<String> allGroups = new HashSet<String>();
60
61 private final Set<String> groups = new HashSet<String>();
62
63 private final List<Exception> exceptions = new ArrayList<Exception>();
64
65 private int count = 0;
66
67 public DefaultScannerListener( IndexingContext context,
68 IndexerEngine indexerEngine, boolean update,
69 ArtifactScanningListener listener )
70 {
71 this.context = context;
72 this.indexerEngine = indexerEngine;
73 this.update = update;
74 this.listener = listener;
75 }
76
77 public void scanningStarted( IndexingContext ctx )
78 {
79 try
80 {
81 if ( update )
82 {
83 initialize( ctx );
84 }
85 }
86 catch ( IOException ex )
87 {
88 exceptions.add( ex );
89 }
90
91 if ( listener != null )
92 {
93 listener.scanningStarted( ctx );
94 }
95 }
96
97 public void artifactDiscovered( ArtifactContext ac )
98 {
99 String uinfo = ac.getArtifactInfo().getUinfo();
100
101
102
103
104
105 if ( processedUinfos.contains( uinfo ) )
106 {
107 return;
108 }
109
110 boolean adding = processedUinfos.add( uinfo );
111
112 if ( uinfos.contains( uinfo ) )
113 {
114
115 uinfos.remove( uinfo );
116 return;
117 }
118
119 try
120 {
121 if ( listener != null )
122 {
123 listener.artifactDiscovered( ac );
124 }
125
126 if ( adding )
127 {
128 indexerEngine.index( context, ac );
129 }
130 else
131 {
132 indexerEngine.update( context, ac );
133 }
134
135 for ( Exception e : ac.getErrors() )
136 {
137 artifactError( ac, e );
138 }
139
140 groups.add( ac.getArtifactInfo().getRootGroup() );
141 allGroups.add( ac.getArtifactInfo().groupId );
142
143 count++;
144 }
145 catch ( IOException ex )
146 {
147 artifactError( ac, ex );
148 }
149 }
150
151 public void scanningFinished( IndexingContext ctx, ScanningResult result )
152 {
153 result.setTotalFiles( count );
154
155 for ( Exception ex : exceptions )
156 {
157 result.addException( ex );
158 }
159
160 try
161 {
162 context.optimize();
163
164 context.setRootGroups( groups );
165
166 context.setAllGroups( allGroups );
167
168 if ( update && !context.isReceivingUpdates() )
169 {
170 removeDeletedArtifacts( context, result, result.getRequest().getStartingPath() );
171 }
172 }
173 catch ( IOException ex )
174 {
175 result.addException( ex );
176 }
177
178 if ( listener != null )
179 {
180 listener.scanningFinished( ctx, result );
181 }
182
183 if ( result.getDeletedFiles() > 0 || result.getTotalFiles() > 0 )
184 {
185 try
186 {
187 context.updateTimestamp( true );
188
189 context.optimize();
190 }
191 catch ( Exception ex )
192 {
193 result.addException( ex );
194 }
195 }
196 }
197
198 public void artifactError( ArtifactContext ac, Exception e )
199 {
200 exceptions.add( e );
201
202 if ( listener != null )
203 {
204 listener.artifactError( ac, e );
205 }
206 }
207
208 private void initialize( IndexingContext ctx )
209 throws IOException, CorruptIndexException
210 {
211 final IndexSearcher indexSearcher = ctx.acquireIndexSearcher();
212 try
213 {
214 final IndexReader r = indexSearcher.getIndexReader();
215
216 for ( int i = 0; i < r.maxDoc(); i++ )
217 {
218 if ( !r.isDeleted( i ) )
219 {
220 Document d = r.document( i );
221
222 String uinfo = d.get( ArtifactInfo.UINFO );
223
224 if ( uinfo != null )
225 {
226
227
228
229
230
231
232 if ( !ctx.isReceivingUpdates() )
233 {
234 uinfos.add( uinfo );
235 }
236
237
238
239 String groupId = uinfo.substring( 0, uinfo.indexOf( '|' ) );
240 int n = groupId.indexOf( '.' );
241 groups.add( n == -1 ? groupId : groupId.substring( 0, n ) );
242 allGroups.add( groupId );
243 }
244 }
245 }
246 }
247 finally
248 {
249 ctx.releaseIndexSearcher( indexSearcher );
250 }
251 }
252
253 private void removeDeletedArtifacts( IndexingContext context, ScanningResult result, String contextPath )
254 throws IOException
255 {
256 int deleted = 0;
257
258 final IndexSearcher indexSearcher = context.acquireIndexSearcher();
259 try
260 {
261 for ( String uinfo : uinfos )
262 {
263 TopScoreDocCollector collector = TopScoreDocCollector.create( 1, false );
264
265 indexSearcher.search( new TermQuery( new Term( ArtifactInfo.UINFO, uinfo ) ), collector );
266
267 if ( collector.getTotalHits() > 0 )
268 {
269 String[] ra = ArtifactInfo.FS_PATTERN.split( uinfo );
270
271 ArtifactInfo ai = new ArtifactInfo();
272
273 ai.repository = context.getRepositoryId();
274
275 ai.groupId = ra[0];
276
277 ai.artifactId = ra[1];
278
279 ai.version = ra[2];
280
281 if ( ra.length > 3 )
282 {
283 ai.classifier = ArtifactInfo.renvl( ra[3] );
284 }
285
286 if ( ra.length > 4 )
287 {
288 ai.packaging = ArtifactInfo.renvl( ra[4] );
289 }
290
291
292 ArtifactContext ac = new ArtifactContext( null, null, null, ai, ai.calculateGav() );
293
294 for ( int i = 0; i < collector.getTotalHits(); i++ )
295 {
296 if ( contextPath == null
297 || context.getGavCalculator().gavToPath( ac.getGav() ).startsWith( contextPath ) )
298 {
299 indexerEngine.remove( context, ac );
300 }
301
302 deleted++;
303 }
304 }
305 }
306 }
307 finally
308 {
309 context.releaseIndexSearcher( indexSearcher );
310 }
311
312 if ( deleted > 0 )
313 {
314 context.commit();
315 }
316
317 result.setDeletedFiles( deleted );
318 }
319
320 }