blob: 5b15030bb6a655bc55132348c8e0c290b1b65ba2 [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.netbeans.modules.maven.indexer;
import com.google.inject.Inject;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.maven.index.ArtifactContext;
import org.apache.maven.index.ArtifactContextProducer;
import org.apache.maven.index.Scanner;
import org.apache.maven.index.ScanningRequest;
import org.apache.maven.index.ScanningResult;
import org.apache.maven.index.context.IndexingContext;
/**
* Alternative to Maven's DefaultScanner which ignores files NetBeans will not
* be interested in indexing; and publishes scanning requests incrementally,
* per-directory, rather than first collecting a tree's worth of artifacts.
*
* @author Tim Boudreau
*/
public class FastScanner
implements Scanner {
private final ArtifactContextProducer artifactContextProducer;
private static final Logger LOG = Logger.getLogger(FastScanner.class.getName());
@Inject
public FastScanner(ArtifactContextProducer artifactContextProducer) {
this.artifactContextProducer = artifactContextProducer;
}
public ScanningResult scan(ScanningRequest request) {
request.getArtifactScanningListener().scanningStarted(request.getIndexingContext());
ScanningResult result = new ScanningResult(request);
try {
scanDirectory(request.getStartingDirectory().toPath(), request);
} catch (IOException ex) {
LOG.log(Level.WARNING, "Scanning failed", ex);
} finally {
request.getArtifactScanningListener().scanningFinished(request.getIndexingContext(), result);
}
return result;
}
private void scanDirectory(Path dir, ScanningRequest request) throws IOException {
if (dir == null) {
return;
}
Files.walkFileTree(dir, new FileVisitor<Path>() {
private final Set<Path> poms = new HashSet<>();
private final Set<Path> artifacts = new HashSet<>();
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
poms.clear();
artifacts.clear();
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
String nm = file.getFileName().toString();
if (nm.endsWith(".pom")) {
poms.add(file);
// txt and sha1 are needed for tests to pass, but not likely useful
// in NetBeans, and will impact performance
} else if (nm.endsWith(".jar") || nm.endsWith(".nbm") || nm.endsWith(".txt") || nm.endsWith(".xml")) {
artifacts.add(file);
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
LOG.log(Level.INFO, "Visit failed: " + file, exc);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
// Ensure JARs are procssed before POMs - see comments on
// DefaultScanner's nested comparator class for why
try {
if (!artifacts.isEmpty()) {
for (Path jar : artifacts) {
processFile(jar.toFile(), request);
}
}
if (!poms.isEmpty()) {
for (Path pom : poms) {
processFile(pom.toFile(), request);
}
}
} catch (Exception e) {
LOG.log(Level.INFO, "Exception indexing " + artifacts + ", " + poms, e);
}
return FileVisitResult.CONTINUE;
}
});
}
private void processFile(File file, ScanningRequest request) {
IndexingContext context = request.getIndexingContext();
ArtifactContext ac = artifactContextProducer.getArtifactContext(context, file);
if (ac != null) {
request.getArtifactScanningListener().artifactDiscovered(ac);
}
}
}