From 896c707d324330d7d4ad92674187923945efcda9 Mon Sep 17 00:00:00 2001 From: Karl Heinz Marbaise Date: Thu, 30 Sep 2021 19:10:44 +0200 Subject: [PATCH] [MNG-7447] - Several Improvements by using Stream API --- .../java/org/apache/maven/ReactorReader.java | 102 ++++++++---------- .../org/apache/maven/RepositoryUtils.java | 47 +++----- .../filter/ExclusionArtifactFilter.java | 53 ++++----- .../apache/maven/execution/MavenSession.java | 12 +-- .../maven/extension/internal/CoreExports.java | 14 ++- .../mapping/DefaultLifecycleMapping.java | 3 +- .../DefaultProfileActivationContext.java | 27 ++--- 7 files changed, 108 insertions(+), 150 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/ReactorReader.java b/maven-core/src/main/java/org/apache/maven/ReactorReader.java index 247632ae75..e50eabb3cb 100644 --- a/maven-core/src/main/java/org/apache/maven/ReactorReader.java +++ b/maven-core/src/main/java/org/apache/maven/ReactorReader.java @@ -24,20 +24,20 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; import java.util.stream.Stream; -import javax.inject.Inject; -import javax.inject.Named; - import org.apache.maven.artifact.ArtifactUtils; import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Model; @@ -49,6 +49,13 @@ import org.eclipse.aether.util.artifact.ArtifactIdUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.inject.Inject; +import javax.inject.Named; + +import static java.util.function.Function.identity; +import static java.util.stream.Collectors.groupingBy; +import static java.util.stream.Collectors.toMap; + /** * An implementation of a workspace reader that knows how to search the Maven reactor for artifacts, either as packaged * jar if it has been built, or only compile output directory if packaging hasn't happened yet. @@ -72,26 +79,22 @@ class ReactorReader private final Map> projectsByGA; private final WorkspaceRepository repository; + private Function projectIntoKey = + s -> ArtifactUtils.key( s.getGroupId(), s.getArtifactId(), s.getVersion() ); + + private Function projectIntoVersionlessKey = + s -> ArtifactUtils.versionlessKey( s.getGroupId(), s.getArtifactId() ); + @Inject ReactorReader( MavenSession session ) { this.session = session; - this.projectsByGAV = new HashMap<>( session.getAllProjects().size() * 2 ); - session.getAllProjects().forEach( project -> - { - String projectId = ArtifactUtils.key( project.getGroupId(), project.getArtifactId(), project.getVersion() ); - this.projectsByGAV.put( projectId, project ); - } ); + this.projectsByGAV = + session.getAllProjects().stream() + .collect( toMap( projectIntoKey, identity() ) ); - projectsByGA = new HashMap<>( projectsByGAV.size() * 2 ); - for ( MavenProject project : projectsByGAV.values() ) - { - String key = ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() ); - - List projects = projectsByGA.computeIfAbsent( key, k -> new ArrayList<>( 1 ) ); - - projects.add( project ); - } + this.projectsByGA = projectsByGAV.values().stream() + .collect( groupingBy( projectIntoVersionlessKey ) ); repository = new WorkspaceRepository( "reactor", new HashSet<>( projectsByGAV.keySet() ) ); } @@ -128,23 +131,11 @@ class ReactorReader { String key = ArtifactUtils.versionlessKey( artifact.getGroupId(), artifact.getArtifactId() ); - List projects = projectsByGA.get( key ); - if ( projects == null || projects.isEmpty() ) - { - return Collections.emptyList(); - } - - List versions = new ArrayList<>(); - - for ( MavenProject project : projects ) - { - if ( find( project, artifact ) != null ) - { - versions.add( project.getVersion() ); - } - } - - return Collections.unmodifiableList( versions ); + return Optional.ofNullable( projectsByGA.get( key ) ) + .orElse( Collections.emptyList() ).stream() + .filter( s -> Objects.nonNull( find( s, artifact ) ) ) + .map( MavenProject::getVersion ) + .collect( Collectors.collectingAndThen( Collectors.toList(), Collections::unmodifiableList ) ); } @Override @@ -334,28 +325,27 @@ class ReactorReader return mainArtifact; } - for ( Artifact attachedArtifact : RepositoryUtils.toArtifacts( project.getAttachedArtifacts() ) ) - { - if ( attachedArtifactComparison( requestedArtifact, attachedArtifact ) ) - { - return attachedArtifact; - } - } - - return null; + return RepositoryUtils.toArtifacts( project.getAttachedArtifacts() ).stream() + .filter( isRequestedArtifact( requestedArtifact ) ) + .findFirst() + .orElse( null ); } - private boolean attachedArtifactComparison( Artifact requested, Artifact attached ) + /** + * We are taking as much as we can from the DefaultArtifact.equals(). The requested artifact has no file, so we want + * to remove that from the comparison. + * + * @param requestArtifact checked against the given artifact. + * @return true if equals, false otherwise. + */ + private Predicate isRequestedArtifact( Artifact requestArtifact ) { - // - // We are taking as much as we can from the DefaultArtifact.equals(). The requested artifact has no file so - // we want to remove that from the comparison. - // - return requested.getArtifactId().equals( attached.getArtifactId() ) - && requested.getGroupId().equals( attached.getGroupId() ) - && requested.getVersion().equals( attached.getVersion() ) - && requested.getExtension().equals( attached.getExtension() ) - && requested.getClassifier().equals( attached.getClassifier() ); + return s -> s.getArtifactId().equals( requestArtifact.getArtifactId() ) + && s.getGroupId().equals( requestArtifact.getGroupId() ) + && s.getVersion().equals( requestArtifact.getVersion() ) + && s.getExtension().equals( requestArtifact.getExtension() ) + && s.getClassifier().equals( requestArtifact.getClassifier() ); + } /** diff --git a/maven-core/src/main/java/org/apache/maven/RepositoryUtils.java b/maven-core/src/main/java/org/apache/maven/RepositoryUtils.java index bafed36ee7..ce840ee2a4 100644 --- a/maven-core/src/main/java/org/apache/maven/RepositoryUtils.java +++ b/maven-core/src/main/java/org/apache/maven/RepositoryUtils.java @@ -26,6 +26,8 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; import org.apache.maven.artifact.handler.ArtifactHandler; import org.apache.maven.artifact.handler.DefaultArtifactHandler; @@ -170,32 +172,21 @@ public class RepositoryUtils Artifact result = toArtifact( artifact ); - List excl = null; - if ( exclusions != null ) - { - excl = new ArrayList<>( exclusions.size() ); - for ( org.apache.maven.model.Exclusion exclusion : exclusions ) - { - excl.add( toExclusion( exclusion ) ); - } - } - + List excl = Optional.ofNullable( exclusions ) + .orElse( Collections.emptyList() ) + .stream() + .map( RepositoryUtils::toExclusion ) + .collect( Collectors.toList() ); return new Dependency( result, artifact.getScope(), artifact.isOptional(), excl ); } public static List toRepos( List repos ) { - if ( repos == null ) - { - return null; - } - - List results = new ArrayList<>( repos.size() ); - for ( ArtifactRepository repo : repos ) - { - results.add( toRepo( repo ) ); - } - return results; + return Optional.ofNullable( repos ) + .orElse( Collections.emptyList() ) + .stream() + .map( RepositoryUtils::toRepo ) + .collect( Collectors.toList() ); } public static RemoteRepository toRepo( ArtifactRepository repo ) @@ -318,11 +309,8 @@ public class RepositoryUtils new DefaultArtifact( dependency.getGroupId(), dependency.getArtifactId(), dependency.getClassifier(), null, dependency.getVersion(), props, stereotype ); - List exclusions = new ArrayList<>( dependency.getExclusions().size() ); - for ( org.apache.maven.model.Exclusion exclusion : dependency.getExclusions() ) - { - exclusions.add( toExclusion( exclusion ) ); - } + List exclusions = + dependency.getExclusions().stream().map( RepositoryUtils::toExclusion ).collect( Collectors.toList() ); return new Dependency( artifact, dependency.getScope(), @@ -363,12 +351,7 @@ public class RepositoryUtils public static Collection toArtifacts( Collection artifactsToConvert ) { - List artifacts = new ArrayList<>(); - for ( org.apache.maven.artifact.Artifact a : artifactsToConvert ) - { - artifacts.add( toArtifact( a ) ); - } - return artifacts; + return artifactsToConvert.stream().map( RepositoryUtils::toArtifact ).collect( Collectors.toList() ); } public static WorkspaceRepository getWorkspace( RepositorySystemSession session ) diff --git a/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/ExclusionArtifactFilter.java b/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/ExclusionArtifactFilter.java index dd50c31748..18d4e833a0 100644 --- a/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/ExclusionArtifactFilter.java +++ b/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/ExclusionArtifactFilter.java @@ -19,11 +19,12 @@ package org.apache.maven.artifact.resolver.filter; * under the License. */ +import java.util.List; +import java.util.function.Predicate; + import org.apache.maven.artifact.Artifact; import org.apache.maven.model.Exclusion; -import java.util.List; - /** * Filter to exclude from a list of artifact patterns. */ @@ -38,31 +39,33 @@ public class ExclusionArtifactFilter implements ArtifactFilter this.exclusions = exclusions; } + private Predicate sameArtifactId( Artifact artifact ) + { + return exclusion -> exclusion.getArtifactId().equals( artifact.getArtifactId() ); + } + + private Predicate sameGroupId( Artifact artifact ) + { + return exclusion -> exclusion.getGroupId().equals( artifact.getGroupId() ); + } + + private Predicate groupIdIsWildcard = exclusion -> WILDCARD.equals( exclusion.getGroupId() ); + + private Predicate artifactIdIsWildcard = exclusion -> WILDCARD.equals( exclusion.getArtifactId() ); + + private Predicate groupIdAndArtifactIdIsWildcard = groupIdIsWildcard.and( artifactIdIsWildcard ); + + private Predicate exclude( Artifact artifact ) + { + return groupIdAndArtifactIdIsWildcard + .or( groupIdIsWildcard.and( sameArtifactId( artifact ) ) ) + .or( artifactIdIsWildcard.and( sameGroupId( artifact ) ) ) + .or( sameGroupId( artifact ).and( sameArtifactId( artifact ) ) ); + } + @Override public boolean include( Artifact artifact ) { - for ( Exclusion exclusion : exclusions ) - { - if ( WILDCARD.equals( exclusion.getGroupId() ) && WILDCARD.equals( exclusion.getArtifactId() ) ) - { - return false; - } - if ( WILDCARD.equals( exclusion.getGroupId() ) - && exclusion.getArtifactId().equals( artifact.getArtifactId() ) ) - { - return false; - } - if ( WILDCARD.equals( exclusion.getArtifactId() ) - && exclusion.getGroupId().equals( artifact.getGroupId() ) ) - { - return false; - } - if ( exclusion.getGroupId().equals( artifact.getGroupId() ) - && exclusion.getArtifactId().equals( artifact.getArtifactId() ) ) - { - return false; - } - } - return true; + return !exclusions.stream().anyMatch( exclude( artifact ) ); } } diff --git a/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java b/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java index c2f0c89e86..5af173410d 100644 --- a/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java +++ b/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java @@ -91,15 +91,9 @@ public class MavenSession if ( !projects.isEmpty() ) { this.currentProject = projects.get( 0 ); - this.topLevelProject = currentProject; - for ( MavenProject project : projects ) - { - if ( project.isExecutionRoot() ) - { - topLevelProject = project; - break; - } - } + this.topLevelProject = + projects.stream().filter( project -> project.isExecutionRoot() ).findFirst() + .orElse( currentProject ); } else { diff --git a/maven-core/src/main/java/org/apache/maven/extension/internal/CoreExports.java b/maven-core/src/main/java/org/apache/maven/extension/internal/CoreExports.java index d72b3f9ea2..2d976ae0ef 100644 --- a/maven-core/src/main/java/org/apache/maven/extension/internal/CoreExports.java +++ b/maven-core/src/main/java/org/apache/maven/extension/internal/CoreExports.java @@ -20,14 +20,16 @@ package org.apache.maven.extension.internal; */ import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; -import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; import org.codehaus.plexus.classworlds.realm.ClassRealm; +import static java.util.function.Function.identity; +import static java.util.stream.Collectors.collectingAndThen; +import static java.util.stream.Collectors.toMap; + /** * Provides information about artifacts (identified by groupId:artifactId string key) and classpath elements exported by * Maven core itself and loaded Maven core extensions. @@ -47,13 +49,9 @@ public class CoreExports public CoreExports( ClassRealm realm, Set exportedArtifacts, Set exportedPackages ) { - Map packages = new LinkedHashMap<>(); - for ( String pkg : exportedPackages ) - { - packages.put( pkg, realm ); - } this.artifacts = Collections.unmodifiableSet( new HashSet<>( exportedArtifacts ) ); - this.packages = Collections.unmodifiableMap( new HashMap<>( packages ) ); + this.packages = exportedPackages.stream().collect( + collectingAndThen( toMap( identity(), v -> realm ), Collections::unmodifiableMap ) ); } /** diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/mapping/DefaultLifecycleMapping.java b/maven-core/src/main/java/org/apache/maven/lifecycle/mapping/DefaultLifecycleMapping.java index e1ff3143bd..4001a97fa0 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/mapping/DefaultLifecycleMapping.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/mapping/DefaultLifecycleMapping.java @@ -24,6 +24,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import static java.util.function.Function.identity; import static java.util.stream.Collectors.toMap; /** @@ -57,7 +58,7 @@ public class DefaultLifecycleMapping public DefaultLifecycleMapping( final List lifecycles ) { this.lifecycleMap = Collections.unmodifiableMap( - lifecycles.stream().collect( toMap( Lifecycle::getId, l -> l ) ) + lifecycles.stream().collect( toMap( Lifecycle::getId, identity() ) ) ); } diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileActivationContext.java b/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileActivationContext.java index 77d92a377c..4fb1b265e3 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileActivationContext.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileActivationContext.java @@ -21,12 +21,13 @@ package org.apache.maven.model.profile; import java.io.File; import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; +import static java.util.stream.Collectors.collectingAndThen; +import static java.util.stream.Collectors.toMap; + /** * Describes the environmental context used to determine the activation status of profiles. * @@ -230,8 +231,11 @@ public class DefaultProfileActivationContext { if ( projectProperties != null ) { - - this.projectProperties = Collections.unmodifiableMap( toMap( projectProperties ) ); + this.projectProperties = projectProperties.entrySet().stream() + .collect( + collectingAndThen( + toMap( k -> String.valueOf( k.getKey() ), v -> String.valueOf( v ) ), + Collections::unmodifiableMap ) ); } else { @@ -241,19 +245,4 @@ public class DefaultProfileActivationContext return this; } - private Map toMap( Properties properties ) - { - if ( properties == null ) - { - return Collections.emptyMap(); - } - Map map = new HashMap<>(); - Enumeration keys = properties.keys(); - while ( keys.hasMoreElements() ) - { - String key = (String) keys.nextElement(); - map.put( key, properties.getProperty( key ) ); - } - return map; - } }