blob: 8d76499251aba0650115cf6bc366c2bf804458d6 [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.openejb.maven.jarstxt;
import edu.emory.mathcs.backport.java.util.Collections;
import org.apache.commons.lang3.text.StrLookup;
import org.apache.commons.lang3.text.StrSubstitutor;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.artifact.resolver.ArtifactResolver;
import org.apache.maven.artifact.versioning.VersionRange;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import org.apache.openejb.loader.Files;
import org.apache.openejb.loader.ProvisioningUtil;
import org.codehaus.plexus.util.FileUtils;
import java.io.File;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
@Mojo(name = "generate", threadSafe = true,
requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, defaultPhase = LifecyclePhase.COMPILE)
public class JarsTxtMojo extends AbstractMojo {
public static final String JAR = "jar";
@Component
protected MavenProject project;
@Parameter(property = "outputFile", defaultValue = "${project.build.directory}/${project.build.finalName}/WEB-INF/jars.txt" )
protected File outputFile;
@Parameter(property = "hash")
protected String hashAlgo;
@Parameter(property = "useTimeStamp", defaultValue = "false")
protected boolean useTimeStamp;
@Component
protected ArtifactFactory factory;
@Component
protected ArtifactResolver resolver;
@Parameter(defaultValue = "${localRepository}", readonly = true)
protected ArtifactRepository local;
@Parameter(defaultValue = "${project.remoteArtifactRepositories}", readonly = true)
protected List<ArtifactRepository> remoteRepos;
@Parameter
protected List<String> additionals;
@Parameter
protected Map<String, String> placeHolders;
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
if (!outputFile.getParentFile().exists()) {
FileUtils.mkdir(outputFile.getParentFile().getAbsolutePath());
}
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new FileWriter(outputFile));
final TreeSet<String> set = new TreeSet<>();
for (final Artifact a : (Set<Artifact>) project.getArtifacts()) {
if (!acceptScope(a.getScope()) || !acceptType(a.getType())) {
continue;
}
a.setScope(Artifact.SCOPE_PROVIDED);
final StringBuilder line = new StringBuilder("mvn:")
.append(a.getGroupId()).append("/")
.append(a.getArtifactId()).append("/")
.append(version(a));
final boolean isJar = JAR.equals(a.getType());
if (!isJar) {
line.append("/").append(a.getType());
}
if (a.getClassifier() != null) {
if (isJar) {
line.append("/").append(JAR);
}
line.append("/").append(a.getClassifier());
}
if (hashAlgo != null) {
final Artifact artifact = factory.createDependencyArtifact(a.getGroupId(), a.getArtifactId(), VersionRange.createFromVersion(a.getVersion()), a.getType(), a.getClassifier(), a.getScope());
try {
resolver.resolve(artifact, remoteRepos, local);
} catch (final ArtifactResolutionException | ArtifactNotFoundException e) {
throw new MojoExecutionException(e.getMessage(), e);
}
final File file = artifact.getFile();
line.append("|").append(Files.hash((Set<URL>) Collections.singleton(file.toURI().toURL()), hashAlgo))
.append("|").append(hashAlgo);
}
set.add(line.toString());
}
if (additionals != null) {
if (placeHolders == null) {
placeHolders = new HashMap<>();
}
final StrSubstitutor lookup = new StrSubstitutor(StrLookup.mapLookup(placeHolders));
for (final String line : additionals) {
final StringBuilder builder = new StringBuilder(line);
if (hashAlgo != null) {
builder.append("|").append(Files.hash(urls(line, lookup), hashAlgo))
.append("|").append(hashAlgo);
}
set.add(builder.toString());
}
}
// written after to be sorted, more readable
for (final String line : set) {
writer.write(line);
writer.write("\n");
}
writer.flush();
} catch (final IOException e) {
getLog().error(e.getMessage(), e);
} finally {
if (writer != null) {
try {
writer.close();
} catch (final IOException e) {
// no-op
}
}
}
}
private Set<URL> urls(final String line, final StrSubstitutor lookup) {
final Set<URL> urls = new HashSet<>();
for (final String location : ProvisioningUtil.realLocation(lookup.replace(line))) { // should have 1 item
try {
urls.add(new File(location).toURI().toURL());
} catch (final MalformedURLException e) {
throw new IllegalArgumentException(e);
}
}
return urls;
}
private String version(final Artifact a) {
if (!useTimeStamp && a.getBaseVersion().endsWith("SNAPSHOT")) {
return a.getBaseVersion();
}
return a.getVersion();
}
private boolean acceptType(final String type) {
return "jar".equals(type) || "zip".equals(type);
}
private boolean acceptScope(final String scope) {
return Artifact.SCOPE_COMPILE.equals(scope) || Artifact.SCOPE_RUNTIME.equals(scope);
}
}