package com.itemis.maven.aether; import java.io.File; import java.util.List; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; import org.eclipse.aether.RepositorySystem; import org.eclipse.aether.RepositorySystemSession; import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.repository.RemoteRepository; import org.eclipse.aether.resolution.ArtifactResult; import com.google.common.base.MoreObjects; import com.google.common.base.Objects; import com.google.common.base.Optional; import com.google.common.cache.CacheBuilder; import com.google.common.cache.LoadingCache; import com.itemis.maven.plugins.cdi.logging.Logger; /** * Resolves artifacts from the aether using the repository system. * * @author <a href="mailto:[email protected]">Stanley Hillner</a> * @since 1.0.0 */ @Singleton public class ArtifactResolver { private RepositorySystemSession repoSession; private LoadingCache<ArtifactCoordinates, Optional<ArtifactResult>> cache; @Inject public ArtifactResolver(RepositorySystem repoSystem, RepositorySystemSession repoSession, @Named("projectRepositories") List<RemoteRepository> remoteProjectRepos, Logger log) { this.repoSession = repoSession; this.cache = CacheBuilder.newBuilder() .build(new ArtifactCacheLoader(repoSystem, repoSession, remoteProjectRepos, log)); } /** * Tries to resolve an artifact that is identified by its coordinates. * * @param coordinates the coordinates of the artifact to resolve. * @param remoteOnly {@code true} if the artifact resolving shall be performed remotely only which means that the * artifact will only be delivered if it is present in any of the remote repositories. * @return the result of the artifact resolution containing the file and the id of the repository from which is has * been resolved. */ public Optional<ResolutionResult> resolve(ArtifactCoordinates coordinates, boolean remoteOnly) { ResolutionResult r = null; try { Optional<ArtifactResult> result = this.cache .get(new ArtifactCoordinates(coordinates.getGroupId(), coordinates.getArtifactId(), coordinates.getVersion(), MoreObjects.firstNonNull(coordinates.getType(), "jar"), coordinates.getClassifier())); if (result.isPresent()) { r = getResolutionResult(result.get(), remoteOnly); } } catch (Throwable t) { throw new RuntimeException(t.getMessage(), t); } return Optional.fromNullable(r); } private ResolutionResult getResolutionResult(ArtifactResult artifactResult, boolean remoteOnly) { ResolutionResult result = null; Artifact artifact = artifactResult.getArtifact(); if (artifact != null) { String repositoryId = artifactResult.getRepository().getId(); if (remoteOnly) { if (!Objects.equal(repositoryId, this.repoSession.getLocalRepository().getId())) { result = new ResolutionResult(artifact.getFile(), repositoryId); } } else { result = new ResolutionResult(artifact.getFile(), repositoryId); } } return result; } public static class ResolutionResult { private File file; private String repositoryId; public ResolutionResult(File f, String repositoryId) { this.file = f; this.repositoryId = repositoryId; } public File getFile() { return this.file; } public String getRepositoryId() { return this.repositoryId; } } }