package org.apache.maven.index; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; import java.io.File; import java.util.Arrays; import java.util.Comparator; import java.util.Set; import java.util.TreeSet; import org.apache.maven.index.context.IndexingContext; /** * A default repository scanner for Maven 2 repository. * * @author Jason Van Zyl * @author Tamas Cservenak */ @Singleton @Named public class DefaultScanner implements Scanner { private final ArtifactContextProducer artifactContextProducer; @Inject public DefaultScanner( ArtifactContextProducer artifactContextProducer ) { this.artifactContextProducer = artifactContextProducer; } public ScanningResult scan( ScanningRequest request ) { request.getArtifactScanningListener().scanningStarted( request.getIndexingContext() ); ScanningResult result = new ScanningResult( request ); scanDirectory( request.getStartingDirectory(), request ); request.getArtifactScanningListener().scanningFinished( request.getIndexingContext(), result ); return result; } private void scanDirectory( File dir, ScanningRequest request ) { if ( dir == null ) { return; } File[] fileArray = dir.listFiles(); if ( fileArray != null ) { Set<File> files = new TreeSet<File>( new ScannerFileComparator() ); files.addAll( Arrays.asList( fileArray ) ); for ( File f : files ) { if ( f.getName().startsWith( "." ) ) { continue; // skip all hidden files and directories } if ( f.isDirectory() ) { scanDirectory( f, request ); } // else if ( !AbstractIndexCreator.isIndexable( f ) ) // { // continue; // skip non-indexable files // } else { processFile( f, request ); } } } } private void processFile( File file, ScanningRequest request ) { IndexingContext context = request.getIndexingContext(); ArtifactContext ac = artifactContextProducer.getArtifactContext( context, file ); if ( ac != null ) { request.getArtifactScanningListener().artifactDiscovered( ac ); } } // == /** * A special comparator to overcome some very bad limitations of nexus-indexer during scanning: using this * comparator, we force to "discover" POMs last, before the actual artifact file. The reason for this, is to * guarantee that scanner will provide only "best" informations 1st about same artifact, since the POM->artifact * direction of discovery is not trivial at all (pom read -> packaging -> extension -> artifact file). The artifact * -> POM direction is trivial. */ private static class ScannerFileComparator implements Comparator<File> { public int compare( File o1, File o2 ) { if ( o1.getName().endsWith( ".pom" ) && !o2.getName().endsWith( ".pom" ) ) { // 1st is pom, 2nd is not return 1; } else if ( !o1.getName().endsWith( ".pom" ) && o2.getName().endsWith( ".pom" ) ) { // 2nd is pom, 1st is not return -1; } else { // both are "same" (pom or not pom) // Use reverse order so that timestamped snapshots // use latest - not first return o2.getName().compareTo( o1.getName() ); } } } }