1 package org.apache.maven.index;
2
3 /*
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21
22 import java.io.File;
23 import java.util.Arrays;
24 import java.util.Comparator;
25 import java.util.Set;
26 import java.util.TreeSet;
27
28 import org.apache.maven.index.context.IndexingContext;
29 import org.codehaus.plexus.component.annotations.Component;
30 import org.codehaus.plexus.component.annotations.Requirement;
31 import org.codehaus.plexus.logging.AbstractLogEnabled;
32
33 /**
34 * A default repository scanner for Maven 2 repository.
35 *
36 * @author Jason Van Zyl
37 * @author Tamas Cservenak
38 */
39 @Component( role = Scanner.class )
40 public class DefaultScanner
41 extends AbstractLogEnabled
42 implements Scanner
43 {
44 @Requirement
45 private ArtifactContextProducer artifactContextProducer;
46
47 public ScanningResult scan( ScanningRequest request )
48 {
49 request.getArtifactScanningListener().scanningStarted( request.getIndexingContext() );
50
51 ScanningResult result = new ScanningResult( request );
52
53 scanDirectory( request.getStartingDirectory(), request );
54
55 request.getArtifactScanningListener().scanningFinished( request.getIndexingContext(), result );
56
57 return result;
58 }
59
60 private void scanDirectory( File dir, ScanningRequest request )
61 {
62 if ( dir == null )
63 {
64 return;
65 }
66
67 File[] fileArray = dir.listFiles();
68
69 if ( fileArray != null )
70 {
71 Set<File> files = new TreeSet<File>( new ScannerFileComparator() );
72
73 files.addAll( Arrays.asList( fileArray ) );
74
75 for ( File f : files )
76 {
77 if ( f.getName().startsWith( "." ) )
78 {
79 continue; // skip all hidden files and directories
80 }
81
82 if ( f.isDirectory() )
83 {
84 scanDirectory( f, request );
85 }
86 // else if ( !AbstractIndexCreator.isIndexable( f ) )
87 // {
88 // continue; // skip non-indexable files
89 // }
90 else
91 {
92 processFile( f, request );
93 }
94 }
95 }
96 }
97
98 private void processFile( File file, ScanningRequest request )
99 {
100 IndexingContext context = request.getIndexingContext();
101
102 ArtifactContext ac = artifactContextProducer.getArtifactContext( context, file );
103
104 if ( ac != null )
105 {
106 request.getArtifactScanningListener().artifactDiscovered( ac );
107 }
108 }
109
110 // ==
111
112 /**
113 * A special comparator to overcome some very bad limitations of nexus-indexer during scanning: using this
114 * comparator, we force to "discover" POMs last, before the actual artifact file. The reason for this, is to
115 * guarantee that scanner will provide only "best" informations 1st about same artifact, since the POM->artifact
116 * direction of discovery is not trivial at all (pom read -> packaging -> extension -> artifact file). The artifact
117 * -> POM direction is trivial.
118 */
119 private static class ScannerFileComparator
120 implements Comparator<File>
121 {
122 public int compare( File o1, File o2 )
123 {
124 if ( o1.getName().endsWith( ".pom" ) && !o2.getName().endsWith( ".pom" ) )
125 {
126 // 1st is pom, 2nd is not
127 return 1;
128 }
129 else if ( !o1.getName().endsWith( ".pom" ) && o2.getName().endsWith( ".pom" ) )
130 {
131 // 2nd is pom, 1st is not
132 return -1;
133 }
134 else
135 {
136 // both are "same" (pom or not pom)
137 // Use reverse order so that timestamped snapshots
138 // use latest - not first
139 return o2.getName().compareTo( o1.getName() );
140
141 }
142 }
143 }
144 }