Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import java.util.stream.Stream;
Expand Down Expand Up @@ -154,23 +155,34 @@ public final class GroupIdRemoteRepositoryFilterSource extends RemoteRepositoryF

private final PathProcessor pathProcessor;

private final ConcurrentHashMap<RemoteRepository, GroupTree> rules;

private final ConcurrentHashMap<RemoteRepository, Path> ruleFiles;

private final ConcurrentHashMap<RemoteRepository, Set<String>> recordedRules;

private final AtomicBoolean onShutdownHandlerRegistered;

@Inject
public GroupIdRemoteRepositoryFilterSource(
RepositorySystemLifecycle repositorySystemLifecycle, PathProcessor pathProcessor) {
this.repositorySystemLifecycle = requireNonNull(repositorySystemLifecycle);
this.pathProcessor = requireNonNull(pathProcessor);
this.rules = new ConcurrentHashMap<>();
this.ruleFiles = new ConcurrentHashMap<>();
this.recordedRules = new ConcurrentHashMap<>();
this.onShutdownHandlerRegistered = new AtomicBoolean(false);
}

@SuppressWarnings("unchecked")
private ConcurrentMap<RemoteRepository, GroupTree> rules(RepositorySystemSession session) {
return (ConcurrentMap<RemoteRepository, GroupTree>)
session.getData().computeIfAbsent(getClass().getName() + ".rules", ConcurrentHashMap::new);
}

@SuppressWarnings("unchecked")
private ConcurrentMap<RemoteRepository, Path> ruleFiles(RepositorySystemSession session) {
return (ConcurrentMap<RemoteRepository, Path>)
session.getData().computeIfAbsent(getClass().getName() + ".ruleFiles", ConcurrentHashMap::new);
}

@SuppressWarnings("unchecked")
private ConcurrentMap<RemoteRepository, Set<String>> recordedRules(RepositorySystemSession session) {
return (ConcurrentMap<RemoteRepository, Set<String>>)
session.getData().computeIfAbsent(getClass().getName() + ".recordedRules", ConcurrentHashMap::new);
}

private AtomicBoolean onShutdownHandlerRegistered(RepositorySystemSession session) {
return (AtomicBoolean) session.getData()
.computeIfAbsent(getClass().getName() + ".onShutdownHandlerRegistered", AtomicBoolean::new);
}

@Override
Expand Down Expand Up @@ -206,8 +218,8 @@ public RemoteRepositoryFilter getRemoteRepositoryFilter(RepositorySystemSession
@Override
public void postProcess(RepositorySystemSession session, List<ArtifactResult> artifactResults) {
if (isEnabled(session) && isRecord(session)) {
if (onShutdownHandlerRegistered.compareAndSet(false, true)) {
repositorySystemLifecycle.addOnSystemEndedHandler(this::saveRecordedLines);
if (onShutdownHandlerRegistered(session).compareAndSet(false, true)) {
repositorySystemLifecycle.addOnSystemEndedHandler(() -> saveRecordedLines(session));
}
for (ArtifactResult artifactResult : artifactResults) {
if (artifactResult.isResolved() && artifactResult.getRepository() instanceof RemoteRepository) {
Expand All @@ -216,10 +228,11 @@ public void postProcess(RepositorySystemSession session, List<ArtifactResult> ar
ruleFile(session, remoteRepository); // populate it; needed for save
String line = "=" + artifactResult.getArtifact().getGroupId();
RemoteRepository normalized = normalizeRemoteRepository(session, remoteRepository);
recordedRules
recordedRules(session)
.computeIfAbsent(normalized, k -> new TreeSet<>())
.add(line);
rules.compute(normalized, (k, v) -> {
rules(session)
.compute(normalized, (k, v) -> {
if (v == null || v == GroupTree.SENTINEL) {
v = new GroupTree("");
}
Expand All @@ -233,16 +246,17 @@ public void postProcess(RepositorySystemSession session, List<ArtifactResult> ar
}

private Path ruleFile(RepositorySystemSession session, RemoteRepository remoteRepository) {
return ruleFiles.computeIfAbsent(normalizeRemoteRepository(session, remoteRepository), r -> getBasedir(
return ruleFiles(session).computeIfAbsent(normalizeRemoteRepository(session, remoteRepository), r -> getBasedir(
session, LOCAL_REPO_PREFIX_DIR, CONFIG_PROP_BASEDIR, false)
.resolve(GROUP_ID_FILE_PREFIX
+ RepositoryIdHelper.cachedIdToPathSegment(session).apply(remoteRepository)
+ GROUP_ID_FILE_SUFFIX));
}

private GroupTree cacheRules(RepositorySystemSession session, RemoteRepository remoteRepository) {
return rules.computeIfAbsent(
normalizeRemoteRepository(session, remoteRepository), r -> loadRepositoryRules(session, r));
return rules(session)
.computeIfAbsent(
normalizeRemoteRepository(session, remoteRepository), r -> loadRepositoryRules(session, r));
}

private GroupTree loadRepositoryRules(RepositorySystemSession session, RemoteRepository remoteRepository) {
Expand Down Expand Up @@ -315,10 +329,10 @@ private boolean isRecord(RepositorySystemSession session) {
/**
* On-close handler that saves recorded rules, if any.
*/
private void saveRecordedLines() {
private void saveRecordedLines(RepositorySystemSession session) {
ArrayList<Exception> exceptions = new ArrayList<>();
for (Map.Entry<RemoteRepository, Path> entry : ruleFiles.entrySet()) {
Set<String> recorded = recordedRules.get(entry.getKey());
for (Map.Entry<RemoteRepository, Path> entry : ruleFiles(session).entrySet()) {
Set<String> recorded = recordedRules(session).get(entry.getKey());
if (recorded != null && !recorded.isEmpty()) {
try {
ArrayList<String> result = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,13 @@
import javax.inject.Named;
import javax.inject.Singleton;

import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Supplier;

import org.eclipse.aether.DefaultRepositorySystemSession;
Expand All @@ -40,6 +43,7 @@
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.resolution.MetadataRequest;
import org.eclipse.aether.resolution.MetadataResult;
import org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithmFactory;
import org.eclipse.aether.spi.connector.filter.RemoteRepositoryFilter;
import org.eclipse.aether.spi.connector.layout.RepositoryLayout;
import org.eclipse.aether.spi.connector.layout.RepositoryLayoutProvider;
Expand Down Expand Up @@ -191,10 +195,6 @@ public final class PrefixesRemoteRepositoryFilterSource extends RemoteRepository

private final RepositoryLayoutProvider repositoryLayoutProvider;

private final ConcurrentHashMap<RemoteRepository, PrefixTree> prefixes;

private final ConcurrentHashMap<RemoteRepository, RepositoryLayout> layouts;

@Inject
public PrefixesRemoteRepositoryFilterSource(
Supplier<MetadataResolver> metadataResolver,
Expand All @@ -203,8 +203,18 @@ public PrefixesRemoteRepositoryFilterSource(
this.metadataResolver = requireNonNull(metadataResolver);
this.remoteRepositoryManager = requireNonNull(remoteRepositoryManager);
this.repositoryLayoutProvider = requireNonNull(repositoryLayoutProvider);
this.prefixes = new ConcurrentHashMap<>();
this.layouts = new ConcurrentHashMap<>();
}

@SuppressWarnings("unchecked")
private ConcurrentMap<RemoteRepository, PrefixTree> prefixes(RepositorySystemSession session) {
return (ConcurrentMap<RemoteRepository, PrefixTree>)
session.getData().computeIfAbsent(getClass().getName() + ".prefixes", ConcurrentHashMap::new);
}

@SuppressWarnings("unchecked")
private ConcurrentMap<RemoteRepository, RepositoryLayout> layouts(RepositorySystemSession session) {
return (ConcurrentMap<RemoteRepository, RepositoryLayout>)
session.getData().computeIfAbsent(getClass().getName() + ".layouts", ConcurrentHashMap::new);
}

@Override
Expand Down Expand Up @@ -238,25 +248,26 @@ public RemoteRepositoryFilter getRemoteRepositoryFilter(RepositorySystemSession
}

/**
* Caches layout instances for remote repository. In case of unknown layout it returns {@code null}.
* Caches layout instances for remote repository. In case of unknown layout it returns {@link #NOT_SUPPORTED}.
*
* @return the layout instance of {@code null} if layout not supported.
* @return the layout instance or {@link #NOT_SUPPORTED} if layout not supported.
*/
private RepositoryLayout cacheLayout(RepositorySystemSession session, RemoteRepository remoteRepository) {
return layouts.computeIfAbsent(normalizeRemoteRepository(session, remoteRepository), r -> {
return layouts(session).computeIfAbsent(normalizeRemoteRepository(session, remoteRepository), r -> {
try {
return repositoryLayoutProvider.newRepositoryLayout(session, remoteRepository);
} catch (NoRepositoryLayoutException e) {
return null;
return NOT_SUPPORTED;
}
});
}

private PrefixTree cachePrefixTree(
RepositorySystemSession session, Path basedir, RemoteRepository remoteRepository) {
return prefixes.computeIfAbsent(
normalizeRemoteRepository(session, remoteRepository),
r -> loadPrefixTree(session, basedir, remoteRepository));
return prefixes(session)
.computeIfAbsent(
normalizeRemoteRepository(session, remoteRepository),
r -> loadPrefixTree(session, basedir, remoteRepository));
}

private PrefixTree loadPrefixTree(
Expand Down Expand Up @@ -339,16 +350,15 @@ private Path resolvePrefixesFromRemoteRepository(
session, Collections.emptyList(), Collections.singletonList(remoteRepository), true)
.get(0);
// retrieve prefix as metadata from repository
MetadataRequest request =
new MetadataRequest(new DefaultMetadata(PREFIX_FILE_TYPE, Metadata.Nature.RELEASE_OR_SNAPSHOT));
request.setRepository(prepared);
request.setDeleteLocalCopyIfMissing(true);
request.setFavorLocalRepository(true);
MetadataResult result = mr.resolveMetadata(
new DefaultRepositorySystemSession(session)
.setTransferListener(null)
.setConfigProperty(CONFIG_PROP_SKIPPED, Boolean.TRUE.toString()),
Collections.singleton(request))
Collections.singleton(new MetadataRequest(
new DefaultMetadata(PREFIX_FILE_TYPE, Metadata.Nature.RELEASE_OR_SNAPSHOT))
.setRepository(prepared)
.setDeleteLocalCopyIfMissing(true)
.setFavorLocalRepository(true)))
.get(0);
if (result.isResolved()) {
return result.getMetadata().getPath();
Expand All @@ -371,7 +381,7 @@ private PrefixesFilter(RepositorySystemSession session, Path basedir) {
@Override
public Result acceptArtifact(RemoteRepository remoteRepository, Artifact artifact) {
RepositoryLayout repositoryLayout = cacheLayout(session, remoteRepository);
if (repositoryLayout == null) {
if (repositoryLayout == NOT_SUPPORTED) {
return new SimpleResult(true, "Unsupported layout: " + remoteRepository);
}
return acceptPrefix(
Expand All @@ -382,7 +392,7 @@ public Result acceptArtifact(RemoteRepository remoteRepository, Artifact artifac
@Override
public Result acceptMetadata(RemoteRepository remoteRepository, Metadata metadata) {
RepositoryLayout repositoryLayout = cacheLayout(session, remoteRepository);
if (repositoryLayout == null) {
if (repositoryLayout == NOT_SUPPORTED) {
return new SimpleResult(true, "Unsupported layout: " + remoteRepository);
}
return acceptPrefix(
Expand All @@ -392,7 +402,7 @@ public Result acceptMetadata(RemoteRepository remoteRepository, Metadata metadat

private Result acceptPrefix(RemoteRepository repository, String path) {
PrefixTree prefixTree = cachePrefixTree(session, basedir, repository);
if (PrefixTree.SENTINEL == prefixTree) {
if (prefixTree == PrefixTree.SENTINEL) {
return NOT_PRESENT_RESULT;
}
if (prefixTree.acceptedPath(path)) {
Expand All @@ -405,4 +415,36 @@ private Result acceptPrefix(RemoteRepository repository, String path) {

private static final RemoteRepositoryFilter.Result NOT_PRESENT_RESULT =
new SimpleResult(true, "Prefix file not present");

private static final RepositoryLayout NOT_SUPPORTED = new RepositoryLayout() {
@Override
public List<ChecksumAlgorithmFactory> getChecksumAlgorithmFactories() {
throw new UnsupportedOperationException();
}

@Override
public boolean hasChecksums(Artifact artifact) {
throw new UnsupportedOperationException();
}

@Override
public URI getLocation(Artifact artifact, boolean upload) {
throw new UnsupportedOperationException();
}

@Override
public URI getLocation(Metadata metadata, boolean upload) {
throw new UnsupportedOperationException();
}

@Override
public List<ChecksumLocation> getChecksumLocations(Artifact artifact, boolean upload, URI location) {
throw new UnsupportedOperationException();
}

@Override
public List<ChecksumLocation> getChecksumLocations(Metadata metadata, boolean upload, URI location) {
throw new UnsupportedOperationException();
}
};
}