blob: a6fa49a3b0af6f1d69e8ba26435298e1e7a6aa00 [file] [log] [blame]
/*
* 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.
*/
package org.apache.maven.index;
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<>(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());
}
}
}
}