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.ByteArrayInputStream;
23 import java.io.ByteArrayOutputStream;
24 import java.io.File;
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.Date;
28 import java.util.Iterator;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.Set;
32
33 import org.apache.lucene.index.Term;
34 import org.apache.lucene.queryParser.ParseException;
35 import org.apache.lucene.search.FilteredQuery;
36 import org.apache.lucene.search.PrefixQuery;
37 import org.apache.lucene.search.Query;
38 import org.apache.lucene.search.QueryWrapperFilter;
39 import org.apache.lucene.search.TermQuery;
40 import org.apache.lucene.store.Directory;
41 import org.apache.lucene.store.FSDirectory;
42 import org.apache.maven.index.ArtifactInfo;
43 import org.apache.maven.index.ArtifactInfoGroup;
44 import org.apache.maven.index.Field;
45 import org.apache.maven.index.FlatSearchRequest;
46 import org.apache.maven.index.FlatSearchResponse;
47 import org.apache.maven.index.GroupedSearchRequest;
48 import org.apache.maven.index.GroupedSearchResponse;
49 import org.apache.maven.index.IteratorSearchRequest;
50 import org.apache.maven.index.IteratorSearchResponse;
51 import org.apache.maven.index.MAVEN;
52 import org.apache.maven.index.MatchHighlight;
53 import org.apache.maven.index.MatchHighlightMode;
54 import org.apache.maven.index.MatchHighlightRequest;
55 import org.apache.maven.index.NexusIndexer;
56 import org.apache.maven.index.SearchType;
57 import org.apache.maven.index.context.IndexingContext;
58 import org.apache.maven.index.packer.DefaultIndexPacker;
59 import org.apache.maven.index.search.grouping.GAGrouping;
60 import org.apache.maven.index.search.grouping.GGrouping;
61 import org.apache.maven.index.updater.DefaultIndexUpdater;
62
63 public class FullIndexNexusIndexerTest
64 extends DefaultIndexNexusIndexerTest
65 {
66 @Override
67 protected void prepareNexusIndexer( NexusIndexer nexusIndexer )
68 throws Exception
69 {
70 context = nexusIndexer.addIndexingContext( "test-default", "test", repo, indexDir, null, null, FULL_CREATORS );
71
72 assertNull( context.getTimestamp() );
73
74 nexusIndexer.scan( context );
75
76 assertNotNull( context.getTimestamp() );
77 }
78
79 public void testSearchGroupedClasses()
80 throws Exception
81 {
82 {
83 Query q = nexusIndexer.constructQuery( MAVEN.CLASSNAMES, "com/thoughtworks/qdox", SearchType.SCORED );
84 GroupedSearchRequest request = new GroupedSearchRequest( q, new GAGrouping() );
85 GroupedSearchResponse response = nexusIndexer.searchGrouped( request );
86 Map<String, ArtifactInfoGroup> r = response.getResults();
87
88 assertEquals( r.toString(), 2, r.size() );
89
90 assertTrue( r.containsKey( "qdox : qdox" ) );
91 assertTrue( r.containsKey( "org.testng : testng" ) );
92 assertEquals( "qdox : qdox", r.get( "qdox : qdox" ).getGroupKey() );
93 assertEquals( "org.testng : testng", r.get( "org.testng : testng" ).getGroupKey() );
94 }
95
96 {
97 Query q = nexusIndexer.constructQuery( MAVEN.CLASSNAMES, "com.thoughtworks.qdox", SearchType.SCORED );
98 GroupedSearchRequest request = new GroupedSearchRequest( q, new GAGrouping() );
99 GroupedSearchResponse response = nexusIndexer.searchGrouped( request );
100 Map<String, ArtifactInfoGroup> r = response.getResults();
101 assertEquals( r.toString(), 2, r.size() );
102
103 assertTrue( r.containsKey( "qdox : qdox" ) );
104 assertTrue( r.containsKey( "org.testng : testng" ) );
105 assertEquals( "qdox : qdox", r.get( "qdox : qdox" ).getGroupKey() );
106 assertEquals( "org.testng : testng", r.get( "org.testng : testng" ).getGroupKey() );
107 }
108
109 {
110 Query q = nexusIndexer.constructQuery( MAVEN.CLASSNAMES, "thoughtworks", SearchType.SCORED );
111 GroupedSearchRequest request = new GroupedSearchRequest( q, new GAGrouping() );
112 GroupedSearchResponse response = nexusIndexer.searchGrouped( request );
113 Map<String, ArtifactInfoGroup> r = response.getResults();
114 assertEquals( r.toString(), 2, r.size() );
115 assertTrue( r.containsKey( "qdox : qdox" ) );
116 assertTrue( r.containsKey( "org.testng : testng" ) );
117 assertEquals( "qdox : qdox", r.get( "qdox : qdox" ).getGroupKey() );
118 assertEquals( "org.testng : testng", r.get( "org.testng : testng" ).getGroupKey() );
119 }
120
121 {
122
123 Query q = nexusIndexer.constructQuery( MAVEN.CLASSNAMES, "Logger", SearchType.SCORED );
124 GroupedSearchRequest request = new GroupedSearchRequest( q, new GGrouping() );
125 GroupedSearchResponse response = nexusIndexer.searchGrouped( request );
126
127 Map<String, ArtifactInfoGroup> r = response.getResults();
128 assertEquals( r.toString(), 2, r.size() );
129
130 Iterator<ArtifactInfoGroup> it = r.values().iterator();
131
132 ArtifactInfoGroup ig1 = it.next();
133 assertEquals( r.toString(), "org.slf4j", ig1.getGroupKey() );
134
135 ArtifactInfoGroup ig2 = it.next();
136 assertEquals( r.toString(), "org.testng", ig2.getGroupKey() );
137 }
138
139 {
140
141 Query q = nexusIndexer.constructQuery( MAVEN.CLASSNAMES, "logger", SearchType.SCORED );
142 GroupedSearchRequest request = new GroupedSearchRequest( q, new GGrouping() );
143 GroupedSearchResponse response = nexusIndexer.searchGrouped( request );
144 Map<String, ArtifactInfoGroup> r = response.getResults();
145 assertEquals( r.toString(), 2, r.size() );
146
147 Iterator<ArtifactInfoGroup> it = r.values().iterator();
148
149 ArtifactInfoGroup ig1 = it.next();
150 assertEquals( r.toString(), "org.slf4j", ig1.getGroupKey() );
151
152 ArtifactInfoGroup ig2 = it.next();
153 assertEquals( r.toString(), "org.testng", ig2.getGroupKey() );
154 }
155
156 {
157
158
159
160 Query q = nexusIndexer.constructQuery( MAVEN.CLASSNAMES, ".Logger", SearchType.SCORED );
161 GroupedSearchRequest request = new GroupedSearchRequest( q, new GGrouping() );
162 GroupedSearchResponse response = nexusIndexer.searchGrouped( request );
163 Map<String, ArtifactInfoGroup> r = response.getResults();
164 assertEquals( r.toString(), 2, r.size() );
165 Iterator<ArtifactInfoGroup> it = r.values().iterator();
166 ArtifactInfoGroup ig1 = it.next();
167 assertEquals( r.toString(), "org.slf4j", ig1.getGroupKey() );
168 ArtifactInfoGroup ig2 = it.next();
169 assertEquals( r.toString(), "org.testng", ig2.getGroupKey() );
170 }
171
172 {
173
174
175
176 Query q = nexusIndexer.constructQuery( MAVEN.CLASSNAMES, ".Logger ", SearchType.SCORED );
177 GroupedSearchRequest request = new GroupedSearchRequest( q, new GGrouping() );
178 GroupedSearchResponse response = nexusIndexer.searchGrouped( request );
179 Map<String, ArtifactInfoGroup> r = response.getResults();
180 assertEquals( r.toString(), 2, r.size() );
181 Iterator<ArtifactInfoGroup> it = r.values().iterator();
182 ArtifactInfoGroup ig1 = it.next();
183 assertEquals( r.toString(), "org.slf4j", ig1.getGroupKey() );
184 ArtifactInfoGroup ig2 = it.next();
185 assertEquals( r.toString(), "org.testng", ig2.getGroupKey() );
186 }
187
188 {
189
190
191
192 Query q = nexusIndexer.constructQuery( MAVEN.CLASSNAMES, "Logger", SearchType.SCORED );
193 GroupedSearchRequest request = new GroupedSearchRequest( q, new GGrouping() );
194 GroupedSearchResponse response = nexusIndexer.searchGrouped( request );
195 Map<String, ArtifactInfoGroup> r = response.getResults();
196
197
198 assertEquals( r.toString(), 2, r.size() );
199
200 Iterator<ArtifactInfoGroup> it = r.values().iterator();
201
202
203
204
205
206 ArtifactInfoGroup ig2 = it.next();
207 assertEquals( r.toString(), "org.slf4j", ig2.getGroupKey() );
208
209 ArtifactInfoGroup ig3 = it.next();
210 assertEquals( r.toString(), "org.testng", ig3.getGroupKey() );
211 }
212
213 {
214
215 Query q =
216 nexusIndexer.constructQuery( MAVEN.CLASSNAMES, "org/apache/commons/logging/LogConfigurationException",
217 SearchType.SCORED );
218 GroupedSearchRequest request = new GroupedSearchRequest( q, new GAGrouping() );
219 GroupedSearchResponse response = nexusIndexer.searchGrouped( request );
220
221 Map<String, ArtifactInfoGroup> r = response.getResults();
222 assertEquals( r.toString(), 2, r.size() );
223 }
224
225 {
226
227 Query q =
228 nexusIndexer.constructQuery( MAVEN.CLASSNAMES, "org.apache.commons.logging.LogConfigurationException",
229 SearchType.SCORED );
230 GroupedSearchRequest request = new GroupedSearchRequest( q, new GAGrouping() );
231 GroupedSearchResponse response = nexusIndexer.searchGrouped( request );
232
233 Map<String, ArtifactInfoGroup> r = response.getResults();
234 assertEquals( r.toString(), 2, r.size() );
235 }
236
237 {
238
239 Query q =
240 nexusIndexer.constructQuery( MAVEN.CLASSNAMES, "org.apache.commons.logging.LogConfigurationException",
241 SearchType.EXACT );
242 GroupedSearchRequest request = new GroupedSearchRequest( q, new GAGrouping() );
243 GroupedSearchResponse response = nexusIndexer.searchGrouped( request );
244
245 Map<String, ArtifactInfoGroup> r = response.getResults();
246 assertEquals( r.toString(), 2, r.size() );
247 }
248
249 {
250
251 Query q = nexusIndexer.constructQuery( MAVEN.CLASSNAMES, "org.apache.commons.logging", SearchType.SCORED );
252 GroupedSearchRequest request = new GroupedSearchRequest( q, new GAGrouping() );
253 GroupedSearchResponse response = nexusIndexer.searchGrouped( request );
254
255 Map<String, ArtifactInfoGroup> r = response.getResults();
256 assertEquals( r.toString(), 2, r.size() );
257 }
258
259 {
260
261
262 Query q = nexusIndexer.constructQuery( MAVEN.CLASSNAMES, "slf4j.Logg*", SearchType.SCORED );
263 GroupedSearchRequest request = new GroupedSearchRequest( q, new GAGrouping() );
264 GroupedSearchResponse response = nexusIndexer.searchGrouped( request );
265
266 Map<String, ArtifactInfoGroup> r = response.getResults();
267
268 assertEquals( r.toString(), 1, r.size() );
269
270 {
271 ArtifactInfoGroup ig = r.values().iterator().next();
272 ArrayList<ArtifactInfo> list1 = new ArrayList<ArtifactInfo>( ig.getArtifactInfos() );
273 assertEquals( r.toString(), 2, list1.size() );
274
275 ArtifactInfo ai1 = list1.get( 0 );
276 assertEquals( "org.slf4j", ai1.groupId );
277 assertEquals( "slf4j-api", ai1.artifactId );
278 assertEquals( "1.4.2", ai1.version );
279 ArtifactInfo ai2 = list1.get( 1 );
280 assertEquals( "org.slf4j", ai2.groupId );
281 assertEquals( "slf4j-api", ai2.artifactId );
282 assertEquals( "1.4.1", ai2.version );
283 }
284
285
286
287
288
289
290
291
292
293
294
295
296
297 }
298 }
299
300 public void testSearchArchetypes()
301 throws Exception
302 {
303
304
305
306
307
308
309 Query q = new TermQuery( new Term( ArtifactInfo.PACKAGING, "maven-archetype" ) );
310 FlatSearchResponse response = nexusIndexer.searchFlat( new FlatSearchRequest( q ) );
311 Collection<ArtifactInfo> r = response.getResults();
312
313 assertEquals( 4, r.size() );
314
315 Iterator<ArtifactInfo> it = r.iterator();
316 {
317 ArtifactInfo ai = it.next();
318 assertEquals( "org.apache.directory.server", ai.groupId );
319 assertEquals( "apacheds-schema-archetype", ai.artifactId );
320 assertEquals( "1.0.2", ai.version );
321 }
322 {
323 ArtifactInfo ai = it.next();
324 assertEquals( "org.apache.servicemix.tooling", ai.groupId );
325 assertEquals( "servicemix-service-engine", ai.artifactId );
326 assertEquals( "3.1", ai.version );
327 }
328 {
329 ArtifactInfo ai = it.next();
330 assertEquals( "org.terracotta.maven.archetypes", ai.groupId );
331 assertEquals( "pojo-archetype", ai.artifactId );
332 assertEquals( "1.0.3", ai.version );
333 }
334 {
335 ArtifactInfo ai = it.next();
336 assertEquals( "proptest", ai.groupId );
337 assertEquals( "proptest-archetype", ai.artifactId );
338 assertEquals( "1.0", ai.version );
339 }
340 }
341
342 public void testIndexTimestamp()
343 throws Exception
344 {
345 ByteArrayOutputStream os = new ByteArrayOutputStream();
346
347 DefaultIndexPacker.packIndexArchive( context, os );
348
349 Thread.sleep( 1000L );
350
351 File newIndex = new File( getBasedir(), "target/test-new" );
352
353 Directory newIndexDir = FSDirectory.open( newIndex );
354
355 DefaultIndexUpdater.unpackIndexArchive( new ByteArrayInputStream( os.toByteArray() ), newIndexDir, context );
356
357 IndexingContext newContext =
358 nexusIndexer.addIndexingContext( "test-new", "test", null, newIndexDir, null, null, DEFAULT_CREATORS );
359
360 assertEquals( context.getTimestamp().getTime(), newContext.getTimestamp().getTime() );
361
362 assertEquals( context.getTimestamp(), newContext.getTimestamp() );
363
364
365
366 Query query = nexusIndexer.constructQuery( MAVEN.GROUP_ID, "qdox", SearchType.SCORED );
367
368 FlatSearchRequest request = new FlatSearchRequest( query, newContext );
369 FlatSearchResponse response = nexusIndexer.searchFlat( request );
370 Collection<ArtifactInfo> r = response.getResults();
371
372 assertEquals( 2, r.size() );
373
374 List<ArtifactInfo> list = new ArrayList<ArtifactInfo>( r );
375
376 assertEquals( 2, list.size() );
377
378 ArtifactInfo ai = list.get( 0 );
379
380 assertEquals( "1.6.1", ai.version );
381
382 ai = list.get( 1 );
383
384 assertEquals( "1.5", ai.version );
385
386 assertEquals( "test", ai.repository );
387
388 Date timestamp = newContext.getTimestamp();
389
390 newContext.close( false );
391
392 newIndexDir = FSDirectory.open( newIndex );
393
394 DefaultIndexUpdater.unpackIndexArchive( new ByteArrayInputStream( os.toByteArray() ), newIndexDir, context );
395
396 newContext =
397 nexusIndexer.addIndexingContext( "test-new", "test", null, newIndexDir, null, null, DEFAULT_CREATORS );
398
399 assertEquals( timestamp, newContext.getTimestamp() );
400
401 newContext.close( true );
402
403 assertFalse( new File( newIndex, "timestamp" ).exists() );
404 }
405
406 public void testArchetype()
407 throws Exception
408 {
409 String term = "proptest";
410
411 Query bq = new PrefixQuery( new Term( ArtifactInfo.GROUP_ID, term ) );
412 TermQuery tq = new TermQuery( new Term( ArtifactInfo.PACKAGING, "maven-archetype" ) );
413 Query query = new FilteredQuery( tq, new QueryWrapperFilter( bq ) );
414
415 FlatSearchResponse response = nexusIndexer.searchFlat( new FlatSearchRequest( query ) );
416
417 Collection<ArtifactInfo> r = response.getResults();
418
419 assertEquals( r.toString(), 1, r.size() );
420 }
421
422 public void testArchetypePackaging()
423 throws Exception
424 {
425 Query query = new TermQuery( new Term( ArtifactInfo.PACKAGING, "maven-archetype" ) );
426 FlatSearchResponse response = nexusIndexer.searchFlat( new FlatSearchRequest( query ) );
427 assertEquals( response.getResults().toString(), 4, response.getTotalHits() );
428 }
429
430 public void testBrokenJar()
431 throws Exception
432 {
433 Query q = nexusIndexer.constructQuery( MAVEN.ARTIFACT_ID, "brokenjar", SearchType.SCORED );
434
435 FlatSearchRequest searchRequest = new FlatSearchRequest( q );
436
437 FlatSearchResponse response = nexusIndexer.searchFlat( searchRequest );
438
439 Set<ArtifactInfo> r = response.getResults();
440
441 assertEquals( r.toString(), 1, r.size() );
442
443 ArtifactInfo ai = r.iterator().next();
444
445 assertEquals( "brokenjar", ai.groupId );
446 assertEquals( "brokenjar", ai.artifactId );
447 assertEquals( "1.0", ai.version );
448 assertEquals( null, ai.classNames );
449 }
450
451 public void testMissingPom()
452 throws Exception
453 {
454 Query q = nexusIndexer.constructQuery( MAVEN.ARTIFACT_ID, "missingpom", SearchType.SCORED );
455
456 FlatSearchRequest searchRequest = new FlatSearchRequest( q );
457
458 FlatSearchResponse response = nexusIndexer.searchFlat( searchRequest );
459
460 Set<ArtifactInfo> r = response.getResults();
461
462 assertEquals( r.toString(), 1, r.size() );
463
464 ArtifactInfo ai = r.iterator().next();
465
466 assertEquals( "missingpom", ai.groupId );
467 assertEquals( "missingpom", ai.artifactId );
468 assertEquals( "1.0", ai.version );
469
470 assertNull( ai.classNames );
471 }
472
473
474
475 protected IteratorSearchRequest createHighlightedRequest( Field field, String text, SearchType type )
476 throws ParseException
477 {
478 Query q = nexusIndexer.constructQuery( field, text, type );
479
480 IteratorSearchRequest request = new IteratorSearchRequest( q );
481
482 request.getMatchHighlightRequests().add( new MatchHighlightRequest( field, q, MatchHighlightMode.HTML ) );
483
484 return request;
485 }
486
487 public void testClassnameSearchNgWithHighlighting()
488 throws Exception
489 {
490 IteratorSearchRequest request = createHighlightedRequest( MAVEN.CLASSNAMES, "Logger", SearchType.SCORED );
491
492 IteratorSearchResponse response = nexusIndexer.searchIterator( request );
493
494 for ( ArtifactInfo ai : response )
495 {
496
497 String classnames = ai.classNames;
498
499 for ( MatchHighlight mh : ai.getMatchHighlights() )
500 {
501 for ( String highlighted : mh.getHighlightedMatch() )
502 {
503
504 assertTrue( "Class name should be highlighted", highlighted.contains( "<B>Logger" ) );
505 assertFalse( "Class name should not contain \"/\" alone (but okay within HTML, see above!)",
506 highlighted.matches( "\\p{Lower}/\\p{Upper}" ) );
507 assertFalse( "Class name should not begin with \".\" or \"/\"", highlighted.startsWith( "." )
508 || highlighted.startsWith( "/" ) );
509 }
510 }
511 }
512
513 assertEquals( "found in jcl104-over-slf4j and commons-logging", 5, response.getTotalHits() );
514 }
515
516 public void testGAVSearchNgWithHighlighting()
517 throws Exception
518 {
519 IteratorSearchRequest request = createHighlightedRequest( MAVEN.GROUP_ID, "commons", SearchType.SCORED );
520
521 IteratorSearchResponse response = nexusIndexer.searchIterator( request );
522
523 for ( ArtifactInfo ai : response )
524 {
525 for ( MatchHighlight mh : ai.getMatchHighlights() )
526 {
527 assertTrue(
528 "Group ID should be highlighted",
529 mh.getHighlightedMatch().contains( "<B>commons</B>-logging" )
530 || mh.getHighlightedMatch().contains( "<B>commons</B>-cli" ) );
531 }
532 }
533
534 assertEquals( "found in commons-logging and commons-cli", 15, response.getTotalHits() );
535 }
536 }