diff --git a/maven_plugin/src/main/java/io/github/chains_project/maven_lockfile/checksum/RemoteChecksumCalculator.java b/maven_plugin/src/main/java/io/github/chains_project/maven_lockfile/checksum/RemoteChecksumCalculator.java index 67eea1469..04b490957 100644 --- a/maven_plugin/src/main/java/io/github/chains_project/maven_lockfile/checksum/RemoteChecksumCalculator.java +++ b/maven_plugin/src/main/java/io/github/chains_project/maven_lockfile/checksum/RemoteChecksumCalculator.java @@ -10,7 +10,9 @@ import java.net.http.HttpResponse; import java.security.MessageDigest; import java.util.Locale; +import java.util.Map; import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.project.ProjectBuildingRequest; @@ -19,6 +21,8 @@ public class RemoteChecksumCalculator extends AbstractChecksumCalculator { private final ProjectBuildingRequest artifactBuildingRequest; private final ProjectBuildingRequest pluginBuildingRequest; + private final Map checksumCache = new ConcurrentHashMap<>(); + private final Map resolvedCache = new ConcurrentHashMap<>(); public RemoteChecksumCalculator( String checksumAlgorithm, @@ -37,7 +41,22 @@ public RemoteChecksumCalculator( this.pluginBuildingRequest = pluginBuildingRequest; } + private String getCacheKey(Artifact artifact) { + String classifier = artifact.getClassifier(); + if (classifier == null) { + classifier = ""; + } + return artifact.getGroupId() + ":" + artifact.getArtifactId() + ":" + artifact.getVersion() + ":" + classifier + + ":" + artifact.getType(); + } + private Optional calculateChecksumInternal(Artifact artifact, ProjectBuildingRequest buildingRequest) { + String cacheKey = getCacheKey(artifact) + ":" + checksumAlgorithm; + String cached = checksumCache.get(cacheKey); + if (cached != null) { + return cached.isEmpty() ? Optional.empty() : Optional.of(cached); + } + try { String groupId = artifact.getGroupId().replace(".", "/"); String artifactId = artifact.getArtifactId(); @@ -73,7 +92,9 @@ private Optional calculateChecksumInternal(Artifact artifact, ProjectBui client.send(checksumRequest, HttpResponse.BodyHandlers.ofString()); if (checksumResponse.statusCode() >= 200 && checksumResponse.statusCode() < 300) { - return Optional.of(checksumResponse.body().strip()); + String checksum = checksumResponse.body().strip(); + checksumCache.put(cacheKey, checksum); + return Optional.of(checksum); } if (checksumResponse.statusCode() == 404) { @@ -133,6 +154,7 @@ private Optional calculateChecksumInternal(Artifact artifact, ProjectBui String checksum = baseEncoding .encode(messageDigest.digest(artifactResponse.body())) .toLowerCase(Locale.ROOT); + checksumCache.put(cacheKey, checksum); return Optional.of(checksum); } } @@ -141,16 +163,24 @@ private Optional calculateChecksumInternal(Artifact artifact, ProjectBui .warn(String.format( "Artifact checksum `%s.%s` not found among remote repositories.", artifact, checksumAlgorithm)); + checksumCache.put(cacheKey, ""); return Optional.empty(); } catch (Exception e) { PluginLogManager.getLog() .warn(String.format("Could not resolve artifact: %s", artifact.getArtifactId()), e); + checksumCache.put(cacheKey, ""); return Optional.empty(); } } private Optional getResolvedFieldInternal( Artifact artifact, ProjectBuildingRequest buildingRequest) { + String cacheKey = getCacheKey(artifact); + RepositoryInformation cached = resolvedCache.get(cacheKey); + if (cached != null) { + return cached.equals(RepositoryInformation.Unresolved()) ? Optional.empty() : Optional.of(cached); + } + try { String groupId = artifact.getGroupId().replace(".", "/"); String artifactId = artifact.getArtifactId(); @@ -184,16 +214,20 @@ private Optional getResolvedFieldInternal( HttpResponse response = client.send(request, HttpResponse.BodyHandlers.discarding()); if (response.statusCode() >= 200 && response.statusCode() < 300) { - return Optional.of( - new RepositoryInformation(ResolvedUrl.of(url), RepositoryId.of(repository.getId()))); + RepositoryInformation result = + new RepositoryInformation(ResolvedUrl.of(url), RepositoryId.of(repository.getId())); + resolvedCache.put(cacheKey, result); + return Optional.of(result); } } PluginLogManager.getLog().warn(String.format("Artifact resolved url `%s` not found.", artifact)); + resolvedCache.put(cacheKey, RepositoryInformation.Unresolved()); return Optional.empty(); } catch (Exception e) { PluginLogManager.getLog() .warn(String.format("Could not resolve url for artifact: %s", artifact.getArtifactId()), e); + resolvedCache.put(cacheKey, RepositoryInformation.Unresolved()); return Optional.empty(); } } diff --git a/maven_plugin/src/main/java/io/github/chains_project/maven_lockfile/checksum/RepositoryInformation.java b/maven_plugin/src/main/java/io/github/chains_project/maven_lockfile/checksum/RepositoryInformation.java index d0c55bbd4..019e94360 100644 --- a/maven_plugin/src/main/java/io/github/chains_project/maven_lockfile/checksum/RepositoryInformation.java +++ b/maven_plugin/src/main/java/io/github/chains_project/maven_lockfile/checksum/RepositoryInformation.java @@ -2,6 +2,7 @@ import io.github.chains_project.maven_lockfile.data.RepositoryId; import io.github.chains_project.maven_lockfile.data.ResolvedUrl; +import java.util.Objects; public class RepositoryInformation { private final ResolvedUrl resolvedUrl; @@ -29,4 +30,19 @@ public ResolvedUrl getResolvedUrl() { public RepositoryId getRepositoryId() { return repositoryId; } + + @Override + public boolean equals(Object o) { + if (o == this) return true; + if (!(o instanceof RepositoryInformation)) { + return false; + } + RepositoryInformation other = (RepositoryInformation) o; + return Objects.equals(resolvedUrl, other.resolvedUrl) && Objects.equals(repositoryId, other.repositoryId); + } + + @Override + public int hashCode() { + return Objects.hash(resolvedUrl, repositoryId); + } }