package org.orienteer.core.boot.loader.util; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import org.apache.http.util.Args; import org.apache.maven.repository.internal.MavenRepositorySystemUtils; import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.RepositorySystem; import org.eclipse.aether.RepositorySystemSession; import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.artifact.DefaultArtifact; import org.eclipse.aether.collection.CollectRequest; import org.eclipse.aether.collection.DependencyCollectionException; import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory; import org.eclipse.aether.graph.Dependency; import org.eclipse.aether.graph.DependencyNode; import org.eclipse.aether.impl.DefaultServiceLocator; import org.eclipse.aether.repository.LocalRepository; import org.eclipse.aether.repository.RemoteRepository; import org.eclipse.aether.resolution.*; import org.eclipse.aether.spi.connector.RepositoryConnectorFactory; import org.eclipse.aether.spi.connector.transport.TransporterFactory; import org.eclipse.aether.transport.file.FileTransporterFactory; import org.eclipse.aether.transport.http.HttpTransporterFactory; import org.eclipse.aether.util.graph.visitor.PreorderNodeListGenerator; import org.eclipse.aether.version.Version; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Collection; import java.util.List; import java.util.Set; /** * Utility class for work with Eclipse Aether. */ class AetherUtils { private static final Logger LOG = LoggerFactory.getLogger(AetherUtils.class); private static final String JAR_EXTENSION = "jar"; private static final String ARTIFACT_TEMPLATE = "%s:%s:%s:%s"; private final RepositorySystem system; private final RepositorySystemSession session; private final List<RemoteRepository> repositories; AetherUtils(InitUtils initUtils) { this.system = getRepositorySystem(); this.session = getRepositorySystemSession(system, initUtils.getMavenLocalRepository()); this.repositories = initUtils.getRemoteRepositories(); } /** * Resolve dependency * @param dependency {@link Dependency} for resolve its dependencies * @return {@link List<Artifact>} of resolved artifact * @throws IllegalArgumentException if dependency is null */ public List<Artifact> resolveDependency(Dependency dependency) { Args.notNull(dependency, "dependency"); CollectRequest collectRequest = new CollectRequest(); collectRequest.setRoot(dependency); collectRequest.setRepositories(repositories); List<Artifact> result = Lists.newArrayList(); DependencyNode node = null; try { node = system.collectDependencies(session, collectRequest).getRoot(); } catch (DependencyCollectionException e) { if (LOG.isDebugEnabled()) { LOG.warn("Can't collect dependencies for: {}", dependency, e); } } if (node != null) { DependencyRequest dependencyRequest = new DependencyRequest(); dependencyRequest.setRoot(node); try { system.resolveDependencies(session, dependencyRequest); } catch (DependencyResolutionException e) { if (LOG.isDebugEnabled()) { LOG.warn("Can't resolve dependencies for: {}", dependency, e); } } PreorderNodeListGenerator nlg = new PreorderNodeListGenerator(); node.accept(nlg); result = nlg.getArtifacts(false); } return result; } /** * Resolve artifact * @param artifact {@link Artifact} for resolve its dependencies * @return {@link List<ArtifactResult>} of resolved artifact * @throws IllegalArgumentException if artifact is null */ public List<ArtifactResult> resolveArtifact(Artifact artifact) { Args.notNull(artifact, "artifact"); ArtifactDescriptorRequest descriptorRequest = createArtifactDescriptionRequest(artifact); ArtifactDescriptorResult descriptorResult = null; try { descriptorResult = system.readArtifactDescriptor(session, descriptorRequest); } catch (ArtifactDescriptorException e) { if (LOG.isDebugEnabled()) LOG.debug(e.getMessage(), e); } Set<ArtifactRequest> requests = createArtifactRequests(descriptorResult); return resolveArtifactRequests(requests); } public List<String> requestArtifactVersions(Artifact artifact) { List<String> versions = Lists.newArrayList(); VersionRangeRequest rangeRequest = new VersionRangeRequest(); rangeRequest.setArtifact(artifact); rangeRequest.setRepositories(repositories); try { VersionRangeResult versionResult = system.resolveVersionRange(session, rangeRequest); if (!versionResult.getVersions().isEmpty()) { String highest = versionResult.getHighestVersion().toString(); versions.add(highest); for (Version version : versionResult.getVersions()) { if (!highest.equals(version.toString())) versions.add(version.toString()); } } } catch (VersionRangeResolutionException e) { LOG.error("Can't create version request: {}", e); } return versions; } /** * Download artifacts * @param artifacts {@link Set<Artifact>} artifacts for download * @return {@link List<Artifact>} of resolved artifact * @throws IllegalArgumentException if artifacts is null */ public List<Artifact> downloadArtifacts(Set<Artifact> artifacts) { Args.notNull(artifacts, "artifacts"); Set<ArtifactRequest> artifactRequests = createArtifactRequests(artifacts); List<ArtifactResult> artifactResults = resolveArtifactRequests(artifactRequests); List<Artifact> result = Lists.newArrayList(); for (ArtifactResult res : artifactResults) { result.add(res.getArtifact()); } return result; } /** * Download artifacts * @param artifact {@link Artifact} artifact for download * @return {@link Artifact} of downloaded artifact or Optional.absent() if can't download artifact * @throws IllegalArgumentException if artifact is null */ public Artifact downloadArtifact(Artifact artifact) { Args.notNull(artifact, "artifact"); ArtifactRequest artifactRequest = createArtifactRequest(artifact); ArtifactResult result = resolveArtifactRequest(artifactRequest); return result != null ? result.getArtifact() : null; } /** * Download artifact from repository * @param artifact {@link Artifact} for download * @param repository repository for download artifact * @return {@link Artifact} of downloaded artifact or Optional.absent if can't download artifact * @throws IllegalArgumentException if artifact or repository is null. */ public Artifact downloadArtifact(Artifact artifact, String repository) { Args.notNull(artifact, "artifact"); Args.notEmpty(repository, "repository"); ArtifactRequest artifactRequest = createArtifactRequest(artifact, newUserRemoteRepository(repository)); ArtifactResult result = resolveArtifactRequest(artifactRequest); return result != null ? result.getArtifact() : null; } private Set<ArtifactRequest> createArtifactRequests(ArtifactDescriptorResult descriptorResult) { Set<Dependency> dependencies = parseDependencies(descriptorResult.getDependencies()); return createArtifactRequests(getArtifactFromDependencies(dependencies)); } private Set<ArtifactRequest> createArtifactRequests(Set<Artifact> dependencies) { Set<ArtifactRequest> requests = Sets.newHashSet(); for (Artifact dependency : dependencies) { requests.add(createArtifactRequest(dependency)); } return requests; } private ArtifactRequest createArtifactRequest(Artifact artifact) { ArtifactRequest artifactRequest = new ArtifactRequest(); artifactRequest.setArtifact(artifact); artifactRequest.setRepositories(repositories); return artifactRequest; } private ArtifactRequest createArtifactRequest(Artifact artifact, RemoteRepository repository) { ArtifactRequest artifactRequest = new ArtifactRequest(); artifactRequest.setArtifact(artifact); artifactRequest.setRepositories(Lists.newArrayList(repository)); return artifactRequest; } private ArtifactDescriptorRequest createArtifactDescriptionRequest(Artifact artifact) { ArtifactDescriptorRequest descriptorRequest = new ArtifactDescriptorRequest(); descriptorRequest.setArtifact(artifact); descriptorRequest.setRepositories(repositories); return descriptorRequest; } private Set<Dependency> parseDependencies(Collection<Dependency> unchagedDeps) { Set<Dependency> changedDeps = Sets.newHashSet(); for (Dependency dependency : unchagedDeps) { Artifact artifact = dependency.getArtifact(); String extension = artifact.getExtension(); if (!extension.equals(JAR_EXTENSION)) { dependency = getChangedDependency(artifact); changedDeps.add(dependency); } else changedDeps.add(dependency); } return changedDeps; } private ArtifactResult resolveArtifactRequest(ArtifactRequest request) { ArtifactResult result = null; try { result = system.resolveArtifact(session, request); } catch (ArtifactResolutionException e) { LOG.warn("Cannot resolve artifact: " + request.getArtifact()); if (LOG.isDebugEnabled()) LOG.debug(e.getMessage(), e); } return result; } private List<ArtifactResult> resolveArtifactRequests(Set<ArtifactRequest> requests) { List<ArtifactResult> artifactResults = Lists.newArrayList(); for (ArtifactRequest request : requests) { ArtifactResult result = resolveArtifactRequest(request); if (result != null) artifactResults.add(result); } return artifactResults; } private RepositorySystem getRepositorySystem() { DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator(); locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class); locator.addService(TransporterFactory.class, FileTransporterFactory.class); locator.addService(TransporterFactory.class, HttpTransporterFactory.class); locator.setErrorHandler(new DefaultServiceLocator.ErrorHandler() { @Override public void serviceCreationFailed(Class<?> type, Class<?> impl, Throwable exception) { LOG.error("ServiceLocator failed", exception); } }); return locator.getService(RepositorySystem.class); } private RepositorySystemSession getRepositorySystemSession(RepositorySystem system, String localRepositoryPath) { DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession(); LocalRepository localRepo = new LocalRepository(localRepositoryPath); session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo)); return session; } private Dependency getChangedDependency(Artifact artifact) { String groupId = artifact.getGroupId(); String artifactId = artifact.getArtifactId(); String versionId = artifact.getVersion(); Artifact newArtifact = new DefaultArtifact( String.format(ARTIFACT_TEMPLATE, groupId, artifactId, JAR_EXTENSION, versionId)); Dependency dependency = new Dependency(newArtifact, ""); return dependency; } private ArtifactDescriptorResult getArtifactDescription(ArtifactDescriptorRequest request) { ArtifactDescriptorResult descriptorResult = null; try { descriptorResult = system.readArtifactDescriptor(session, request); } catch (ArtifactDescriptorException e) { LOG.warn("Can't get artifact description: {}", request); if (LOG.isDebugEnabled()) LOG.debug(e.getMessage(), e); } return descriptorResult; } private Set<Artifact> getArtifactFromDependencies(Collection<Dependency> dependencies) { Set<Artifact> result = Sets.newHashSet(); for (Dependency dependency : dependencies) { result.add(dependency.getArtifact()); } return result; } private RemoteRepository newUserRemoteRepository(String repository) { return new RemoteRepository.Builder("user-" + repositories.size() + 1, "default", repository).build(); } public void addRepository(String repository) { repositories.add(newUserRemoteRepository(repository)); } }