org.eclipse.aether.internal.impl.DefaultArtifactResolver Maven / Gradle / Ivy
/*
* 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.eclipse.aether.internal.impl;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import org.eclipse.aether.RepositoryEvent;
import org.eclipse.aether.RepositoryEvent.EventType;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.RequestTrace;
import org.eclipse.aether.SyncContext;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.ArtifactProperties;
import org.eclipse.aether.impl.ArtifactResolver;
import org.eclipse.aether.impl.OfflineController;
import org.eclipse.aether.impl.RemoteRepositoryFilterManager;
import org.eclipse.aether.impl.RemoteRepositoryManager;
import org.eclipse.aether.impl.RepositoryConnectorProvider;
import org.eclipse.aether.impl.RepositoryEventDispatcher;
import org.eclipse.aether.impl.UpdateCheck;
import org.eclipse.aether.impl.UpdateCheckManager;
import org.eclipse.aether.impl.VersionResolver;
import org.eclipse.aether.repository.ArtifactRepository;
import org.eclipse.aether.repository.LocalArtifactRegistration;
import org.eclipse.aether.repository.LocalArtifactRequest;
import org.eclipse.aether.repository.LocalArtifactResult;
import org.eclipse.aether.repository.LocalRepository;
import org.eclipse.aether.repository.LocalRepositoryManager;
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.repository.RepositoryPolicy;
import org.eclipse.aether.repository.WorkspaceReader;
import org.eclipse.aether.resolution.ArtifactRequest;
import org.eclipse.aether.resolution.ArtifactResolutionException;
import org.eclipse.aether.resolution.ArtifactResult;
import org.eclipse.aether.resolution.ResolutionErrorPolicy;
import org.eclipse.aether.resolution.VersionRequest;
import org.eclipse.aether.resolution.VersionResolutionException;
import org.eclipse.aether.resolution.VersionResult;
import org.eclipse.aether.spi.connector.ArtifactDownload;
import org.eclipse.aether.spi.connector.RepositoryConnector;
import org.eclipse.aether.spi.connector.filter.RemoteRepositoryFilter;
import org.eclipse.aether.spi.io.FileProcessor;
import org.eclipse.aether.spi.locator.Service;
import org.eclipse.aether.spi.locator.ServiceLocator;
import org.eclipse.aether.spi.resolution.ArtifactResolverPostProcessor;
import org.eclipse.aether.spi.synccontext.SyncContextFactory;
import org.eclipse.aether.transfer.ArtifactFilteredOutException;
import org.eclipse.aether.transfer.ArtifactNotFoundException;
import org.eclipse.aether.transfer.ArtifactTransferException;
import org.eclipse.aether.transfer.NoRepositoryConnectorException;
import org.eclipse.aether.transfer.RepositoryOfflineException;
import org.eclipse.aether.util.ConfigUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static java.util.Objects.requireNonNull;
/**
*
*/
@Singleton
@Named
public class DefaultArtifactResolver implements ArtifactResolver, Service {
/**
* Configuration to enable "snapshot normalization", downloaded snapshots from remote with timestamped file names
* will have file names converted back to baseVersion. Default: {@code true}.
*/
private static final String CONFIG_PROP_SNAPSHOT_NORMALIZATION = "aether.artifactResolver.snapshotNormalization";
/**
* Configuration to enable "interoperability" with Simple LRM, but this breaks RRF feature, hence this configuration
* is IGNORED when RRF is used, and is warmly recommended to leave it disabled even if no RRF is being used.
* Default: {@code false}.
*/
private static final String CONFIG_PROP_SIMPLE_LRM_INTEROP = "aether.artifactResolver.simpleLrmInterop";
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultArtifactResolver.class);
private FileProcessor fileProcessor;
private RepositoryEventDispatcher repositoryEventDispatcher;
private VersionResolver versionResolver;
private UpdateCheckManager updateCheckManager;
private RepositoryConnectorProvider repositoryConnectorProvider;
private RemoteRepositoryManager remoteRepositoryManager;
private SyncContextFactory syncContextFactory;
private OfflineController offlineController;
private Map artifactResolverPostProcessors;
private RemoteRepositoryFilterManager remoteRepositoryFilterManager;
@Deprecated
public DefaultArtifactResolver() {
// enables default constructor
}
@SuppressWarnings("checkstyle:parameternumber")
@Inject
public DefaultArtifactResolver(
FileProcessor fileProcessor,
RepositoryEventDispatcher repositoryEventDispatcher,
VersionResolver versionResolver,
UpdateCheckManager updateCheckManager,
RepositoryConnectorProvider repositoryConnectorProvider,
RemoteRepositoryManager remoteRepositoryManager,
SyncContextFactory syncContextFactory,
OfflineController offlineController,
Map artifactResolverPostProcessors,
RemoteRepositoryFilterManager remoteRepositoryFilterManager) {
setFileProcessor(fileProcessor);
setRepositoryEventDispatcher(repositoryEventDispatcher);
setVersionResolver(versionResolver);
setUpdateCheckManager(updateCheckManager);
setRepositoryConnectorProvider(repositoryConnectorProvider);
setRemoteRepositoryManager(remoteRepositoryManager);
setSyncContextFactory(syncContextFactory);
setOfflineController(offlineController);
setArtifactResolverPostProcessors(artifactResolverPostProcessors);
setRemoteRepositoryFilterManager(remoteRepositoryFilterManager);
}
public void initService(ServiceLocator locator) {
setFileProcessor(locator.getService(FileProcessor.class));
setRepositoryEventDispatcher(locator.getService(RepositoryEventDispatcher.class));
setVersionResolver(locator.getService(VersionResolver.class));
setUpdateCheckManager(locator.getService(UpdateCheckManager.class));
setRepositoryConnectorProvider(locator.getService(RepositoryConnectorProvider.class));
setRemoteRepositoryManager(locator.getService(RemoteRepositoryManager.class));
setSyncContextFactory(locator.getService(SyncContextFactory.class));
setOfflineController(locator.getService(OfflineController.class));
setArtifactResolverPostProcessors(Collections.emptyMap());
setRemoteRepositoryFilterManager(locator.getService(RemoteRepositoryFilterManager.class));
}
/**
* @deprecated not used any more since MRESOLVER-36 move to slf4j, added back in MRESOLVER-64 for compatibility
*/
@Deprecated
public DefaultArtifactResolver setLoggerFactory(org.eclipse.aether.spi.log.LoggerFactory loggerFactory) {
// this.logger = NullLoggerFactory.getSafeLogger( loggerFactory, getClass() );
return this;
}
public DefaultArtifactResolver setFileProcessor(FileProcessor fileProcessor) {
this.fileProcessor = requireNonNull(fileProcessor, "file processor cannot be null");
return this;
}
public DefaultArtifactResolver setRepositoryEventDispatcher(RepositoryEventDispatcher repositoryEventDispatcher) {
this.repositoryEventDispatcher =
requireNonNull(repositoryEventDispatcher, "repository event dispatcher cannot be null");
return this;
}
public DefaultArtifactResolver setVersionResolver(VersionResolver versionResolver) {
this.versionResolver = requireNonNull(versionResolver, "version resolver cannot be null");
return this;
}
public DefaultArtifactResolver setUpdateCheckManager(UpdateCheckManager updateCheckManager) {
this.updateCheckManager = requireNonNull(updateCheckManager, "update check manager cannot be null");
return this;
}
public DefaultArtifactResolver setRepositoryConnectorProvider(
RepositoryConnectorProvider repositoryConnectorProvider) {
this.repositoryConnectorProvider =
requireNonNull(repositoryConnectorProvider, "repository connector provider cannot be null");
return this;
}
public DefaultArtifactResolver setRemoteRepositoryManager(RemoteRepositoryManager remoteRepositoryManager) {
this.remoteRepositoryManager =
requireNonNull(remoteRepositoryManager, "remote repository provider cannot be null");
return this;
}
public DefaultArtifactResolver setSyncContextFactory(SyncContextFactory syncContextFactory) {
this.syncContextFactory = requireNonNull(syncContextFactory, "sync context factory cannot be null");
return this;
}
public DefaultArtifactResolver setOfflineController(OfflineController offlineController) {
this.offlineController = requireNonNull(offlineController, "offline controller cannot be null");
return this;
}
public DefaultArtifactResolver setArtifactResolverPostProcessors(
Map artifactResolverPostProcessors) {
this.artifactResolverPostProcessors =
requireNonNull(artifactResolverPostProcessors, "artifact resolver post-processors cannot be null");
return this;
}
public DefaultArtifactResolver setRemoteRepositoryFilterManager(
RemoteRepositoryFilterManager remoteRepositoryFilterManager) {
this.remoteRepositoryFilterManager =
requireNonNull(remoteRepositoryFilterManager, "remote repository filter manager cannot be null");
return this;
}
public ArtifactResult resolveArtifact(RepositorySystemSession session, ArtifactRequest request)
throws ArtifactResolutionException {
requireNonNull(session, "session cannot be null");
requireNonNull(request, "request cannot be null");
return resolveArtifacts(session, Collections.singleton(request)).get(0);
}
public List resolveArtifacts(
RepositorySystemSession session, Collection extends ArtifactRequest> requests)
throws ArtifactResolutionException {
requireNonNull(session, "session cannot be null");
requireNonNull(requests, "requests cannot be null");
try (SyncContext shared = syncContextFactory.newInstance(session, true);
SyncContext exclusive = syncContextFactory.newInstance(session, false)) {
Collection artifacts = new ArrayList<>(requests.size());
for (ArtifactRequest request : requests) {
if (request.getArtifact().getProperty(ArtifactProperties.LOCAL_PATH, null) != null) {
continue;
}
artifacts.add(request.getArtifact());
}
return resolve(shared, exclusive, artifacts, session, requests);
}
}
@SuppressWarnings("checkstyle:methodlength")
private List resolve(
SyncContext shared,
SyncContext exclusive,
Collection subjects,
RepositorySystemSession session,
Collection extends ArtifactRequest> requests)
throws ArtifactResolutionException {
SyncContext current = shared;
try {
while (true) {
current.acquire(subjects, null);
boolean failures = false;
final List results = new ArrayList<>(requests.size());
final boolean simpleLrmInterop = ConfigUtils.getBoolean(session, false, CONFIG_PROP_SIMPLE_LRM_INTEROP);
final LocalRepositoryManager lrm = session.getLocalRepositoryManager();
final WorkspaceReader workspace = session.getWorkspaceReader();
final List groups = new ArrayList<>();
// filter != null: means "filtering applied", if null no filtering applied (behave as before)
final RemoteRepositoryFilter filter = remoteRepositoryFilterManager.getRemoteRepositoryFilter(session);
for (ArtifactRequest request : requests) {
RequestTrace trace = RequestTrace.newChild(request.getTrace(), request);
ArtifactResult result = new ArtifactResult(request);
results.add(result);
Artifact artifact = request.getArtifact();
if (current == shared) {
artifactResolving(session, trace, artifact);
}
String localPath = artifact.getProperty(ArtifactProperties.LOCAL_PATH, null);
if (localPath != null) {
// unhosted artifact, just validate file
File file = new File(localPath);
if (!file.isFile()) {
failures = true;
result.addException(new ArtifactNotFoundException(artifact, null));
} else {
artifact = artifact.setFile(file);
result.setArtifact(artifact);
artifactResolved(session, trace, artifact, null, result.getExceptions());
}
continue;
}
List remoteRepositories = request.getRepositories();
List filteredRemoteRepositories = new ArrayList<>(remoteRepositories);
if (filter != null) {
for (RemoteRepository repository : remoteRepositories) {
RemoteRepositoryFilter.Result filterResult = filter.acceptArtifact(repository, artifact);
if (!filterResult.isAccepted()) {
result.addException(new ArtifactFilteredOutException(
artifact, repository, filterResult.reasoning()));
filteredRemoteRepositories.remove(repository);
}
}
}
VersionResult versionResult;
try {
VersionRequest versionRequest =
new VersionRequest(artifact, filteredRemoteRepositories, request.getRequestContext());
versionRequest.setTrace(trace);
versionResult = versionResolver.resolveVersion(session, versionRequest);
} catch (VersionResolutionException e) {
result.addException(e);
continue;
}
artifact = artifact.setVersion(versionResult.getVersion());
if (versionResult.getRepository() != null) {
if (versionResult.getRepository() instanceof RemoteRepository) {
filteredRemoteRepositories =
Collections.singletonList((RemoteRepository) versionResult.getRepository());
} else {
filteredRemoteRepositories = Collections.emptyList();
}
}
if (workspace != null) {
File file = workspace.findArtifact(artifact);
if (file != null) {
artifact = artifact.setFile(file);
result.setArtifact(artifact);
result.setRepository(workspace.getRepository());
artifactResolved(session, trace, artifact, result.getRepository(), null);
continue;
}
}
LocalArtifactResult local = lrm.find(
session,
new LocalArtifactRequest(
artifact, filteredRemoteRepositories, request.getRequestContext()));
result.setLocalArtifactResult(local);
boolean found = (filter != null && local.isAvailable()) || isLocallyInstalled(local, versionResult);
// with filtering it is availability that drives logic
// without filtering it is simply presence of file that drives the logic
// "interop" logic with simple LRM leads to RRF breakage: hence is ignored when filtering in effect
if (found) {
if (local.getRepository() != null) {
result.setRepository(local.getRepository());
} else {
result.setRepository(lrm.getRepository());
}
try {
artifact = artifact.setFile(getFile(session, artifact, local.getFile()));
result.setArtifact(artifact);
artifactResolved(session, trace, artifact, result.getRepository(), null);
} catch (ArtifactTransferException e) {
result.addException(e);
}
if (filter == null && simpleLrmInterop && !local.isAvailable()) {
/*
* NOTE: Interop with simple local repository: An artifact installed by a simple local repo
* manager will not show up in the repository tracking file of the enhanced local repository.
* If however the maven-metadata-local.xml tells us the artifact was installed locally, we
* sync the repository tracking file.
*/
lrm.add(session, new LocalArtifactRegistration(artifact));
}
continue;
}
if (local.getFile() != null) {
LOGGER.info(
"Artifact {} is present in the local repository, but cached from a remote repository ID that is unavailable in current build context, verifying that is downloadable from {}",
artifact,
remoteRepositories);
}
LOGGER.debug("Resolving artifact {} from {}", artifact, remoteRepositories);
AtomicBoolean resolved = new AtomicBoolean(false);
Iterator groupIt = groups.iterator();
for (RemoteRepository repo : filteredRemoteRepositories) {
if (!repo.getPolicy(artifact.isSnapshot()).isEnabled()) {
continue;
}
try {
Utils.checkOffline(session, offlineController, repo);
} catch (RepositoryOfflineException e) {
Exception exception = new ArtifactNotFoundException(
artifact,
repo,
"Cannot access " + repo.getId() + " ("
+ repo.getUrl() + ") in offline mode and the artifact " + artifact
+ " has not been downloaded from it before.",
e);
result.addException(exception);
continue;
}
ResolutionGroup group = null;
while (groupIt.hasNext()) {
ResolutionGroup t = groupIt.next();
if (t.matches(repo)) {
group = t;
break;
}
}
if (group == null) {
group = new ResolutionGroup(repo);
groups.add(group);
groupIt = Collections.emptyIterator();
}
group.items.add(new ResolutionItem(trace, artifact, resolved, result, local, repo));
}
}
if (!groups.isEmpty() && current == shared) {
current.close();
current = exclusive;
continue;
}
for (ResolutionGroup group : groups) {
performDownloads(session, group);
}
for (ArtifactResolverPostProcessor artifactResolverPostProcessor :
artifactResolverPostProcessors.values()) {
artifactResolverPostProcessor.postProcess(session, results);
}
for (ArtifactResult result : results) {
ArtifactRequest request = result.getRequest();
Artifact artifact = result.getArtifact();
if (artifact == null || artifact.getFile() == null) {
failures = true;
if (result.getExceptions().isEmpty()) {
Exception exception = new ArtifactNotFoundException(request.getArtifact(), null);
result.addException(exception);
}
RequestTrace trace = RequestTrace.newChild(request.getTrace(), request);
artifactResolved(session, trace, request.getArtifact(), null, result.getExceptions());
}
}
if (failures) {
throw new ArtifactResolutionException(results);
}
return results;
}
} finally {
current.close();
}
}
private boolean isLocallyInstalled(LocalArtifactResult lar, VersionResult vr) {
if (lar.isAvailable()) {
return true;
}
if (lar.getFile() != null) {
if (vr.getRepository() instanceof LocalRepository) {
// resolution of (snapshot) version found locally installed artifact
return true;
} else if (vr.getRepository() == null
&& lar.getRequest().getRepositories().isEmpty()) {
// resolution of version range found locally installed artifact
return true;
}
}
return false;
}
private File getFile(RepositorySystemSession session, Artifact artifact, File file)
throws ArtifactTransferException {
if (artifact.isSnapshot()
&& !artifact.getVersion().equals(artifact.getBaseVersion())
&& ConfigUtils.getBoolean(session, true, CONFIG_PROP_SNAPSHOT_NORMALIZATION)) {
String name = file.getName().replace(artifact.getVersion(), artifact.getBaseVersion());
File dst = new File(file.getParent(), name);
boolean copy = dst.length() != file.length() || dst.lastModified() != file.lastModified();
if (copy) {
try {
fileProcessor.copy(file, dst);
dst.setLastModified(file.lastModified());
} catch (IOException e) {
throw new ArtifactTransferException(artifact, null, e);
}
}
file = dst;
}
return file;
}
private void performDownloads(RepositorySystemSession session, ResolutionGroup group) {
List downloads = gatherDownloads(session, group);
if (downloads.isEmpty()) {
return;
}
for (ArtifactDownload download : downloads) {
artifactDownloading(session, download.getTrace(), download.getArtifact(), group.repository);
}
try {
try (RepositoryConnector connector =
repositoryConnectorProvider.newRepositoryConnector(session, group.repository)) {
connector.get(downloads, null);
}
} catch (NoRepositoryConnectorException e) {
for (ArtifactDownload download : downloads) {
download.setException(new ArtifactTransferException(download.getArtifact(), group.repository, e));
}
}
evaluateDownloads(session, group);
}
private List gatherDownloads(RepositorySystemSession session, ResolutionGroup group) {
LocalRepositoryManager lrm = session.getLocalRepositoryManager();
List downloads = new ArrayList<>();
for (ResolutionItem item : group.items) {
Artifact artifact = item.artifact;
if (item.resolved.get()) {
// resolved in previous resolution group
continue;
}
ArtifactDownload download = new ArtifactDownload();
download.setArtifact(artifact);
download.setRequestContext(item.request.getRequestContext());
download.setListener(SafeTransferListener.wrap(session));
download.setTrace(item.trace);
if (item.local.getFile() != null) {
download.setFile(item.local.getFile());
download.setExistenceCheck(true);
} else {
String path =
lrm.getPathForRemoteArtifact(artifact, group.repository, item.request.getRequestContext());
download.setFile(new File(lrm.getRepository().getBasedir(), path));
}
boolean snapshot = artifact.isSnapshot();
RepositoryPolicy policy = remoteRepositoryManager.getPolicy(session, group.repository, !snapshot, snapshot);
int errorPolicy = Utils.getPolicy(session, artifact, group.repository);
if ((errorPolicy & ResolutionErrorPolicy.CACHE_ALL) != 0) {
UpdateCheck check = new UpdateCheck<>();
check.setItem(artifact);
check.setFile(download.getFile());
check.setFileValid(false);
check.setRepository(group.repository);
check.setPolicy(policy.getUpdatePolicy());
item.updateCheck = check;
updateCheckManager.checkArtifact(session, check);
if (!check.isRequired()) {
item.result.addException(check.getException());
continue;
}
}
download.setChecksumPolicy(policy.getChecksumPolicy());
download.setRepositories(item.repository.getMirroredRepositories());
downloads.add(download);
item.download = download;
}
return downloads;
}
private void evaluateDownloads(RepositorySystemSession session, ResolutionGroup group) {
LocalRepositoryManager lrm = session.getLocalRepositoryManager();
for (ResolutionItem item : group.items) {
ArtifactDownload download = item.download;
if (download == null) {
continue;
}
Artifact artifact = download.getArtifact();
if (download.getException() == null) {
item.resolved.set(true);
item.result.setRepository(group.repository);
try {
artifact = artifact.setFile(getFile(session, artifact, download.getFile()));
item.result.setArtifact(artifact);
lrm.add(
session,
new LocalArtifactRegistration(artifact, group.repository, download.getSupportedContexts()));
} catch (ArtifactTransferException e) {
download.setException(e);
item.result.addException(e);
}
} else {
item.result.addException(download.getException());
}
/*
* NOTE: Touch after registration with local repo to ensure concurrent resolution is not rejected with
* "already updated" via session data when actual update to local repo is still pending.
*/
if (item.updateCheck != null) {
item.updateCheck.setException(download.getException());
updateCheckManager.touchArtifact(session, item.updateCheck);
}
artifactDownloaded(session, download.getTrace(), artifact, group.repository, download.getException());
if (download.getException() == null) {
artifactResolved(session, download.getTrace(), artifact, group.repository, null);
}
}
}
private void artifactResolving(RepositorySystemSession session, RequestTrace trace, Artifact artifact) {
RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.ARTIFACT_RESOLVING);
event.setTrace(trace);
event.setArtifact(artifact);
repositoryEventDispatcher.dispatch(event.build());
}
private void artifactResolved(
RepositorySystemSession session,
RequestTrace trace,
Artifact artifact,
ArtifactRepository repository,
List exceptions) {
RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.ARTIFACT_RESOLVED);
event.setTrace(trace);
event.setArtifact(artifact);
event.setRepository(repository);
event.setExceptions(exceptions);
if (artifact != null) {
event.setFile(artifact.getFile());
}
repositoryEventDispatcher.dispatch(event.build());
}
private void artifactDownloading(
RepositorySystemSession session, RequestTrace trace, Artifact artifact, RemoteRepository repository) {
RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.ARTIFACT_DOWNLOADING);
event.setTrace(trace);
event.setArtifact(artifact);
event.setRepository(repository);
repositoryEventDispatcher.dispatch(event.build());
}
private void artifactDownloaded(
RepositorySystemSession session,
RequestTrace trace,
Artifact artifact,
RemoteRepository repository,
Exception exception) {
RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.ARTIFACT_DOWNLOADED);
event.setTrace(trace);
event.setArtifact(artifact);
event.setRepository(repository);
event.setException(exception);
if (artifact != null) {
event.setFile(artifact.getFile());
}
repositoryEventDispatcher.dispatch(event.build());
}
static class ResolutionGroup {
final RemoteRepository repository;
final List items = new ArrayList<>();
ResolutionGroup(RemoteRepository repository) {
this.repository = repository;
}
boolean matches(RemoteRepository repo) {
return repository.getUrl().equals(repo.getUrl())
&& repository.getContentType().equals(repo.getContentType())
&& repository.isRepositoryManager() == repo.isRepositoryManager();
}
}
static class ResolutionItem {
final RequestTrace trace;
final ArtifactRequest request;
final ArtifactResult result;
final LocalArtifactResult local;
final RemoteRepository repository;
final Artifact artifact;
final AtomicBoolean resolved;
ArtifactDownload download;
UpdateCheck updateCheck;
ResolutionItem(
RequestTrace trace,
Artifact artifact,
AtomicBoolean resolved,
ArtifactResult result,
LocalArtifactResult local,
RemoteRepository repository) {
this.trace = trace;
this.artifact = artifact;
this.resolved = resolved;
this.result = result;
this.request = result.getRequest();
this.local = local;
this.repository = repository;
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy