View Javadoc

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 }