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