package aQute.bnd.maven.indexer.plugin;
import static java.util.Arrays.asList;
import static org.apache.maven.plugins.annotations.LifecyclePhase.PROCESS_RESOURCES;
import java.io.File;
import java.net.URI;
import java.nio.file.Path;
import java.util.HashSet;
import java.util.Set;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import aQute.bnd.osgi.repository.ResourcesRepository;
import aQute.bnd.osgi.repository.XMLResourceGenerator;
import aQute.bnd.osgi.resource.ResourceBuilder;
import aQute.lib.io.IO;
/**
* Exports project dependencies to OSGi R5 index format.
*/
@Mojo(name = "local-index", defaultPhase = PROCESS_RESOURCES)
public class LocalIndexerMojo extends AbstractMojo {
private static final Logger logger = LoggerFactory.getLogger(LocalIndexerMojo.class);
@Parameter(property = "bnd.indexer.input.dir", required=true)
private File inputDir;
@Parameter(property = "bnd.indexer.output.file", defaultValue = "${project.build.directory}/index.xml")
private File outputFile;
@Parameter(property = "bnd.indexer.base.file")
private File baseFile;
@Parameter(property = "bnd.indexer.include.gzip", defaultValue = "true")
private boolean includeGzip;
@Parameter(property = "bnd.indexer.skip", defaultValue = "false")
private boolean skip;
private boolean fail;
public void execute() throws MojoExecutionException, MojoFailureException {
if ( skip ) {
logger.debug("skip project as configured");
return;
}
if(baseFile == null) {
baseFile = outputFile.getParentFile();
}
logger.debug("Indexing dependencies in folder: {}", inputDir.getAbsolutePath());
logger.debug("Outputting index to: {}", outputFile.getAbsolutePath());
logger.debug("Producing additional gzip index: {}", includeGzip);
logger.debug("URI paths will be relative to: {}", baseFile);
Set<File> toIndex = new HashSet<>();
toIndex.addAll(asList(inputDir.listFiles()));
BaseFileURLResolver baseFileURLResolver = new BaseFileURLResolver();
ResourcesRepository resourcesRepository = new ResourcesRepository();
XMLResourceGenerator xmlResourceGenerator = new XMLResourceGenerator();
for (File file : toIndex) {
ResourceBuilder resourceBuilder = new ResourceBuilder();
try {
resourceBuilder.addFile(file, baseFileURLResolver.resolver(file));
} catch (Exception e) {
throw new MojoExecutionException(e.getMessage(), e);
}
resourcesRepository.add(resourceBuilder.build());
}
try {
IO.mkdirs(outputFile.getParentFile());
xmlResourceGenerator.repository(resourcesRepository).save(outputFile);
} catch (Exception e) {
throw new MojoExecutionException(e.getMessage(), e);
}
if (fail) {
throw new MojoExecutionException("One or more URI lookups failed");
}
if (includeGzip) {
File gzipOutputFile = new File(outputFile.getPath() + ".gz");
try {
xmlResourceGenerator.save(gzipOutputFile);
} catch (Exception e) {
throw new MojoExecutionException("Unable to create the gzipped output file");
}
}
}
class BaseFileURLResolver {
public URI resolver(File file) throws Exception {
try {
logger.debug("Resolving {} relative to {}", file.getAbsolutePath(), baseFile.getAbsolutePath());
Path relativePath = baseFile.getAbsoluteFile().toPath().relativize(file.getAbsoluteFile().toPath());
logger.debug("Relative Path is: {}", relativePath);
// Note that relativePath.toURI() gives the wrong answer for us!
// We have to do some Windows related mashing here too :(
URI relativeURI = URI.create(relativePath.toString().replace(File.separatorChar, '/'));
logger.debug("Relative URI is: {}", relativeURI);
return relativeURI;
} catch (Exception e) {
logger.error("Exception resolving URI", e);
fail = true;
throw e;
}
}
}
}