This is an automated email from the ASF dual-hosted git repository.

sjaranowski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-enforcer.git


The following commit(s) were added to refs/heads/master by this push:
     new d58be76f Improve performance of transitive dependency checks (#904)
d58be76f is described below

commit d58be76facad6e44838ca1ec2f805458f01a66ad
Author: harrisric <48761651+harris...@users.noreply.github.com>
AuthorDate: Wed Jul 9 19:54:24 2025 +0100

    Improve performance of transitive dependency checks (#904)
    
    * Keep track of artifacts already validated during transitive dependency 
enforcement
    
    * Optimise common case where part of Pattern accepts everything
---
 .../rules/dependency/BannedDependenciesBase.java   | 17 ++++--
 .../enforcer/rules/utils/ArtifactMatcher.java      | 63 ++++++++++++++++++++--
 2 files changed, 71 insertions(+), 9 deletions(-)

diff --git 
a/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/BannedDependenciesBase.java
 
b/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/BannedDependenciesBase.java
index 1bf3fa3b..f06e414c 100644
--- 
a/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/BannedDependenciesBase.java
+++ 
b/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/BannedDependenciesBase.java
@@ -19,13 +19,16 @@
 package org.apache.maven.enforcer.rules.dependency;
 
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
 import org.apache.maven.enforcer.rules.AbstractStandardEnforcerRule;
+import org.apache.maven.enforcer.rules.utils.ArtifactMatcher.MatchingArtifact;
 import org.apache.maven.enforcer.rules.utils.ArtifactUtils;
 import org.apache.maven.execution.MavenSession;
 import org.eclipse.aether.graph.DependencyNode;
@@ -104,7 +107,8 @@ abstract class BannedDependenciesBase extends 
AbstractStandardEnforcerRule {
         } else {
             StringBuilder messageBuilder = new StringBuilder();
             DependencyNode rootNode = 
resolverUtil.resolveTransitiveDependenciesVerbose(Collections.emptyList());
-            if (!validate(rootNode, 0, messageBuilder)) {
+            Set<MatchingArtifact> visitedArtifacts = new HashSet<>();
+            if (!validate(rootNode, 0, messageBuilder, visitedArtifacts)) {
                 String message = "";
                 if (getMessage() != null) {
                     message = getMessage() + System.lineSeparator();
@@ -114,12 +118,17 @@ abstract class BannedDependenciesBase extends 
AbstractStandardEnforcerRule {
         }
     }
 
-    protected boolean validate(DependencyNode node, int level, StringBuilder 
messageBuilder) {
-        boolean rootFailed = level > 0 && 
!validate(ArtifactUtils.toArtifact(node));
+    protected boolean validate(
+            DependencyNode node, int level, StringBuilder messageBuilder, 
Set<MatchingArtifact> visitedArtifacts) {
+        Artifact artifact = ArtifactUtils.toArtifact(node);
+        boolean rootFailed = false;
+        if (level > 0 && visitedArtifacts.add(new MatchingArtifact(artifact))) 
{
+            rootFailed = !validate(artifact);
+        }
         StringBuilder childMessageBuilder = new StringBuilder();
         if (rootFailed
                 || !node.getChildren().stream()
-                        .map(childNode -> validate(childNode, level + 1, 
childMessageBuilder))
+                        .map(childNode -> validate(childNode, level + 1, 
childMessageBuilder, visitedArtifacts))
                         .reduce(true, Boolean::logicalAnd)) {
             messageBuilder
                     .append(StringUtils.repeat("   ", level))
diff --git 
a/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/utils/ArtifactMatcher.java
 
b/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/utils/ArtifactMatcher.java
index caf2c599..fd4e204d 100644
--- 
a/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/utils/ArtifactMatcher.java
+++ 
b/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/utils/ArtifactMatcher.java
@@ -22,6 +22,7 @@ import java.util.Collection;
 import java.util.HashSet;
 import java.util.Objects;
 import java.util.function.Function;
+import java.util.function.Predicate;
 
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.versioning.ArtifactVersion;
@@ -47,7 +48,7 @@ public final class ArtifactMatcher {
         private final String pattern;
 
         private final String[] parts;
-        private final java.util.regex.Pattern[] partsRegex;
+        private final Predicate<String>[] partsRegex;
 
         public Pattern(String pattern) {
             if (pattern == null) {
@@ -67,7 +68,7 @@ public final class ArtifactMatcher {
                     throw new IllegalArgumentException("Pattern or its part is 
empty.");
                 }
             }
-            partsRegex = new java.util.regex.Pattern[parts.length];
+            partsRegex = new Predicate[parts.length];
         }
 
         public boolean match(Artifact artifact) {
@@ -149,7 +150,6 @@ public final class ArtifactMatcher {
             if (input == null) {
                 input = "";
             }
-            //          return matches(parts[index], input);
             if (partsRegex[index] == null) {
                 String regex = parts[index]
                         .replace(".", "\\.")
@@ -161,9 +161,14 @@ public final class ArtifactMatcher {
                         .replace("(", "\\(")
                         .replace(")", "\\)");
 
-                partsRegex[index] = java.util.regex.Pattern.compile(regex);
+                if (".*".equals(regex)) {
+                    partsRegex[index] = test -> true;
+                } else {
+                    partsRegex[index] = test ->
+                            
java.util.regex.Pattern.compile(regex).matcher(test).matches();
+                }
             }
-            return partsRegex[index].matcher(input).matches();
+            return partsRegex[index].test(input);
         }
 
         @Override
@@ -240,4 +245,52 @@ public final class ArtifactMatcher {
             return compareTo <= 0;
         }
     }
+
+    /**
+     * To be used for artifacts which are equivalent for the purposes of the 
{@link ArtifactMatcher}.
+     */
+    public static class MatchingArtifact {
+        String artifactString;
+
+        public MatchingArtifact(Artifact artifact) {
+            artifactString = new StringBuilder()
+                    .append(artifact.getGroupId())
+                    .append(":")
+                    .append(artifact.getArtifactId())
+                    .append(":")
+                    .append(artifact.getVersion())
+                    .append(":")
+                    .append(artifact.getType())
+                    .append(":")
+                    .append(artifact.getScope())
+                    .append(":")
+                    .append(artifact.getClassifier())
+                    .toString();
+        }
+
+        @Override
+        public int hashCode() {
+            return artifactString.hashCode();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj == null) {
+                return false;
+            }
+            if (getClass() != obj.getClass()) {
+                return false;
+            }
+            MatchingArtifact other = (MatchingArtifact) obj;
+            return Objects.equals(artifactString, other.artifactString);
+        }
+
+        @Override
+        public String toString() {
+            return artifactString;
+        }
+    }
 }

Reply via email to