blob: f7aee354f82cfa51234db73a9f2ffabbb7f87f65 [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.hyracks.maven.license;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.hyracks.maven.license.project.LicensedProjects;
import org.apache.hyracks.maven.license.project.Project;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.DefaultArtifact;
import org.apache.maven.artifact.metadata.ArtifactMetadata;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
import org.apache.maven.artifact.repository.Authentication;
import org.apache.maven.artifact.repository.DefaultRepositoryRequest;
import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuildingException;
import org.apache.maven.repository.Proxy;
public class SourcePointerResolver {
private static final String CENTRAL_REPO_ID = "central";
private final GenerateFileMojo mojo;
private SourcePointerResolver(GenerateFileMojo mojo) {
this.mojo = mojo;
}
public static void execute(GenerateFileMojo mojo) throws ProjectBuildingException, IOException {
SourcePointerResolver instance = new SourcePointerResolver(mojo);
instance.collectSourcePointers();
}
/**
* @return an ArtifactRepository pair representing the {@code central} repository, where the left element is how to
* reach the {@code central} repository, with the right element being the {@code central} repository itself.
* Note that these only differ when using a mirror to access {@code central}
*/
private Pair<ArtifactRepository, ArtifactRepository> getCentralRepository() {
for (ArtifactRepository candidate : mojo.getSession().getRequest().getRemoteRepositories()) {
if (CENTRAL_REPO_ID.equals(candidate.getId())) {
return Pair.of(candidate, candidate);
}
for (ArtifactRepository mirrored : candidate.getMirroredRepositories()) {
if (CENTRAL_REPO_ID.equals(mirrored.getId())) {
return Pair.of(candidate, mirrored);
}
}
}
throw new IllegalStateException("Unable to find '" + CENTRAL_REPO_ID + "' remote repository!");
}
private void collectSourcePointers() throws ProjectBuildingException, IOException {
List<Project> cddlProjects = new ArrayList<>();
for (LicensedProjects lp : mojo.getLicenseMap().values()) {
if (lp.getLicense().getDisplayName() != null
&& lp.getLicense().getDisplayName().toLowerCase().contains("cddl")) {
cddlProjects.addAll(lp.getProjects());
}
}
if (cddlProjects.isEmpty()) {
return;
}
try (StubArtifactRepository stubRepo = new StubArtifactRepository()) {
DefaultRepositoryRequest rr = new DefaultRepositoryRequest();
rr.setLocalRepository(stubRepo);
Pair<ArtifactRepository, ArtifactRepository> central = getCentralRepository();
rr.setRemoteRepositories(Collections.singletonList(central.getLeft()));
ArtifactResolutionRequest request = new ArtifactResolutionRequest(rr);
for (Project cddlProject : cddlProjects) {
ensureCDDLSourcesPointer(cddlProject, central.getRight(), request);
}
}
}
private void ensureCDDLSourcesPointer(Project project, ArtifactRepository central,
ArtifactResolutionRequest request) throws ProjectBuildingException, IOException {
if (project.getSourcePointer() != null) {
return;
}
mojo.getLog().debug("finding sources for artifact: " + project);
Artifact sourcesArtifact = new DefaultArtifact(project.getGroupId(), project.getArtifactId(),
project.getVersion(), Artifact.SCOPE_COMPILE, "jar", "sources", null);
MavenProject mavenProject = mojo.resolveDependency(sourcesArtifact);
sourcesArtifact.setArtifactHandler(mavenProject.getArtifact().getArtifactHandler());
final ArtifactRepository localRepo = mojo.getSession().getLocalRepository();
final File marker = new File(localRepo.getBasedir(), localRepo.pathOf(sourcesArtifact) + ".oncentral");
final File antimarker = new File(localRepo.getBasedir(), localRepo.pathOf(sourcesArtifact) + ".nocentral");
boolean onCentral;
if (marker.exists() || antimarker.exists()) {
onCentral = marker.exists();
} else {
request.setArtifact(sourcesArtifact);
ArtifactResolutionResult result = mojo.getArtifactResolver().resolve(request);
mojo.getLog().debug("result: " + result);
onCentral = result.isSuccess();
if (onCentral) {
FileUtils.touch(marker);
} else {
FileUtils.touch(antimarker);
}
}
StringBuilder noticeBuilder = new StringBuilder("You may obtain ");
noticeBuilder.append(project.getName()).append(" in Source Code form code here:\n");
if (onCentral) {
noticeBuilder.append(central.getUrl()).append("/").append(central.pathOf(sourcesArtifact));
} else {
mojo.getLog().warn("Unable to find sources on '" + CENTRAL_REPO_ID + "' for " + project
+ ", falling back to project url: " + project.getUrl());
noticeBuilder.append(project.getUrl() != null ? project.getUrl() : "MISSING SOURCE POINTER");
}
project.setSourcePointer(noticeBuilder.toString());
}
private static class StubArtifactRepository implements ArtifactRepository, AutoCloseable {
private static final Random random = new Random();
private final File tempDir;
private final ArtifactRepositoryLayout layout;
public StubArtifactRepository() {
String tmpDir = System.getProperty("java.io.tmpdir", "/tmp");
this.tempDir = new File(tmpDir, "repo" + random.nextInt());
this.layout = new DefaultRepositoryLayout();
}
@java.lang.Override
public ArtifactRepositoryLayout getLayout() {
return layout;
}
@java.lang.Override
public String pathOf(Artifact artifact) {
return this.layout.pathOf(artifact);
}
@java.lang.Override
public String getBasedir() {
return tempDir.toString();
}
@java.lang.Override
public void close() throws IOException {
FileUtils.deleteDirectory(tempDir);
}
@java.lang.Override
public String pathOfRemoteRepositoryMetadata(ArtifactMetadata artifactMetadata) {
return null;
}
@java.lang.Override
public String pathOfLocalRepositoryMetadata(ArtifactMetadata artifactMetadata,
ArtifactRepository artifactRepository) {
return null;
}
@java.lang.Override
public String getUrl() {
return null;
}
@java.lang.Override
public void setUrl(String s) {
// unused
}
@java.lang.Override
public String getProtocol() {
return null;
}
@java.lang.Override
public String getId() {
return "stub";
}
@java.lang.Override
public void setId(String s) {
// unused
}
@java.lang.Override
public ArtifactRepositoryPolicy getSnapshots() {
return null;
}
@java.lang.Override
public void setSnapshotUpdatePolicy(ArtifactRepositoryPolicy artifactRepositoryPolicy) {
// unused
}
@java.lang.Override
public ArtifactRepositoryPolicy getReleases() {
return null;
}
@java.lang.Override
public void setReleaseUpdatePolicy(ArtifactRepositoryPolicy artifactRepositoryPolicy) {
// unused
}
@java.lang.Override
public void setLayout(ArtifactRepositoryLayout artifactRepositoryLayout) {
// unused
}
@java.lang.Override
public String getKey() {
return null;
}
@java.lang.Override
public boolean isUniqueVersion() {
return false;
}
@java.lang.Override
public boolean isBlacklisted() {
return false;
}
@java.lang.Override
public void setBlacklisted(boolean b) {
// unused
}
@java.lang.Override
public Artifact find(Artifact artifact) {
return null;
}
@java.lang.Override
public List<String> findVersions(Artifact artifact) {
return Collections.emptyList();
}
@java.lang.Override
public boolean isProjectAware() {
return false;
}
@java.lang.Override
public void setAuthentication(Authentication authentication) {
// unused
}
@java.lang.Override
public Authentication getAuthentication() {
return null;
}
@java.lang.Override
public void setProxy(Proxy proxy) {
// unused
}
@java.lang.Override
public Proxy getProxy() {
return null;
}
@java.lang.Override
public List<ArtifactRepository> getMirroredRepositories() {
return Collections.emptyList();
}
@java.lang.Override
public void setMirroredRepositories(List<ArtifactRepository> list) {
// unused
}
@java.lang.Override
public boolean isBlocked() {
return false;
}
@java.lang.Override
public void setBlocked(boolean blocked) {
// unused
}
}
}